6e8d1cd9270dcc73079503e05ec99ddb6aec1b56
[mesa.git] / src / mesa / drivers / dri / r600 / r700_assembler.c
1 /*
2 * Copyright (C) 2008-2009 Advanced Micro Devices, 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
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR 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) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 /*
23 * Authors:
24 * Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25 */
26
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include "main/mtypes.h"
34 #include "main/imports.h"
35
36 #include "radeon_debug.h"
37 #include "r600_context.h"
38
39 #include "r700_assembler.h"
40
41 #define USE_CF_FOR_CONTINUE_BREAK 1
42 #define USE_CF_FOR_POP_AFTER 1
43
44 BITS addrmode_PVSDST(PVSDST * pPVSDST)
45 {
46 return pPVSDST->addrmode0 | ((BITS)pPVSDST->addrmode1 << 1);
47 }
48
49 void setaddrmode_PVSDST(PVSDST * pPVSDST, BITS addrmode)
50 {
51 pPVSDST->addrmode0 = addrmode & 1;
52 pPVSDST->addrmode1 = (addrmode >> 1) & 1;
53 }
54
55 void nomask_PVSDST(PVSDST * pPVSDST)
56 {
57 pPVSDST->writex = pPVSDST->writey = pPVSDST->writez = pPVSDST->writew = 1;
58 }
59
60 BITS addrmode_PVSSRC(PVSSRC* pPVSSRC)
61 {
62 return pPVSSRC->addrmode0 | ((BITS)pPVSSRC->addrmode1 << 1);
63 }
64
65 void setaddrmode_PVSSRC(PVSSRC* pPVSSRC, BITS addrmode)
66 {
67 pPVSSRC->addrmode0 = addrmode & 1;
68 pPVSSRC->addrmode1 = (addrmode >> 1) & 1;
69 }
70
71
72 void setswizzle_PVSSRC(PVSSRC* pPVSSRC, BITS swz)
73 {
74 pPVSSRC->swizzlex =
75 pPVSSRC->swizzley =
76 pPVSSRC->swizzlez =
77 pPVSSRC->swizzlew = swz;
78 }
79
80 void noswizzle_PVSSRC(PVSSRC* pPVSSRC)
81 {
82 pPVSSRC->swizzlex = SQ_SEL_X;
83 pPVSSRC->swizzley = SQ_SEL_Y;
84 pPVSSRC->swizzlez = SQ_SEL_Z;
85 pPVSSRC->swizzlew = SQ_SEL_W;
86 }
87
88 void
89 swizzleagain_PVSSRC(PVSSRC * pPVSSRC, BITS x, BITS y, BITS z, BITS w)
90 {
91 switch (x)
92 {
93 case SQ_SEL_X: x = pPVSSRC->swizzlex;
94 break;
95 case SQ_SEL_Y: x = pPVSSRC->swizzley;
96 break;
97 case SQ_SEL_Z: x = pPVSSRC->swizzlez;
98 break;
99 case SQ_SEL_W: x = pPVSSRC->swizzlew;
100 break;
101 default:;
102 }
103
104 switch (y)
105 {
106 case SQ_SEL_X: y = pPVSSRC->swizzlex;
107 break;
108 case SQ_SEL_Y: y = pPVSSRC->swizzley;
109 break;
110 case SQ_SEL_Z: y = pPVSSRC->swizzlez;
111 break;
112 case SQ_SEL_W: y = pPVSSRC->swizzlew;
113 break;
114 default:;
115 }
116
117 switch (z)
118 {
119 case SQ_SEL_X: z = pPVSSRC->swizzlex;
120 break;
121 case SQ_SEL_Y: z = pPVSSRC->swizzley;
122 break;
123 case SQ_SEL_Z: z = pPVSSRC->swizzlez;
124 break;
125 case SQ_SEL_W: z = pPVSSRC->swizzlew;
126 break;
127 default:;
128 }
129
130 switch (w)
131 {
132 case SQ_SEL_X: w = pPVSSRC->swizzlex;
133 break;
134 case SQ_SEL_Y: w = pPVSSRC->swizzley;
135 break;
136 case SQ_SEL_Z: w = pPVSSRC->swizzlez;
137 break;
138 case SQ_SEL_W: w = pPVSSRC->swizzlew;
139 break;
140 default:;
141 }
142
143 pPVSSRC->swizzlex = x;
144 pPVSSRC->swizzley = y;
145 pPVSSRC->swizzlez = z;
146 pPVSSRC->swizzlew = w;
147 }
148
149 void neg_PVSSRC(PVSSRC* pPVSSRC)
150 {
151 pPVSSRC->negx = 1;
152 pPVSSRC->negy = 1;
153 pPVSSRC->negz = 1;
154 pPVSSRC->negw = 1;
155 }
156
157 void noneg_PVSSRC(PVSSRC* pPVSSRC)
158 {
159 pPVSSRC->negx = 0;
160 pPVSSRC->negy = 0;
161 pPVSSRC->negz = 0;
162 pPVSSRC->negw = 0;
163 }
164
165 // negate argument (for SUB instead of ADD and alike)
166 void flipneg_PVSSRC(PVSSRC* pPVSSRC)
167 {
168 pPVSSRC->negx = !pPVSSRC->negx;
169 pPVSSRC->negy = !pPVSSRC->negy;
170 pPVSSRC->negz = !pPVSSRC->negz;
171 pPVSSRC->negw = !pPVSSRC->negw;
172 }
173
174 void zerocomp_PVSSRC(PVSSRC* pPVSSRC, int c)
175 {
176 switch (c)
177 {
178 case 0: pPVSSRC->swizzlex = SQ_SEL_0; pPVSSRC->negx = 0; break;
179 case 1: pPVSSRC->swizzley = SQ_SEL_0; pPVSSRC->negy = 0; break;
180 case 2: pPVSSRC->swizzlez = SQ_SEL_0; pPVSSRC->negz = 0; break;
181 case 3: pPVSSRC->swizzlew = SQ_SEL_0; pPVSSRC->negw = 0; break;
182 default:;
183 }
184 }
185
186 void onecomp_PVSSRC(PVSSRC* pPVSSRC, int c)
187 {
188 switch (c)
189 {
190 case 0: pPVSSRC->swizzlex = SQ_SEL_1; pPVSSRC->negx = 0; break;
191 case 1: pPVSSRC->swizzley = SQ_SEL_1; pPVSSRC->negy = 0; break;
192 case 2: pPVSSRC->swizzlez = SQ_SEL_1; pPVSSRC->negz = 0; break;
193 case 3: pPVSSRC->swizzlew = SQ_SEL_1; pPVSSRC->negw = 0; break;
194 default:;
195 }
196 }
197
198 BITS is_misc_component_exported(VAP_OUT_VTX_FMT_0* pOutVTXFmt0)
199 {
200 return (pOutVTXFmt0->point_size |
201 pOutVTXFmt0->edge_flag |
202 pOutVTXFmt0->rta_index |
203 pOutVTXFmt0->kill_flag |
204 pOutVTXFmt0->viewport_index);
205 }
206
207 BITS is_depth_component_exported(OUT_FRAGMENT_FMT_0* pFPOutFmt)
208 {
209 return (pFPOutFmt->depth |
210 pFPOutFmt->stencil_ref |
211 pFPOutFmt->mask |
212 pFPOutFmt->coverage_to_mask);
213 }
214
215 GLboolean is_reduction_opcode(PVSDWORD* dest)
216 {
217 if (dest->dst.op3 == 0)
218 {
219 if ( (dest->dst.opcode == SQ_OP2_INST_DOT4 || dest->dst.opcode == SQ_OP2_INST_DOT4_IEEE || dest->dst.opcode == SQ_OP2_INST_CUBE) )
220 {
221 return GL_TRUE;
222 }
223 }
224 return GL_FALSE;
225 }
226
227 GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size)
228 {
229 GLuint format = FMT_INVALID;
230 GLuint uiElemSize = 0;
231
232 switch (eType)
233 {
234 case GL_BYTE:
235 case GL_UNSIGNED_BYTE:
236 uiElemSize = 1;
237 switch(nChannels)
238 {
239 case 1:
240 format = FMT_8; break;
241 case 2:
242 format = FMT_8_8; break;
243 case 3:
244 format = FMT_8_8_8; break;
245 case 4:
246 format = FMT_8_8_8_8; break;
247 default:
248 break;
249 }
250 break;
251
252 case GL_UNSIGNED_SHORT:
253 case GL_SHORT:
254 uiElemSize = 2;
255 switch(nChannels)
256 {
257 case 1:
258 format = FMT_16; break;
259 case 2:
260 format = FMT_16_16; break;
261 case 3:
262 format = FMT_16_16_16; break;
263 case 4:
264 format = FMT_16_16_16_16; break;
265 default:
266 break;
267 }
268 break;
269
270 case GL_UNSIGNED_INT:
271 case GL_INT:
272 uiElemSize = 4;
273 switch(nChannels)
274 {
275 case 1:
276 format = FMT_32; break;
277 case 2:
278 format = FMT_32_32; break;
279 case 3:
280 format = FMT_32_32_32; break;
281 case 4:
282 format = FMT_32_32_32_32; break;
283 default:
284 break;
285 }
286 break;
287
288 case GL_FLOAT:
289 uiElemSize = 4;
290 switch(nChannels)
291 {
292 case 1:
293 format = FMT_32_FLOAT; break;
294 case 2:
295 format = FMT_32_32_FLOAT; break;
296 case 3:
297 format = FMT_32_32_32_FLOAT; break;
298 case 4:
299 format = FMT_32_32_32_32_FLOAT; break;
300 default:
301 break;
302 }
303 break;
304 case GL_DOUBLE:
305 uiElemSize = 8;
306 switch(nChannels)
307 {
308 case 1:
309 format = FMT_32_FLOAT; break;
310 case 2:
311 format = FMT_32_32_FLOAT; break;
312 case 3:
313 format = FMT_32_32_32_FLOAT; break;
314 case 4:
315 format = FMT_32_32_32_32_FLOAT; break;
316 default:
317 break;
318 }
319 break;
320 default:
321 ;
322 //GL_ASSERT_NO_CASE();
323 }
324
325 if(NULL != pClient_size)
326 {
327 *pClient_size = uiElemSize * nChannels;
328 }
329
330 return(format);
331 }
332
333 unsigned int r700GetNumOperands(r700_AssemblerBase* pAsm)
334 {
335 if(pAsm->D.dst.op3)
336 {
337 return 3;
338 }
339
340 switch (pAsm->D.dst.opcode)
341 {
342 case SQ_OP2_INST_ADD:
343 case SQ_OP2_INST_KILLGT:
344 case SQ_OP2_INST_MUL:
345 case SQ_OP2_INST_MAX:
346 case SQ_OP2_INST_MIN:
347 //case SQ_OP2_INST_MAX_DX10:
348 //case SQ_OP2_INST_MIN_DX10:
349 case SQ_OP2_INST_SETE:
350 case SQ_OP2_INST_SETNE:
351 case SQ_OP2_INST_SETGT:
352 case SQ_OP2_INST_SETGE:
353 case SQ_OP2_INST_PRED_SETE:
354 case SQ_OP2_INST_PRED_SETGT:
355 case SQ_OP2_INST_PRED_SETGE:
356 case SQ_OP2_INST_PRED_SETNE:
357 case SQ_OP2_INST_DOT4:
358 case SQ_OP2_INST_DOT4_IEEE:
359 case SQ_OP2_INST_CUBE:
360 return 2;
361
362 case SQ_OP2_INST_MOV:
363 case SQ_OP2_INST_MOVA_FLOOR:
364 case SQ_OP2_INST_FRACT:
365 case SQ_OP2_INST_FLOOR:
366 case SQ_OP2_INST_EXP_IEEE:
367 case SQ_OP2_INST_LOG_CLAMPED:
368 case SQ_OP2_INST_LOG_IEEE:
369 case SQ_OP2_INST_RECIP_IEEE:
370 case SQ_OP2_INST_RECIPSQRT_IEEE:
371 case SQ_OP2_INST_FLT_TO_INT:
372 case SQ_OP2_INST_SIN:
373 case SQ_OP2_INST_COS:
374 return 1;
375
376 default: radeon_error(
377 "Need instruction operand number for %x.\n", pAsm->D.dst.opcode);
378 };
379
380 return 3;
381 }
382
383 int Init_r700_AssemblerBase(SHADER_PIPE_TYPE spt, r700_AssemblerBase* pAsm, R700_Shader* pShader)
384 {
385 GLuint i;
386
387 Init_R700_Shader(pShader);
388 pAsm->pR700Shader = pShader;
389 pAsm->currentShaderType = spt;
390
391 pAsm->cf_last_export_ptr = NULL;
392
393 pAsm->cf_current_export_clause_ptr = NULL;
394 pAsm->cf_current_alu_clause_ptr = NULL;
395 pAsm->cf_current_tex_clause_ptr = NULL;
396 pAsm->cf_current_vtx_clause_ptr = NULL;
397 pAsm->cf_current_cf_clause_ptr = NULL;
398
399 // No clause has been created yet
400 pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
401
402 pAsm->number_of_colorandz_exports = 0;
403 pAsm->number_of_exports = 0;
404 pAsm->number_of_export_opcodes = 0;
405
406 pAsm->alu_x_opcode = 0;
407
408 pAsm->D2.bits = 0;
409
410 pAsm->D.bits = 0;
411 pAsm->S[0].bits = 0;
412 pAsm->S[1].bits = 0;
413 pAsm->S[2].bits = 0;
414
415 pAsm->uLastPosUpdate = 0;
416
417 *(BITS *) &pAsm->fp_stOutFmt0 = 0;
418
419 pAsm->uIIns = 0;
420 pAsm->uOIns = 0;
421 pAsm->number_used_registers = 0;
422 pAsm->uUsedConsts = 256;
423
424
425 // Fragment programs
426 pAsm->uBoolConsts = 0;
427 pAsm->uIntConsts = 0;
428 pAsm->uInsts = 0;
429 pAsm->uConsts = 0;
430
431 pAsm->FCSP = 0;
432 pAsm->fc_stack[0].type = FC_NONE;
433
434 pAsm->branch_depth = 0;
435 pAsm->max_branch_depth = 0;
436
437 pAsm->aArgSubst[0] =
438 pAsm->aArgSubst[1] =
439 pAsm->aArgSubst[2] =
440 pAsm->aArgSubst[3] = (-1);
441
442 pAsm->uOutputs = 0;
443
444 for (i=0; i<NUMBER_OF_OUTPUT_COLORS; i++)
445 {
446 pAsm->color_export_register_number[i] = (-1);
447 }
448
449
450 pAsm->depth_export_register_number = (-1);
451 pAsm->stencil_export_register_number = (-1);
452 pAsm->coverage_to_mask_export_register_number = (-1);
453 pAsm->mask_export_register_number = (-1);
454
455 pAsm->starting_export_register_number = 0;
456 pAsm->starting_vfetch_register_number = 0;
457 pAsm->starting_temp_register_number = 0;
458 pAsm->uFirstHelpReg = 0;
459
460
461 pAsm->input_position_is_used = GL_FALSE;
462 pAsm->input_normal_is_used = GL_FALSE;
463
464
465 for (i=0; i<NUMBER_OF_INPUT_COLORS; i++)
466 {
467 pAsm->input_color_is_used[ i ] = GL_FALSE;
468 }
469
470 for (i=0; i<NUMBER_OF_TEXTURE_UNITS; i++)
471 {
472 pAsm->input_texture_unit_is_used[ i ] = GL_FALSE;
473 }
474
475 for (i=0; i<VERT_ATTRIB_MAX; i++)
476 {
477 pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
478 }
479
480 pAsm->number_of_inputs = 0;
481
482 pAsm->is_tex = GL_FALSE;
483 pAsm->need_tex_barrier = GL_FALSE;
484
485 pAsm->subs = NULL;
486 pAsm->unSubArraySize = 0;
487 pAsm->unSubArrayPointer = 0;
488 pAsm->callers = NULL;
489 pAsm->unCallerArraySize = 0;
490 pAsm->unCallerArrayPointer = 0;
491
492 pAsm->CALLSP = 0;
493 pAsm->CALLSTACK[0].FCSP_BeforeEntry = 0;
494 pAsm->CALLSTACK[0].plstCFInstructions_local
495 = &(pAsm->pR700Shader->lstCFInstructions);
496
497 pAsm->CALLSTACK[0].stackUsage.bits = 0;
498
499 SetActiveCFlist(pAsm->pR700Shader, pAsm->CALLSTACK[0].plstCFInstructions_local);
500
501 pAsm->unCFflags = 0;
502
503 return 0;
504 }
505
506 GLboolean IsTex(gl_inst_opcode Opcode)
507 {
508 if( (OPCODE_TEX==Opcode) || (OPCODE_TXP==Opcode) || (OPCODE_TXB==Opcode) )
509 {
510 return GL_TRUE;
511 }
512 return GL_FALSE;
513 }
514
515 GLboolean IsAlu(gl_inst_opcode Opcode)
516 {
517 //TODO : more for fc and ex for higher spec.
518 if( IsTex(Opcode) )
519 {
520 return GL_FALSE;
521 }
522 return GL_TRUE;
523 }
524
525 int check_current_clause(r700_AssemblerBase* pAsm,
526 CF_CLAUSE_TYPE new_clause_type)
527 {
528 if (pAsm->cf_current_clause_type != new_clause_type)
529 { //Close last open clause
530 switch (pAsm->cf_current_clause_type)
531 {
532 case CF_ALU_CLAUSE:
533 if ( pAsm->cf_current_alu_clause_ptr != NULL)
534 {
535 pAsm->cf_current_alu_clause_ptr = NULL;
536 }
537 break;
538 case CF_VTX_CLAUSE:
539 if ( pAsm->cf_current_vtx_clause_ptr != NULL)
540 {
541 pAsm->cf_current_vtx_clause_ptr = NULL;
542 }
543 break;
544 case CF_TEX_CLAUSE:
545 if ( pAsm->cf_current_tex_clause_ptr != NULL)
546 {
547 pAsm->cf_current_tex_clause_ptr = NULL;
548 }
549 break;
550 case CF_EXPORT_CLAUSE:
551 if ( pAsm->cf_current_export_clause_ptr != NULL)
552 {
553 pAsm->cf_current_export_clause_ptr = NULL;
554 }
555 break;
556 case CF_OTHER_CLAUSE:
557 if ( pAsm->cf_current_cf_clause_ptr != NULL)
558 {
559 pAsm->cf_current_cf_clause_ptr = NULL;
560 }
561 break;
562 case CF_EMPTY_CLAUSE:
563 break;
564 default:
565 radeon_error(
566 "Unknown CF_CLAUSE_TYPE (%d) in check_current_clause. \n", (int) new_clause_type);
567 return GL_FALSE;
568 }
569
570 pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
571
572 // Create new clause
573 switch (new_clause_type)
574 {
575 case CF_ALU_CLAUSE:
576 pAsm->cf_current_clause_type = CF_ALU_CLAUSE;
577 break;
578 case CF_VTX_CLAUSE:
579 pAsm->cf_current_clause_type = CF_VTX_CLAUSE;
580 break;
581 case CF_TEX_CLAUSE:
582 pAsm->cf_current_clause_type = CF_TEX_CLAUSE;
583 break;
584 case CF_EXPORT_CLAUSE:
585 {
586 R700ControlFlowSXClause* pR700ControlFlowSXClause
587 = (R700ControlFlowSXClause*) CALLOC_STRUCT(R700ControlFlowSXClause);
588
589 // Add new export instruction to control flow program
590 if (pR700ControlFlowSXClause != 0)
591 {
592 pAsm->cf_current_export_clause_ptr = pR700ControlFlowSXClause;
593 Init_R700ControlFlowSXClause(pR700ControlFlowSXClause);
594 AddCFInstruction( pAsm->pR700Shader,
595 (R700ControlFlowInstruction *)pR700ControlFlowSXClause );
596 }
597 else
598 {
599 radeon_error(
600 "Error allocating new EXPORT CF instruction in check_current_clause. \n");
601 return GL_FALSE;
602 }
603 pAsm->cf_current_clause_type = CF_EXPORT_CLAUSE;
604 }
605 break;
606 case CF_EMPTY_CLAUSE:
607 break;
608 case CF_OTHER_CLAUSE:
609 pAsm->cf_current_clause_type = CF_OTHER_CLAUSE;
610 break;
611 default:
612 radeon_error(
613 "Unknown CF_CLAUSE_TYPE (%d) in check_current_clause. \n", (int) new_clause_type);
614 return GL_FALSE;
615 }
616 }
617
618 return GL_TRUE;
619 }
620
621 GLboolean add_cf_instruction(r700_AssemblerBase* pAsm)
622 {
623 if(GL_FALSE == check_current_clause(pAsm, CF_OTHER_CLAUSE))
624 {
625 return GL_FALSE;
626 }
627
628 pAsm->cf_current_cf_clause_ptr =
629 (R700ControlFlowGenericClause*) CALLOC_STRUCT(R700ControlFlowGenericClause);
630
631 if (pAsm->cf_current_cf_clause_ptr != NULL)
632 {
633 Init_R700ControlFlowGenericClause(pAsm->cf_current_cf_clause_ptr);
634 AddCFInstruction( pAsm->pR700Shader,
635 (R700ControlFlowInstruction *)pAsm->cf_current_cf_clause_ptr );
636 }
637 else
638 {
639 radeon_error("Could not allocate a new VFetch CF instruction.\n");
640 return GL_FALSE;
641 }
642
643 return GL_TRUE;
644 }
645
646 GLboolean add_vfetch_instruction(r700_AssemblerBase* pAsm,
647 R700VertexInstruction* vertex_instruction_ptr)
648 {
649 if( GL_FALSE == check_current_clause(pAsm, CF_VTX_CLAUSE) )
650 {
651 return GL_FALSE;
652 }
653
654 if( pAsm->cf_current_vtx_clause_ptr == NULL ||
655 ( (pAsm->cf_current_vtx_clause_ptr != NULL) &&
656 (pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count >= GetCFMaxInstructions(pAsm->cf_current_vtx_clause_ptr->m_ShaderInstType)-1)
657 ) )
658 {
659 // Create new Vfetch control flow instruction for this new clause
660 pAsm->cf_current_vtx_clause_ptr = (R700ControlFlowGenericClause*) CALLOC_STRUCT(R700ControlFlowGenericClause);
661
662 if (pAsm->cf_current_vtx_clause_ptr != NULL)
663 {
664 Init_R700ControlFlowGenericClause(pAsm->cf_current_vtx_clause_ptr);
665 AddCFInstruction( pAsm->pR700Shader,
666 (R700ControlFlowInstruction *)pAsm->cf_current_vtx_clause_ptr );
667 }
668 else
669 {
670 radeon_error("Could not allocate a new VFetch CF instruction.\n");
671 return GL_FALSE;
672 }
673
674 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.pop_count = 0x0;
675 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_const = 0x0;
676 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
677 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count = 0x0;
678 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.end_of_program = 0x0;
679 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
680 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_VTX;
681 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
682 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.barrier = 0x1;
683
684 LinkVertexInstruction(pAsm->cf_current_vtx_clause_ptr, vertex_instruction_ptr );
685 }
686 else
687 {
688 pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count++;
689 }
690
691 AddVTXInstruction(pAsm->pR700Shader, vertex_instruction_ptr);
692
693 return GL_TRUE;
694 }
695
696 GLboolean add_tex_instruction(r700_AssemblerBase* pAsm,
697 R700TextureInstruction* tex_instruction_ptr)
698 {
699 if ( GL_FALSE == check_current_clause(pAsm, CF_TEX_CLAUSE) )
700 {
701 return GL_FALSE;
702 }
703
704 if ( pAsm->cf_current_tex_clause_ptr == NULL ||
705 ( (pAsm->cf_current_tex_clause_ptr != NULL) &&
706 (pAsm->cf_current_tex_clause_ptr->m_Word1.f.count >= GetCFMaxInstructions(pAsm->cf_current_tex_clause_ptr->m_ShaderInstType)-1)
707 ) )
708 {
709 // new tex cf instruction for this new clause
710 pAsm->cf_current_tex_clause_ptr = (R700ControlFlowGenericClause*) CALLOC_STRUCT(R700ControlFlowGenericClause);
711
712 if (pAsm->cf_current_tex_clause_ptr != NULL)
713 {
714 Init_R700ControlFlowGenericClause(pAsm->cf_current_tex_clause_ptr);
715 AddCFInstruction( pAsm->pR700Shader,
716 (R700ControlFlowInstruction *)pAsm->cf_current_tex_clause_ptr );
717 }
718 else
719 {
720 radeon_error("Could not allocate a new TEX CF instruction.\n");
721 return GL_FALSE;
722 }
723
724 pAsm->cf_current_tex_clause_ptr->m_Word1.f.pop_count = 0x0;
725 pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_const = 0x0;
726 pAsm->cf_current_tex_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
727
728 pAsm->cf_current_tex_clause_ptr->m_Word1.f.end_of_program = 0x0;
729 pAsm->cf_current_tex_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
730 pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_TEX;
731 pAsm->cf_current_tex_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
732 pAsm->cf_current_tex_clause_ptr->m_Word1.f.barrier = 0x0; //0x1;
733 }
734 else
735 {
736 pAsm->cf_current_tex_clause_ptr->m_Word1.f.count++;
737 }
738
739 // If this clause constains any TEX instruction that is dependent on a previous instruction,
740 // set the barrier bit
741 if( pAsm->pInstDeps[pAsm->uiCurInst].nDstDep > (-1) || pAsm->need_tex_barrier == GL_TRUE )
742 {
743 pAsm->cf_current_tex_clause_ptr->m_Word1.f.barrier = 0x1;
744 }
745
746 if(NULL == pAsm->cf_current_tex_clause_ptr->m_pLinkedTEXInstruction)
747 {
748 pAsm->cf_current_tex_clause_ptr->m_pLinkedTEXInstruction = tex_instruction_ptr;
749 tex_instruction_ptr->m_pLinkedGenericClause = pAsm->cf_current_tex_clause_ptr;
750 }
751
752 AddTEXInstruction(pAsm->pR700Shader, tex_instruction_ptr);
753
754 return GL_TRUE;
755 }
756
757 GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
758 GLuint gl_client_id,
759 GLuint destination_register,
760 GLuint number_of_elements,
761 GLenum dataElementType,
762 VTX_FETCH_METHOD* pFetchMethod)
763 {
764 GLuint client_size_inbyte;
765 GLuint data_format;
766 GLuint mega_fetch_count;
767 GLuint is_mega_fetch_flag;
768
769 R700VertexGenericFetch* vfetch_instruction_ptr;
770 R700VertexGenericFetch* assembled_vfetch_instruction_ptr = pAsm->vfetch_instruction_ptr_array[ gl_client_id ];
771
772 if (assembled_vfetch_instruction_ptr == NULL)
773 {
774 vfetch_instruction_ptr = (R700VertexGenericFetch*) CALLOC_STRUCT(R700VertexGenericFetch);
775 if (vfetch_instruction_ptr == NULL)
776 {
777 return GL_FALSE;
778 }
779 Init_R700VertexGenericFetch(vfetch_instruction_ptr);
780 }
781 else
782 {
783 vfetch_instruction_ptr = assembled_vfetch_instruction_ptr;
784 }
785
786 data_format = GetSurfaceFormat(dataElementType, number_of_elements, &client_size_inbyte);
787
788 if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
789 {
790 //TODO : mini fetch
791 }
792 else
793 {
794 mega_fetch_count = MEGA_FETCH_BYTES - 1;
795 is_mega_fetch_flag = 0x1;
796 pFetchMethod->mega_fetch_remainder = MEGA_FETCH_BYTES - client_size_inbyte;
797 }
798
799 vfetch_instruction_ptr->m_Word0.f.vtx_inst = SQ_VTX_INST_FETCH;
800 vfetch_instruction_ptr->m_Word0.f.fetch_type = SQ_VTX_FETCH_VERTEX_DATA;
801 vfetch_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
802
803 vfetch_instruction_ptr->m_Word0.f.buffer_id = gl_client_id;
804 vfetch_instruction_ptr->m_Word0.f.src_gpr = 0x0;
805 vfetch_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
806 vfetch_instruction_ptr->m_Word0.f.src_sel_x = SQ_SEL_X;
807 vfetch_instruction_ptr->m_Word0.f.mega_fetch_count = mega_fetch_count;
808
809 vfetch_instruction_ptr->m_Word1.f.dst_sel_x = (number_of_elements < 1) ? SQ_SEL_0 : SQ_SEL_X;
810 vfetch_instruction_ptr->m_Word1.f.dst_sel_y = (number_of_elements < 2) ? SQ_SEL_0 : SQ_SEL_Y;
811 vfetch_instruction_ptr->m_Word1.f.dst_sel_z = (number_of_elements < 3) ? SQ_SEL_0 : SQ_SEL_Z;
812 vfetch_instruction_ptr->m_Word1.f.dst_sel_w = (number_of_elements < 4) ? SQ_SEL_1 : SQ_SEL_W;
813
814 vfetch_instruction_ptr->m_Word1.f.use_const_fields = 1;
815
816 // Destination register
817 vfetch_instruction_ptr->m_Word1_GPR.f.dst_gpr = destination_register;
818 vfetch_instruction_ptr->m_Word1_GPR.f.dst_rel = SQ_ABSOLUTE;
819
820 vfetch_instruction_ptr->m_Word2.f.offset = 0;
821 vfetch_instruction_ptr->m_Word2.f.const_buf_no_stride = 0x0;
822
823 vfetch_instruction_ptr->m_Word2.f.mega_fetch = is_mega_fetch_flag;
824
825 if (assembled_vfetch_instruction_ptr == NULL)
826 {
827 if ( GL_FALSE == add_vfetch_instruction(pAsm, (R700VertexInstruction *)vfetch_instruction_ptr) )
828 {
829 return GL_FALSE;
830 }
831
832 if (pAsm->vfetch_instruction_ptr_array[ gl_client_id ] != NULL)
833 {
834 return GL_FALSE;
835 }
836 else
837 {
838 pAsm->vfetch_instruction_ptr_array[ gl_client_id ] = vfetch_instruction_ptr;
839 }
840 }
841
842 return GL_TRUE;
843 }
844
845 GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
846 GLuint destination_register,
847 GLenum type,
848 GLint size,
849 GLubyte element,
850 GLuint _signed,
851 GLboolean normalize,
852 VTX_FETCH_METHOD * pFetchMethod)
853 {
854 GLuint client_size_inbyte;
855 GLuint data_format;
856 GLuint mega_fetch_count;
857 GLuint is_mega_fetch_flag;
858
859 R700VertexGenericFetch* vfetch_instruction_ptr;
860 R700VertexGenericFetch* assembled_vfetch_instruction_ptr
861 = pAsm->vfetch_instruction_ptr_array[element];
862
863 if (assembled_vfetch_instruction_ptr == NULL)
864 {
865 vfetch_instruction_ptr = (R700VertexGenericFetch*) CALLOC_STRUCT(R700VertexGenericFetch);
866 if (vfetch_instruction_ptr == NULL)
867 {
868 return GL_FALSE;
869 }
870 Init_R700VertexGenericFetch(vfetch_instruction_ptr);
871 }
872 else
873 {
874 vfetch_instruction_ptr = assembled_vfetch_instruction_ptr;
875 }
876
877 data_format = GetSurfaceFormat(type, size, &client_size_inbyte);
878
879 if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
880 {
881 //TODO : mini fetch
882 }
883 else
884 {
885 mega_fetch_count = MEGA_FETCH_BYTES - 1;
886 is_mega_fetch_flag = 0x1;
887 pFetchMethod->mega_fetch_remainder = MEGA_FETCH_BYTES - client_size_inbyte;
888 }
889
890 vfetch_instruction_ptr->m_Word0.f.vtx_inst = SQ_VTX_INST_FETCH;
891 vfetch_instruction_ptr->m_Word0.f.fetch_type = SQ_VTX_FETCH_VERTEX_DATA;
892 vfetch_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
893
894 vfetch_instruction_ptr->m_Word0.f.buffer_id = element;
895 vfetch_instruction_ptr->m_Word0.f.src_gpr = 0x0;
896 vfetch_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
897 vfetch_instruction_ptr->m_Word0.f.src_sel_x = SQ_SEL_X;
898 vfetch_instruction_ptr->m_Word0.f.mega_fetch_count = mega_fetch_count;
899
900 vfetch_instruction_ptr->m_Word1.f.dst_sel_x = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
901 vfetch_instruction_ptr->m_Word1.f.dst_sel_y = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
902 vfetch_instruction_ptr->m_Word1.f.dst_sel_z = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
903 vfetch_instruction_ptr->m_Word1.f.dst_sel_w = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
904
905 vfetch_instruction_ptr->m_Word1.f.use_const_fields = 1;
906 vfetch_instruction_ptr->m_Word1.f.data_format = data_format;
907 vfetch_instruction_ptr->m_Word2.f.endian_swap = SQ_ENDIAN_NONE;
908
909 if(1 == _signed)
910 {
911 vfetch_instruction_ptr->m_Word1.f.format_comp_all = SQ_FORMAT_COMP_SIGNED;
912 }
913 else
914 {
915 vfetch_instruction_ptr->m_Word1.f.format_comp_all = SQ_FORMAT_COMP_UNSIGNED;
916 }
917
918 if(GL_TRUE == normalize)
919 {
920 vfetch_instruction_ptr->m_Word1.f.num_format_all = SQ_NUM_FORMAT_NORM;
921 }
922 else
923 {
924 vfetch_instruction_ptr->m_Word1.f.num_format_all = SQ_NUM_FORMAT_INT;
925 }
926
927 // Destination register
928 vfetch_instruction_ptr->m_Word1_GPR.f.dst_gpr = destination_register;
929 vfetch_instruction_ptr->m_Word1_GPR.f.dst_rel = SQ_ABSOLUTE;
930
931 vfetch_instruction_ptr->m_Word2.f.offset = 0;
932 vfetch_instruction_ptr->m_Word2.f.const_buf_no_stride = 0x0;
933
934 vfetch_instruction_ptr->m_Word2.f.mega_fetch = is_mega_fetch_flag;
935
936 if (assembled_vfetch_instruction_ptr == NULL)
937 {
938 if ( GL_FALSE == add_vfetch_instruction(pAsm, (R700VertexInstruction *)vfetch_instruction_ptr) )
939 {
940 return GL_FALSE;
941 }
942
943 if (pAsm->vfetch_instruction_ptr_array[element] != NULL)
944 {
945 return GL_FALSE;
946 }
947 else
948 {
949 pAsm->vfetch_instruction_ptr_array[element] = vfetch_instruction_ptr;
950 }
951 }
952
953 return GL_TRUE;
954 }
955
956 GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm)
957 {
958 GLint i;
959 pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
960 pAsm->cf_current_vtx_clause_ptr = NULL;
961
962 for (i=0; i<VERT_ATTRIB_MAX; i++)
963 {
964 pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
965 }
966
967 cleanup_vfetch_shaderinst(pAsm->pR700Shader);
968
969 return GL_TRUE;
970 }
971
972 GLuint gethelpr(r700_AssemblerBase* pAsm)
973 {
974 GLuint r = pAsm->uHelpReg;
975 pAsm->uHelpReg++;
976 if (pAsm->uHelpReg > pAsm->number_used_registers)
977 {
978 pAsm->number_used_registers = pAsm->uHelpReg;
979 }
980 return r;
981 }
982 void resethelpr(r700_AssemblerBase* pAsm)
983 {
984 pAsm->uHelpReg = pAsm->uFirstHelpReg;
985 }
986
987 void checkop_init(r700_AssemblerBase* pAsm)
988 {
989 resethelpr(pAsm);
990 pAsm->aArgSubst[0] =
991 pAsm->aArgSubst[1] =
992 pAsm->aArgSubst[2] =
993 pAsm->aArgSubst[3] = -1;
994 }
995
996 GLboolean mov_temp(r700_AssemblerBase* pAsm, int src)
997 {
998 GLuint tmp = gethelpr(pAsm);
999
1000 //mov src to temp helper gpr.
1001 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
1002
1003 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1004
1005 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
1006 pAsm->D.dst.reg = tmp;
1007
1008 nomask_PVSDST(&(pAsm->D.dst));
1009
1010 if( GL_FALSE == assemble_src(pAsm, src, 0) )
1011 {
1012 return GL_FALSE;
1013 }
1014
1015 noswizzle_PVSSRC(&(pAsm->S[0].src));
1016 noneg_PVSSRC(&(pAsm->S[0].src));
1017
1018 if( GL_FALSE == next_ins(pAsm) )
1019 {
1020 return GL_FALSE;
1021 }
1022
1023 pAsm->aArgSubst[1 + src] = tmp;
1024
1025 return GL_TRUE;
1026 }
1027
1028 GLboolean checkop1(r700_AssemblerBase* pAsm)
1029 {
1030 checkop_init(pAsm);
1031 return GL_TRUE;
1032 }
1033
1034 GLboolean checkop2(r700_AssemblerBase* pAsm)
1035 {
1036 GLboolean bSrcConst[2];
1037 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1038
1039 checkop_init(pAsm);
1040
1041 if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) ||
1042 (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) ||
1043 (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) ||
1044 (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) )
1045 {
1046 bSrcConst[0] = GL_TRUE;
1047 }
1048 else
1049 {
1050 bSrcConst[0] = GL_FALSE;
1051 }
1052 if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) ||
1053 (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) ||
1054 (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) ||
1055 (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) )
1056 {
1057 bSrcConst[1] = GL_TRUE;
1058 }
1059 else
1060 {
1061 bSrcConst[1] = GL_FALSE;
1062 }
1063
1064 if( (bSrcConst[0] == GL_TRUE) && (bSrcConst[1] == GL_TRUE) )
1065 {
1066 if(pILInst->SrcReg[0].Index != pILInst->SrcReg[1].Index)
1067 {
1068 if( GL_FALSE == mov_temp(pAsm, 1) )
1069 {
1070 return GL_FALSE;
1071 }
1072 }
1073 }
1074
1075 return GL_TRUE;
1076 }
1077
1078 GLboolean checkop3(r700_AssemblerBase* pAsm)
1079 {
1080 GLboolean bSrcConst[3];
1081 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1082
1083 checkop_init(pAsm);
1084
1085 if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) ||
1086 (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) ||
1087 (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) ||
1088 (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) )
1089 {
1090 bSrcConst[0] = GL_TRUE;
1091 }
1092 else
1093 {
1094 bSrcConst[0] = GL_FALSE;
1095 }
1096 if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) ||
1097 (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) ||
1098 (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) ||
1099 (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) )
1100 {
1101 bSrcConst[1] = GL_TRUE;
1102 }
1103 else
1104 {
1105 bSrcConst[1] = GL_FALSE;
1106 }
1107 if( (pILInst->SrcReg[2].File == PROGRAM_CONSTANT) ||
1108 (pILInst->SrcReg[2].File == PROGRAM_LOCAL_PARAM) ||
1109 (pILInst->SrcReg[2].File == PROGRAM_ENV_PARAM) ||
1110 (pILInst->SrcReg[2].File == PROGRAM_STATE_VAR) )
1111 {
1112 bSrcConst[2] = GL_TRUE;
1113 }
1114 else
1115 {
1116 bSrcConst[2] = GL_FALSE;
1117 }
1118
1119 if( (GL_TRUE == bSrcConst[0]) &&
1120 (GL_TRUE == bSrcConst[1]) &&
1121 (GL_TRUE == bSrcConst[2]) )
1122 {
1123 if( GL_FALSE == mov_temp(pAsm, 1) )
1124 {
1125 return GL_FALSE;
1126 }
1127 if( GL_FALSE == mov_temp(pAsm, 2) )
1128 {
1129 return GL_FALSE;
1130 }
1131
1132 return GL_TRUE;
1133 }
1134 else if( (GL_TRUE == bSrcConst[0]) &&
1135 (GL_TRUE == bSrcConst[1]) )
1136 {
1137 if(pILInst->SrcReg[0].Index != pILInst->SrcReg[1].Index)
1138 {
1139 if( GL_FALSE == mov_temp(pAsm, 1) )
1140 {
1141 return 1;
1142 }
1143 }
1144
1145 return GL_TRUE;
1146 }
1147 else if ( (GL_TRUE == bSrcConst[0]) &&
1148 (GL_TRUE == bSrcConst[2]) )
1149 {
1150 if(pILInst->SrcReg[0].Index != pILInst->SrcReg[2].Index)
1151 {
1152 if( GL_FALSE == mov_temp(pAsm, 2) )
1153 {
1154 return GL_FALSE;
1155 }
1156 }
1157
1158 return GL_TRUE;
1159 }
1160 else if( (GL_TRUE == bSrcConst[1]) &&
1161 (GL_TRUE == bSrcConst[2]) )
1162 {
1163 if(pILInst->SrcReg[1].Index != pILInst->SrcReg[2].Index)
1164 {
1165 if( GL_FALSE == mov_temp(pAsm, 2) )
1166 {
1167 return GL_FALSE;
1168 }
1169 }
1170
1171 return GL_TRUE;
1172 }
1173
1174 return GL_TRUE;
1175 }
1176
1177 GLboolean assemble_src(r700_AssemblerBase *pAsm,
1178 int src,
1179 int fld)
1180 {
1181 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1182
1183 if (fld == -1)
1184 {
1185 fld = src;
1186 }
1187
1188 if(pAsm->aArgSubst[1+src] >= 0)
1189 {
1190 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
1191 pAsm->S[fld].src.rtype = SRC_REG_TEMPORARY;
1192 pAsm->S[fld].src.reg = pAsm->aArgSubst[1+src];
1193 }
1194 else
1195 {
1196 switch (pILInst->SrcReg[src].File)
1197 {
1198 case PROGRAM_TEMPORARY:
1199 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
1200 pAsm->S[fld].src.rtype = SRC_REG_TEMPORARY;
1201 pAsm->S[fld].src.reg = pILInst->SrcReg[src].Index + pAsm->starting_temp_register_number;
1202 break;
1203 case PROGRAM_CONSTANT:
1204 case PROGRAM_LOCAL_PARAM:
1205 case PROGRAM_ENV_PARAM:
1206 case PROGRAM_STATE_VAR:
1207 case PROGRAM_UNIFORM:
1208 if (1 == pILInst->SrcReg[src].RelAddr)
1209 {
1210 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_RELATIVE_A0);
1211 }
1212 else
1213 {
1214 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
1215 }
1216
1217 pAsm->S[fld].src.rtype = SRC_REG_CONSTANT;
1218 pAsm->S[fld].src.reg = pILInst->SrcReg[src].Index;
1219 break;
1220 case PROGRAM_INPUT:
1221 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
1222 pAsm->S[fld].src.rtype = SRC_REG_INPUT;
1223 switch (pAsm->currentShaderType)
1224 {
1225 case SPT_FP:
1226 pAsm->S[fld].src.reg = pAsm->uiFP_AttributeMap[pILInst->SrcReg[src].Index];
1227 break;
1228 case SPT_VP:
1229 pAsm->S[fld].src.reg = pAsm->ucVP_AttributeMap[pILInst->SrcReg[src].Index];
1230 break;
1231 }
1232 break;
1233 default:
1234 radeon_error("Invalid source argument type : %d \n", pILInst->SrcReg[src].File);
1235 return GL_FALSE;
1236 }
1237 }
1238
1239 pAsm->S[fld].src.swizzlex = pILInst->SrcReg[src].Swizzle & 0x7;
1240 pAsm->S[fld].src.swizzley = (pILInst->SrcReg[src].Swizzle >> 3) & 0x7;
1241 pAsm->S[fld].src.swizzlez = (pILInst->SrcReg[src].Swizzle >> 6) & 0x7;
1242 pAsm->S[fld].src.swizzlew = (pILInst->SrcReg[src].Swizzle >> 9) & 0x7;
1243
1244 pAsm->S[fld].src.negx = pILInst->SrcReg[src].Negate & 0x1;
1245 pAsm->S[fld].src.negy = (pILInst->SrcReg[src].Negate >> 1) & 0x1;
1246 pAsm->S[fld].src.negz = (pILInst->SrcReg[src].Negate >> 2) & 0x1;
1247 pAsm->S[fld].src.negw = (pILInst->SrcReg[src].Negate >> 3) & 0x1;
1248
1249 return GL_TRUE;
1250 }
1251
1252 GLboolean assemble_dst(r700_AssemblerBase *pAsm)
1253 {
1254 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1255 switch (pILInst->DstReg.File)
1256 {
1257 case PROGRAM_TEMPORARY:
1258 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1259 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
1260 pAsm->D.dst.reg = pILInst->DstReg.Index + pAsm->starting_temp_register_number;
1261 break;
1262 case PROGRAM_ADDRESS:
1263 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1264 pAsm->D.dst.rtype = DST_REG_A0;
1265 pAsm->D.dst.reg = 0;
1266 break;
1267 case PROGRAM_OUTPUT:
1268 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1269 pAsm->D.dst.rtype = DST_REG_OUT;
1270 switch (pAsm->currentShaderType)
1271 {
1272 case SPT_FP:
1273 pAsm->D.dst.reg = pAsm->uiFP_OutputMap[pILInst->DstReg.Index];
1274 break;
1275 case SPT_VP:
1276 pAsm->D.dst.reg = pAsm->ucVP_OutputMap[pILInst->DstReg.Index];
1277 break;
1278 }
1279 break;
1280 default:
1281 radeon_error("Invalid destination output argument type\n");
1282 return GL_FALSE;
1283 }
1284
1285 pAsm->D.dst.writex = pILInst->DstReg.WriteMask & 0x1;
1286 pAsm->D.dst.writey = (pILInst->DstReg.WriteMask >> 1) & 0x1;
1287 pAsm->D.dst.writez = (pILInst->DstReg.WriteMask >> 2) & 0x1;
1288 pAsm->D.dst.writew = (pILInst->DstReg.WriteMask >> 3) & 0x1;
1289
1290 return GL_TRUE;
1291 }
1292
1293 GLboolean tex_dst(r700_AssemblerBase *pAsm)
1294 {
1295 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1296
1297 if(PROGRAM_TEMPORARY == pILInst->DstReg.File)
1298 {
1299 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
1300 pAsm->D.dst.reg = pAsm->pILInst[pAsm->uiCurInst].DstReg.Index + pAsm->starting_temp_register_number;
1301
1302 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1303 }
1304 else if(PROGRAM_OUTPUT == pILInst->DstReg.File)
1305 {
1306 pAsm->D.dst.rtype = DST_REG_OUT;
1307 switch (pAsm->currentShaderType)
1308 {
1309 case SPT_FP:
1310 pAsm->D.dst.reg = pAsm->uiFP_OutputMap[pILInst->DstReg.Index];
1311 break;
1312 case SPT_VP:
1313 pAsm->D.dst.reg = pAsm->ucVP_OutputMap[pILInst->DstReg.Index];
1314 break;
1315 }
1316
1317 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
1318 }
1319 else
1320 {
1321 radeon_error("Invalid destination output argument type\n");
1322 return GL_FALSE;
1323 }
1324
1325 pAsm->D.dst.writex = pILInst->DstReg.WriteMask & 0x1;
1326 pAsm->D.dst.writey = (pILInst->DstReg.WriteMask >> 1) & 0x1;
1327 pAsm->D.dst.writez = (pILInst->DstReg.WriteMask >> 2) & 0x1;
1328 pAsm->D.dst.writew = (pILInst->DstReg.WriteMask >> 3) & 0x1;
1329
1330 return GL_TRUE;
1331 }
1332
1333 GLboolean tex_src(r700_AssemblerBase *pAsm)
1334 {
1335 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
1336
1337 GLboolean bValidTexCoord = GL_FALSE;
1338
1339 if(pAsm->aArgSubst[1] >= 0)
1340 {
1341 bValidTexCoord = GL_TRUE;
1342 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
1343 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
1344 pAsm->S[0].src.reg = pAsm->aArgSubst[1];
1345 }
1346 else
1347 {
1348 switch (pILInst->SrcReg[0].File) {
1349 case PROGRAM_CONSTANT:
1350 case PROGRAM_LOCAL_PARAM:
1351 case PROGRAM_ENV_PARAM:
1352 case PROGRAM_STATE_VAR:
1353 break;
1354 case PROGRAM_TEMPORARY:
1355 bValidTexCoord = GL_TRUE;
1356 pAsm->S[0].src.reg = pILInst->SrcReg[0].Index +
1357 pAsm->starting_temp_register_number;
1358 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
1359 break;
1360 case PROGRAM_INPUT:
1361 switch (pILInst->SrcReg[0].Index)
1362 {
1363 case FRAG_ATTRIB_WPOS:
1364 case FRAG_ATTRIB_COL0:
1365 case FRAG_ATTRIB_COL1:
1366 case FRAG_ATTRIB_FOGC:
1367 case FRAG_ATTRIB_TEX0:
1368 case FRAG_ATTRIB_TEX1:
1369 case FRAG_ATTRIB_TEX2:
1370 case FRAG_ATTRIB_TEX3:
1371 case FRAG_ATTRIB_TEX4:
1372 case FRAG_ATTRIB_TEX5:
1373 case FRAG_ATTRIB_TEX6:
1374 case FRAG_ATTRIB_TEX7:
1375 bValidTexCoord = GL_TRUE;
1376 pAsm->S[0].src.reg =
1377 pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
1378 pAsm->S[0].src.rtype = SRC_REG_INPUT;
1379 break;
1380 case FRAG_ATTRIB_FACE:
1381 fprintf(stderr, "FRAG_ATTRIB_FACE unsupported\n");
1382 break;
1383 case FRAG_ATTRIB_PNTC:
1384 fprintf(stderr, "FRAG_ATTRIB_PNTC unsupported\n");
1385 break;
1386 case FRAG_ATTRIB_VAR0:
1387 fprintf(stderr, "FRAG_ATTRIB_VAR0 unsupported\n");
1388 break;
1389 }
1390
1391 if( (pILInst->SrcReg[0].Index >= FRAG_ATTRIB_VAR0) ||
1392 (pILInst->SrcReg[0].Index < FRAG_ATTRIB_MAX) )
1393 {
1394 bValidTexCoord = GL_TRUE;
1395 pAsm->S[0].src.reg =
1396 pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
1397 pAsm->S[0].src.rtype = SRC_REG_INPUT;
1398 }
1399
1400 break;
1401 }
1402 }
1403
1404 if(GL_TRUE == bValidTexCoord)
1405 {
1406 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
1407 }
1408 else
1409 {
1410 radeon_error("Invalid source texcoord for TEX instruction\n");
1411 return GL_FALSE;
1412 }
1413
1414 pAsm->S[0].src.swizzlex = pILInst->SrcReg[0].Swizzle & 0x7;
1415 pAsm->S[0].src.swizzley = (pILInst->SrcReg[0].Swizzle >> 3) & 0x7;
1416 pAsm->S[0].src.swizzlez = (pILInst->SrcReg[0].Swizzle >> 6) & 0x7;
1417 pAsm->S[0].src.swizzlew = (pILInst->SrcReg[0].Swizzle >> 9) & 0x7;
1418
1419 pAsm->S[0].src.negx = pILInst->SrcReg[0].Negate & 0x1;
1420 pAsm->S[0].src.negy = (pILInst->SrcReg[0].Negate >> 1) & 0x1;
1421 pAsm->S[0].src.negz = (pILInst->SrcReg[0].Negate >> 2) & 0x1;
1422 pAsm->S[0].src.negw = (pILInst->SrcReg[0].Negate >> 3) & 0x1;
1423
1424 return GL_TRUE;
1425 }
1426
1427 GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalized)
1428 {
1429 PVSSRC * texture_coordinate_source;
1430 PVSSRC * texture_unit_source;
1431
1432 R700TextureInstruction* tex_instruction_ptr = (R700TextureInstruction*) CALLOC_STRUCT(R700TextureInstruction);
1433 if (tex_instruction_ptr == NULL)
1434 {
1435 return GL_FALSE;
1436 }
1437 Init_R700TextureInstruction(tex_instruction_ptr);
1438
1439 texture_coordinate_source = &(pAsm->S[0].src);
1440 texture_unit_source = &(pAsm->S[1].src);
1441
1442 tex_instruction_ptr->m_Word0.f.tex_inst = pAsm->D.dst.opcode;
1443 tex_instruction_ptr->m_Word0.f.bc_frac_mode = 0x0;
1444 tex_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
1445
1446 tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg;
1447
1448 tex_instruction_ptr->m_Word1.f.lod_bias = 0x0;
1449 if (normalized) {
1450 tex_instruction_ptr->m_Word1.f.coord_type_x = SQ_TEX_NORMALIZED;
1451 tex_instruction_ptr->m_Word1.f.coord_type_y = SQ_TEX_NORMALIZED;
1452 tex_instruction_ptr->m_Word1.f.coord_type_z = SQ_TEX_NORMALIZED;
1453 tex_instruction_ptr->m_Word1.f.coord_type_w = SQ_TEX_NORMALIZED;
1454 } else {
1455 /* XXX: UNNORMALIZED tex coords have limited wrap modes */
1456 tex_instruction_ptr->m_Word1.f.coord_type_x = SQ_TEX_UNNORMALIZED;
1457 tex_instruction_ptr->m_Word1.f.coord_type_y = SQ_TEX_UNNORMALIZED;
1458 tex_instruction_ptr->m_Word1.f.coord_type_z = SQ_TEX_UNNORMALIZED;
1459 tex_instruction_ptr->m_Word1.f.coord_type_w = SQ_TEX_UNNORMALIZED;
1460 }
1461
1462 tex_instruction_ptr->m_Word2.f.offset_x = 0x0;
1463 tex_instruction_ptr->m_Word2.f.offset_y = 0x0;
1464 tex_instruction_ptr->m_Word2.f.offset_z = 0x0;
1465
1466 tex_instruction_ptr->m_Word2.f.sampler_id = texture_unit_source->reg;
1467
1468 // dst
1469 if ( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) ||
1470 (pAsm->D.dst.rtype == DST_REG_OUT) )
1471 {
1472 tex_instruction_ptr->m_Word0.f.src_gpr = texture_coordinate_source->reg;
1473 tex_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
1474
1475 tex_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg;
1476 tex_instruction_ptr->m_Word1.f.dst_rel = SQ_ABSOLUTE;
1477
1478 tex_instruction_ptr->m_Word1.f.dst_sel_x = (pAsm->D.dst.writex ? texture_unit_source->swizzlex : SQ_SEL_MASK);
1479 tex_instruction_ptr->m_Word1.f.dst_sel_y = (pAsm->D.dst.writey ? texture_unit_source->swizzley : SQ_SEL_MASK);
1480 tex_instruction_ptr->m_Word1.f.dst_sel_z = (pAsm->D.dst.writez ? texture_unit_source->swizzlez : SQ_SEL_MASK);
1481 tex_instruction_ptr->m_Word1.f.dst_sel_w = (pAsm->D.dst.writew ? texture_unit_source->swizzlew : SQ_SEL_MASK);
1482
1483
1484 tex_instruction_ptr->m_Word2.f.src_sel_x = texture_coordinate_source->swizzlex;
1485 tex_instruction_ptr->m_Word2.f.src_sel_y = texture_coordinate_source->swizzley;
1486 tex_instruction_ptr->m_Word2.f.src_sel_z = texture_coordinate_source->swizzlez;
1487 tex_instruction_ptr->m_Word2.f.src_sel_w = texture_coordinate_source->swizzlew;
1488 }
1489 else
1490 {
1491 radeon_error("Only temp destination registers supported for TEX dest regs.\n");
1492 return GL_FALSE;
1493 }
1494
1495 if( GL_FALSE == add_tex_instruction(pAsm, tex_instruction_ptr) )
1496 {
1497 return GL_FALSE;
1498 }
1499
1500 return GL_TRUE;
1501 }
1502
1503 void initialize(r700_AssemblerBase *pAsm)
1504 {
1505 GLuint cycle, component;
1506
1507 for (cycle=0; cycle<NUMBER_OF_CYCLES; cycle++)
1508 {
1509 for (component=0; component<NUMBER_OF_COMPONENTS; component++)
1510 {
1511 pAsm->hw_gpr[cycle][component] = (-1);
1512 }
1513 }
1514 for (component=0; component<NUMBER_OF_COMPONENTS; component++)
1515 {
1516 pAsm->hw_cfile_addr[component] = (-1);
1517 pAsm->hw_cfile_chan[component] = (-1);
1518 }
1519 }
1520
1521 GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
1522 int source_index,
1523 PVSSRC* pSource,
1524 BITS scalar_channel_index)
1525 {
1526 BITS src_sel;
1527 BITS src_rel;
1528 BITS src_chan;
1529 BITS src_neg;
1530
1531 //--------------------------------------------------------------------------
1532 // Source for operands src0, src1.
1533 // Values [0,127] correspond to GPR[0..127].
1534 // Values [256,511] correspond to cfile constants c[0..255].
1535
1536 //--------------------------------------------------------------------------
1537 // Other special values are shown in the list below.
1538
1539 // 248 SQ_ALU_SRC_0: special constant 0.0.
1540 // 249 SQ_ALU_SRC_1: special constant 1.0 float.
1541
1542 // 250 SQ_ALU_SRC_1_INT: special constant 1 integer.
1543 // 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer.
1544
1545 // 252 SQ_ALU_SRC_0_5: special constant 0.5 float.
1546 // 253 SQ_ALU_SRC_LITERAL: literal constant.
1547
1548 // 254 SQ_ALU_SRC_PV: previous vector result.
1549 // 255 SQ_ALU_SRC_PS: previous scalar result.
1550 //--------------------------------------------------------------------------
1551
1552 BITS channel_swizzle;
1553 switch (scalar_channel_index)
1554 {
1555 case 0: channel_swizzle = pSource->swizzlex; break;
1556 case 1: channel_swizzle = pSource->swizzley; break;
1557 case 2: channel_swizzle = pSource->swizzlez; break;
1558 case 3: channel_swizzle = pSource->swizzlew; break;
1559 default: channel_swizzle = SQ_SEL_MASK; break;
1560 }
1561
1562 if(channel_swizzle == SQ_SEL_0)
1563 {
1564 src_sel = SQ_ALU_SRC_0;
1565 }
1566 else if (channel_swizzle == SQ_SEL_1)
1567 {
1568 src_sel = SQ_ALU_SRC_1;
1569 }
1570 else
1571 {
1572 if ( (pSource->rtype == SRC_REG_TEMPORARY) ||
1573 (pSource->rtype == SRC_REG_INPUT)
1574 )
1575 {
1576 src_sel = pSource->reg;
1577 }
1578 else if (pSource->rtype == SRC_REG_CONSTANT)
1579 {
1580 src_sel = pSource->reg + CFILE_REGISTER_OFFSET;
1581 }
1582 else if (pSource->rtype == SRC_REC_LITERAL)
1583 {
1584 src_sel = SQ_ALU_SRC_LITERAL;
1585 }
1586 else
1587 {
1588 radeon_error("Source (%d) register type (%d) not one of TEMP, INPUT, or CONSTANT.\n",
1589 source_index, pSource->rtype);
1590 return GL_FALSE;
1591 }
1592 }
1593
1594 if( ADDR_ABSOLUTE == addrmode_PVSSRC(pSource) )
1595 {
1596 src_rel = SQ_ABSOLUTE;
1597 }
1598 else
1599 {
1600 src_rel = SQ_RELATIVE;
1601 }
1602
1603 switch (channel_swizzle)
1604 {
1605 case SQ_SEL_X:
1606 src_chan = SQ_CHAN_X;
1607 break;
1608 case SQ_SEL_Y:
1609 src_chan = SQ_CHAN_Y;
1610 break;
1611 case SQ_SEL_Z:
1612 src_chan = SQ_CHAN_Z;
1613 break;
1614 case SQ_SEL_W:
1615 src_chan = SQ_CHAN_W;
1616 break;
1617 case SQ_SEL_0:
1618 case SQ_SEL_1:
1619 // Does not matter since src_sel controls
1620 src_chan = SQ_CHAN_X;
1621 break;
1622 default:
1623 radeon_error("Unknown source select value (%d) in assemble_alu_src().\n", channel_swizzle);
1624 return GL_FALSE;
1625 break;
1626 }
1627
1628 switch (scalar_channel_index)
1629 {
1630 case 0: src_neg = pSource->negx; break;
1631 case 1: src_neg = pSource->negy; break;
1632 case 2: src_neg = pSource->negz; break;
1633 case 3: src_neg = pSource->negw; break;
1634 default: src_neg = 0; break;
1635 }
1636
1637 switch (source_index)
1638 {
1639 case 0:
1640 alu_instruction_ptr->m_Word0.f.src0_sel = src_sel;
1641 alu_instruction_ptr->m_Word0.f.src0_rel = src_rel;
1642 alu_instruction_ptr->m_Word0.f.src0_chan = src_chan;
1643 alu_instruction_ptr->m_Word0.f.src0_neg = src_neg;
1644 break;
1645 case 1:
1646 alu_instruction_ptr->m_Word0.f.src1_sel = src_sel;
1647 alu_instruction_ptr->m_Word0.f.src1_rel = src_rel;
1648 alu_instruction_ptr->m_Word0.f.src1_chan = src_chan;
1649 alu_instruction_ptr->m_Word0.f.src1_neg = src_neg;
1650 break;
1651 case 2:
1652 alu_instruction_ptr->m_Word1_OP3.f.src2_sel = src_sel;
1653 alu_instruction_ptr->m_Word1_OP3.f.src2_rel = src_rel;
1654 alu_instruction_ptr->m_Word1_OP3.f.src2_chan = src_chan;
1655 alu_instruction_ptr->m_Word1_OP3.f.src2_neg = src_neg;
1656 break;
1657 default:
1658 radeon_error("Only three sources allowed in ALU opcodes.\n");
1659 return GL_FALSE;
1660 break;
1661 }
1662
1663 return GL_TRUE;
1664 }
1665
1666 GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
1667 R700ALUInstruction* alu_instruction_ptr,
1668 GLuint contiguous_slots_needed)
1669 {
1670 if( GL_FALSE == check_current_clause(pAsm, CF_ALU_CLAUSE) )
1671 {
1672 return GL_FALSE;
1673 }
1674
1675 if ( pAsm->alu_x_opcode != 0 ||
1676 pAsm->cf_current_alu_clause_ptr == NULL ||
1677 ( (pAsm->cf_current_alu_clause_ptr != NULL) &&
1678 (pAsm->cf_current_alu_clause_ptr->m_Word1.f.count >= (GetCFMaxInstructions(pAsm->cf_current_alu_clause_ptr->m_ShaderInstType)-contiguous_slots_needed-1) )
1679 ) )
1680 {
1681
1682 //new cf inst for this clause
1683 pAsm->cf_current_alu_clause_ptr = (R700ControlFlowALUClause*) CALLOC_STRUCT(R700ControlFlowALUClause);
1684
1685 // link the new cf to cf segment
1686 if(NULL != pAsm->cf_current_alu_clause_ptr)
1687 {
1688 Init_R700ControlFlowALUClause(pAsm->cf_current_alu_clause_ptr);
1689 AddCFInstruction( pAsm->pR700Shader,
1690 (R700ControlFlowInstruction *)pAsm->cf_current_alu_clause_ptr );
1691 }
1692 else
1693 {
1694 radeon_error("Could not allocate a new ALU CF instruction.\n");
1695 return GL_FALSE;
1696 }
1697
1698 pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_bank0 = 0x0;
1699 pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_bank1 = 0x0;
1700 pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_mode0 = SQ_CF_KCACHE_NOP;
1701
1702 pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_mode1 = SQ_CF_KCACHE_NOP;
1703 pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr0 = 0x0;
1704 pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr1 = 0x0;
1705
1706 pAsm->cf_current_alu_clause_ptr->m_Word1.f.count = 0x0;
1707
1708 if(pAsm->alu_x_opcode != 0)
1709 {
1710 pAsm->cf_current_alu_clause_ptr->m_Word1.f.cf_inst = pAsm->alu_x_opcode;
1711 pAsm->alu_x_opcode = 0;
1712 }
1713 else
1714 {
1715 pAsm->cf_current_alu_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_ALU;
1716 }
1717
1718 pAsm->cf_current_alu_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
1719
1720 pAsm->cf_current_alu_clause_ptr->m_Word1.f.barrier = 0x1;
1721 }
1722 else
1723 {
1724 pAsm->cf_current_alu_clause_ptr->m_Word1.f.count++;
1725 }
1726
1727 // If this clause constains any instruction that is forward dependent on a TEX instruction,
1728 // set the whole_quad_mode for this clause
1729 if ( pAsm->pInstDeps[pAsm->uiCurInst].nDstDep > (-1) )
1730 {
1731 pAsm->cf_current_alu_clause_ptr->m_Word1.f.whole_quad_mode = 0x1;
1732 }
1733
1734 if (pAsm->cf_current_alu_clause_ptr->m_Word1.f.count >= (GetCFMaxInstructions(pAsm->cf_current_alu_clause_ptr->m_ShaderInstType)-1) )
1735 {
1736 alu_instruction_ptr->m_Word0.f.last = 1;
1737 }
1738
1739 if(NULL == pAsm->cf_current_alu_clause_ptr->m_pLinkedALUInstruction)
1740 {
1741 pAsm->cf_current_alu_clause_ptr->m_pLinkedALUInstruction = alu_instruction_ptr;
1742 alu_instruction_ptr->m_pLinkedALUClause = pAsm->cf_current_alu_clause_ptr;
1743 }
1744
1745 AddALUInstruction(pAsm->pR700Shader, alu_instruction_ptr);
1746
1747 return GL_TRUE;
1748 }
1749
1750 void get_src_properties(R700ALUInstruction* alu_instruction_ptr,
1751 int source_index,
1752 BITS* psrc_sel,
1753 BITS* psrc_rel,
1754 BITS* psrc_chan,
1755 BITS* psrc_neg)
1756 {
1757 switch (source_index)
1758 {
1759 case 0:
1760 *psrc_sel = alu_instruction_ptr->m_Word0.f.src0_sel ;
1761 *psrc_rel = alu_instruction_ptr->m_Word0.f.src0_rel ;
1762 *psrc_chan = alu_instruction_ptr->m_Word0.f.src0_chan;
1763 *psrc_neg = alu_instruction_ptr->m_Word0.f.src0_neg ;
1764 break;
1765
1766 case 1:
1767 *psrc_sel = alu_instruction_ptr->m_Word0.f.src1_sel ;
1768 *psrc_rel = alu_instruction_ptr->m_Word0.f.src1_rel ;
1769 *psrc_chan = alu_instruction_ptr->m_Word0.f.src1_chan;
1770 *psrc_neg = alu_instruction_ptr->m_Word0.f.src1_neg ;
1771 break;
1772
1773 case 2:
1774 *psrc_sel = alu_instruction_ptr->m_Word1_OP3.f.src2_sel;
1775 *psrc_rel = alu_instruction_ptr->m_Word1_OP3.f.src2_rel;
1776 *psrc_chan = alu_instruction_ptr->m_Word1_OP3.f.src2_chan;
1777 *psrc_neg = alu_instruction_ptr->m_Word1_OP3.f.src2_neg;
1778 break;
1779 }
1780 }
1781
1782 int is_cfile(BITS sel)
1783 {
1784 if (sel > 255 && sel < 512)
1785 {
1786 return 1;
1787 }
1788 return 0;
1789 }
1790
1791 int is_const(BITS sel)
1792 {
1793 if (is_cfile(sel))
1794 {
1795 return 1;
1796 }
1797 else if(sel >= SQ_ALU_SRC_0 && sel <= SQ_ALU_SRC_LITERAL)
1798 {
1799 return 1;
1800 }
1801 return 0;
1802 }
1803
1804 int is_gpr(BITS sel)
1805 {
1806 if (sel >= 0 && sel < 128)
1807 {
1808 return 1;
1809 }
1810 return 0;
1811 }
1812
1813 const GLuint BANK_SWIZZLE_VEC[8] = {SQ_ALU_VEC_210, //000
1814 SQ_ALU_VEC_120, //001
1815 SQ_ALU_VEC_102, //010
1816
1817 SQ_ALU_VEC_201, //011
1818 SQ_ALU_VEC_012, //100
1819 SQ_ALU_VEC_021, //101
1820
1821 SQ_ALU_VEC_012, //110
1822 SQ_ALU_VEC_012}; //111
1823
1824 const GLuint BANK_SWIZZLE_SCL[8] = {SQ_ALU_SCL_210, //000
1825 SQ_ALU_SCL_122, //001
1826 SQ_ALU_SCL_122, //010
1827
1828 SQ_ALU_SCL_221, //011
1829 SQ_ALU_SCL_212, //100
1830 SQ_ALU_SCL_122, //101
1831
1832 SQ_ALU_SCL_122, //110
1833 SQ_ALU_SCL_122}; //111
1834
1835 GLboolean reserve_cfile(r700_AssemblerBase* pAsm,
1836 GLuint sel,
1837 GLuint chan)
1838 {
1839 int res_match = (-1);
1840 int res_empty = (-1);
1841
1842 GLint res;
1843
1844 for (res=3; res>=0; res--)
1845 {
1846 if(pAsm->hw_cfile_addr[ res] < 0)
1847 {
1848 res_empty = res;
1849 }
1850 else if( (pAsm->hw_cfile_addr[res] == (int)sel)
1851 &&
1852 (pAsm->hw_cfile_chan[ res ] == (int) chan) )
1853 {
1854 res_match = res;
1855 }
1856 }
1857
1858 if(res_match >= 0)
1859 {
1860 // Read for this scalar component already reserved, nothing to do here.
1861 ;
1862 }
1863 else if(res_empty >= 0)
1864 {
1865 pAsm->hw_cfile_addr[ res_empty ] = sel;
1866 pAsm->hw_cfile_chan[ res_empty ] = chan;
1867 }
1868 else
1869 {
1870 radeon_error("All cfile read ports are used, cannot reference C$sel, channel $chan.\n");
1871 return GL_FALSE;
1872 }
1873 return GL_TRUE;
1874 }
1875
1876 GLboolean reserve_gpr(r700_AssemblerBase* pAsm, GLuint sel, GLuint chan, GLuint cycle)
1877 {
1878 if(pAsm->hw_gpr[cycle][chan] < 0)
1879 {
1880 pAsm->hw_gpr[cycle][chan] = sel;
1881 }
1882 else if(pAsm->hw_gpr[cycle][chan] != (int)sel)
1883 {
1884 radeon_error("Another scalar operation has already used GPR read port for given channel\n");
1885 return GL_FALSE;
1886 }
1887
1888 return GL_TRUE;
1889 }
1890
1891 GLboolean cycle_for_scalar_bank_swizzle(const int swiz, const int sel, GLuint* pCycle)
1892 {
1893 switch (swiz)
1894 {
1895 case SQ_ALU_SCL_210:
1896 {
1897 int table[3] = {2, 1, 0};
1898 *pCycle = table[sel];
1899 return GL_TRUE;
1900 }
1901 break;
1902 case SQ_ALU_SCL_122:
1903 {
1904 int table[3] = {1, 2, 2};
1905 *pCycle = table[sel];
1906 return GL_TRUE;
1907 }
1908 break;
1909 case SQ_ALU_SCL_212:
1910 {
1911 int table[3] = {2, 1, 2};
1912 *pCycle = table[sel];
1913 return GL_TRUE;
1914 }
1915 break;
1916 case SQ_ALU_SCL_221:
1917 {
1918 int table[3] = {2, 2, 1};
1919 *pCycle = table[sel];
1920 return GL_TRUE;
1921 }
1922 break;
1923 default:
1924 radeon_error("Bad Scalar bank swizzle value\n");
1925 break;
1926 }
1927
1928 return GL_FALSE;
1929 }
1930
1931 GLboolean cycle_for_vector_bank_swizzle(const int swiz, const int sel, GLuint* pCycle)
1932 {
1933 switch (swiz)
1934 {
1935 case SQ_ALU_VEC_012:
1936 {
1937 int table[3] = {0, 1, 2};
1938 *pCycle = table[sel];
1939 }
1940 break;
1941 case SQ_ALU_VEC_021:
1942 {
1943 int table[3] = {0, 2, 1};
1944 *pCycle = table[sel];
1945 }
1946 break;
1947 case SQ_ALU_VEC_120:
1948 {
1949 int table[3] = {1, 2, 0};
1950 *pCycle = table[sel];
1951 }
1952 break;
1953 case SQ_ALU_VEC_102:
1954 {
1955 int table[3] = {1, 0, 2};
1956 *pCycle = table[sel];
1957 }
1958 break;
1959 case SQ_ALU_VEC_201:
1960 {
1961 int table[3] = {2, 0, 1};
1962 *pCycle = table[sel];
1963 }
1964 break;
1965 case SQ_ALU_VEC_210:
1966 {
1967 int table[3] = {2, 1, 0};
1968 *pCycle = table[sel];
1969 }
1970 break;
1971 default:
1972 radeon_error("Bad Vec bank swizzle value\n");
1973 return GL_FALSE;
1974 break;
1975 }
1976
1977 return GL_TRUE;
1978 }
1979
1980 GLboolean check_scalar(r700_AssemblerBase* pAsm,
1981 R700ALUInstruction* alu_instruction_ptr)
1982 {
1983 GLuint cycle;
1984 GLuint bank_swizzle;
1985 GLuint const_count = 0;
1986
1987 BITS sel;
1988 BITS chan;
1989 BITS rel;
1990 BITS neg;
1991
1992 GLuint src;
1993
1994 BITS src_sel [3] = {0,0,0};
1995 BITS src_chan[3] = {0,0,0};
1996 BITS src_rel [3] = {0,0,0};
1997 BITS src_neg [3] = {0,0,0};
1998
1999 GLuint swizzle_key;
2000
2001 GLuint number_of_operands = r700GetNumOperands(pAsm);
2002
2003 for (src=0; src<number_of_operands; src++)
2004 {
2005 get_src_properties(alu_instruction_ptr,
2006 src,
2007 &(src_sel[src]),
2008 &(src_rel[src]),
2009 &(src_chan[src]),
2010 &(src_neg[src]) );
2011 }
2012
2013
2014 swizzle_key = ( (is_const( src_sel[0] ) ? 4 : 0) +
2015 (is_const( src_sel[1] ) ? 2 : 0) +
2016 (is_const( src_sel[2] ) ? 1 : 0) );
2017
2018 alu_instruction_ptr->m_Word1.f.bank_swizzle = BANK_SWIZZLE_SCL[ swizzle_key ];
2019
2020 for (src=0; src<number_of_operands; src++)
2021 {
2022 sel = src_sel [src];
2023 chan = src_chan[src];
2024 rel = src_rel [src];
2025 neg = src_neg [src];
2026
2027 if (is_const( sel ))
2028 {
2029 // Any constant, including literal and inline constants
2030 const_count++;
2031
2032 if (is_cfile( sel ))
2033 {
2034 reserve_cfile(pAsm, sel, chan);
2035 }
2036
2037 }
2038 }
2039
2040 for (src=0; src<number_of_operands; src++)
2041 {
2042 sel = src_sel [src];
2043 chan = src_chan[src];
2044 rel = src_rel [src];
2045 neg = src_neg [src];
2046
2047 if( is_gpr(sel) )
2048 {
2049 bank_swizzle = alu_instruction_ptr->m_Word1.f.bank_swizzle;
2050
2051 if( GL_FALSE == cycle_for_scalar_bank_swizzle(bank_swizzle, src, &cycle) )
2052 {
2053 return GL_FALSE;
2054 }
2055
2056 if(cycle < const_count)
2057 {
2058 if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) )
2059 {
2060 return GL_FALSE;
2061 }
2062 }
2063 }
2064 }
2065
2066 return GL_TRUE;
2067 }
2068
2069 GLboolean check_vector(r700_AssemblerBase* pAsm,
2070 R700ALUInstruction* alu_instruction_ptr)
2071 {
2072 GLuint cycle;
2073 GLuint bank_swizzle;
2074 GLuint const_count = 0;
2075
2076 GLuint src;
2077
2078 BITS sel;
2079 BITS chan;
2080 BITS rel;
2081 BITS neg;
2082
2083 BITS src_sel [3] = {0,0,0};
2084 BITS src_chan[3] = {0,0,0};
2085 BITS src_rel [3] = {0,0,0};
2086 BITS src_neg [3] = {0,0,0};
2087
2088 GLuint swizzle_key;
2089
2090 GLuint number_of_operands = r700GetNumOperands(pAsm);
2091
2092 for (src=0; src<number_of_operands; src++)
2093 {
2094 get_src_properties(alu_instruction_ptr,
2095 src,
2096 &(src_sel[src]),
2097 &(src_rel[src]),
2098 &(src_chan[src]),
2099 &(src_neg[src]) );
2100 }
2101
2102
2103 swizzle_key = ( (is_const( src_sel[0] ) ? 4 : 0) +
2104 (is_const( src_sel[1] ) ? 2 : 0) +
2105 (is_const( src_sel[2] ) ? 1 : 0)
2106 );
2107
2108 alu_instruction_ptr->m_Word1.f.bank_swizzle = BANK_SWIZZLE_VEC[swizzle_key];
2109
2110 for (src=0; src<number_of_operands; src++)
2111 {
2112 sel = src_sel [src];
2113 chan = src_chan[src];
2114 rel = src_rel [src];
2115 neg = src_neg [src];
2116
2117
2118 bank_swizzle = alu_instruction_ptr->m_Word1.f.bank_swizzle;
2119
2120 if( is_gpr(sel) )
2121 {
2122 if( GL_FALSE == cycle_for_vector_bank_swizzle(bank_swizzle, src, &cycle) )
2123 {
2124 return GL_FALSE;
2125 }
2126
2127 if ( (src == 1) &&
2128 (sel == src_sel[0]) &&
2129 (chan == src_chan[0]) )
2130 {
2131 }
2132 else
2133 {
2134 if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) )
2135 {
2136 return GL_FALSE;
2137 }
2138 }
2139 }
2140 else if( is_const(sel) )
2141 {
2142 const_count++;
2143
2144 if( is_cfile(sel) )
2145 {
2146 if( GL_FALSE == reserve_cfile(pAsm, sel, chan) )
2147 {
2148 return GL_FALSE;
2149 }
2150 }
2151 }
2152 }
2153
2154 return GL_TRUE;
2155 }
2156
2157 GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
2158 {
2159 GLuint number_of_scalar_operations;
2160 GLboolean is_single_scalar_operation;
2161 GLuint scalar_channel_index;
2162
2163 PVSSRC * pcurrent_source;
2164 int current_source_index;
2165 GLuint contiguous_slots_needed;
2166
2167 GLuint uNumSrc = r700GetNumOperands(pAsm);
2168 //GLuint channel_swizzle, j;
2169 //GLuint chan_counter[4] = {0, 0, 0, 0};
2170 //PVSSRC * pSource[3];
2171 GLboolean bSplitInst = GL_FALSE;
2172
2173 if (1 == pAsm->D.dst.math)
2174 {
2175 is_single_scalar_operation = GL_TRUE;
2176 number_of_scalar_operations = 1;
2177 }
2178 else
2179 {
2180 is_single_scalar_operation = GL_FALSE;
2181 number_of_scalar_operations = 4;
2182
2183 /* current assembler doesn't do more than 1 register per source */
2184 #if 0
2185 /* check read port, only very preliminary algorithm, not count in
2186 src0/1 same comp case and prev slot repeat case; also not count relative
2187 addressing. TODO: improve performance. */
2188 for(j=0; j<uNumSrc; j++)
2189 {
2190 pSource[j] = &(pAsm->S[j].src);
2191 }
2192 for(scalar_channel_index=0; scalar_channel_index<4; scalar_channel_index++)
2193 {
2194 for(j=0; j<uNumSrc; j++)
2195 {
2196 switch (scalar_channel_index)
2197 {
2198 case 0: channel_swizzle = pSource[j]->swizzlex; break;
2199 case 1: channel_swizzle = pSource[j]->swizzley; break;
2200 case 2: channel_swizzle = pSource[j]->swizzlez; break;
2201 case 3: channel_swizzle = pSource[j]->swizzlew; break;
2202 default: channel_swizzle = SQ_SEL_MASK; break;
2203 }
2204 if ( ((pSource[j]->rtype == SRC_REG_TEMPORARY) ||
2205 (pSource[j]->rtype == SRC_REG_INPUT))
2206 && (channel_swizzle <= SQ_SEL_W) )
2207 {
2208 chan_counter[channel_swizzle]++;
2209 }
2210 }
2211 }
2212 if( (chan_counter[SQ_SEL_X] > 3)
2213 || (chan_counter[SQ_SEL_Y] > 3)
2214 || (chan_counter[SQ_SEL_Z] > 3)
2215 || (chan_counter[SQ_SEL_W] > 3) ) /* each chan bank has only 3 ports. */
2216 {
2217 bSplitInst = GL_TRUE;
2218 }
2219 #endif
2220 }
2221
2222 contiguous_slots_needed = 0;
2223
2224 if(GL_TRUE == is_reduction_opcode(&(pAsm->D)) )
2225 {
2226 contiguous_slots_needed = 4;
2227 }
2228
2229 initialize(pAsm);
2230
2231 for (scalar_channel_index=0;
2232 scalar_channel_index < number_of_scalar_operations;
2233 scalar_channel_index++)
2234 {
2235 R700ALUInstruction* alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
2236 if (alu_instruction_ptr == NULL)
2237 {
2238 return GL_FALSE;
2239 }
2240 Init_R700ALUInstruction(alu_instruction_ptr);
2241
2242 //src 0
2243 current_source_index = 0;
2244 pcurrent_source = &(pAsm->S[0].src);
2245
2246 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2247 current_source_index,
2248 pcurrent_source,
2249 scalar_channel_index) )
2250 {
2251 return GL_FALSE;
2252 }
2253
2254 if (uNumSrc > 1)
2255 {
2256 // Process source 1
2257 current_source_index = 1;
2258 pcurrent_source = &(pAsm->S[current_source_index].src);
2259
2260 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2261 current_source_index,
2262 pcurrent_source,
2263 scalar_channel_index) )
2264 {
2265 return GL_FALSE;
2266 }
2267 }
2268
2269 //other bits
2270 alu_instruction_ptr->m_Word0.f.index_mode = SQ_INDEX_AR_X;
2271
2272 if( (is_single_scalar_operation == GL_TRUE)
2273 || (GL_TRUE == bSplitInst) )
2274 {
2275 alu_instruction_ptr->m_Word0.f.last = 1;
2276 }
2277 else
2278 {
2279 alu_instruction_ptr->m_Word0.f.last = (scalar_channel_index == 3) ? 1 : 0;
2280 }
2281
2282 alu_instruction_ptr->m_Word0.f.pred_sel = 0x0;
2283 alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x0;
2284 alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
2285
2286 // dst
2287 if( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) ||
2288 (pAsm->D.dst.rtype == DST_REG_OUT) )
2289 {
2290 alu_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg;
2291 }
2292 else
2293 {
2294 radeon_error("Only temp destination registers supported for ALU dest regs.\n");
2295 return GL_FALSE;
2296 }
2297
2298 alu_instruction_ptr->m_Word1.f.dst_rel = SQ_ABSOLUTE; //D.rtype
2299
2300 if ( is_single_scalar_operation == GL_TRUE )
2301 {
2302 // Override scalar_channel_index since only one scalar value will be written
2303 if(pAsm->D.dst.writex)
2304 {
2305 scalar_channel_index = 0;
2306 }
2307 else if(pAsm->D.dst.writey)
2308 {
2309 scalar_channel_index = 1;
2310 }
2311 else if(pAsm->D.dst.writez)
2312 {
2313 scalar_channel_index = 2;
2314 }
2315 else if(pAsm->D.dst.writew)
2316 {
2317 scalar_channel_index = 3;
2318 }
2319 }
2320
2321 alu_instruction_ptr->m_Word1.f.dst_chan = scalar_channel_index;
2322
2323 alu_instruction_ptr->m_Word1.f.clamp = pAsm->pILInst[pAsm->uiCurInst].SaturateMode;
2324
2325 if (pAsm->D.dst.op3)
2326 {
2327 //op3
2328
2329 alu_instruction_ptr->m_Word1_OP3.f.alu_inst = pAsm->D.dst.opcode;
2330
2331 //There's 3rd src for op3
2332 current_source_index = 2;
2333 pcurrent_source = &(pAsm->S[current_source_index].src);
2334
2335 if ( GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2336 current_source_index,
2337 pcurrent_source,
2338 scalar_channel_index) )
2339 {
2340 return GL_FALSE;
2341 }
2342 }
2343 else
2344 {
2345 //op2
2346 if (pAsm->bR6xx)
2347 {
2348 alu_instruction_ptr->m_Word1_OP2.f6.alu_inst = pAsm->D.dst.opcode;
2349
2350 alu_instruction_ptr->m_Word1_OP2.f6.src0_abs = 0x0;
2351 alu_instruction_ptr->m_Word1_OP2.f6.src1_abs = 0x0;
2352
2353 //alu_instruction_ptr->m_Word1_OP2.f6.update_execute_mask = 0x0;
2354 //alu_instruction_ptr->m_Word1_OP2.f6.update_pred = 0x0;
2355 switch (scalar_channel_index)
2356 {
2357 case 0:
2358 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writex;
2359 break;
2360 case 1:
2361 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writey;
2362 break;
2363 case 2:
2364 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writez;
2365 break;
2366 case 3:
2367 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writew;
2368 break;
2369 default:
2370 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = 1; //SQ_SEL_MASK;
2371 break;
2372 }
2373 alu_instruction_ptr->m_Word1_OP2.f6.omod = SQ_ALU_OMOD_OFF;
2374 }
2375 else
2376 {
2377 alu_instruction_ptr->m_Word1_OP2.f.alu_inst = pAsm->D.dst.opcode;
2378
2379 alu_instruction_ptr->m_Word1_OP2.f.src0_abs = 0x0;
2380 alu_instruction_ptr->m_Word1_OP2.f.src1_abs = 0x0;
2381
2382 //alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
2383 //alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x0;
2384 switch (scalar_channel_index)
2385 {
2386 case 0:
2387 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writex;
2388 break;
2389 case 1:
2390 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writey;
2391 break;
2392 case 2:
2393 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writez;
2394 break;
2395 case 3:
2396 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writew;
2397 break;
2398 default:
2399 alu_instruction_ptr->m_Word1_OP2.f.write_mask = 1; //SQ_SEL_MASK;
2400 break;
2401 }
2402 alu_instruction_ptr->m_Word1_OP2.f.omod = SQ_ALU_OMOD_OFF;
2403 }
2404 }
2405
2406 if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) )
2407 {
2408 return GL_FALSE;
2409 }
2410
2411 /*
2412 * Judge the type of current instruction, is it vector or scalar
2413 * instruction.
2414 */
2415 if (is_single_scalar_operation)
2416 {
2417 if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) )
2418 {
2419 return GL_FALSE;
2420 }
2421 }
2422 else
2423 {
2424 if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) )
2425 {
2426 return 1;
2427 }
2428 }
2429
2430 contiguous_slots_needed = 0;
2431 }
2432
2433 return GL_TRUE;
2434 }
2435
2436 GLboolean assemble_alu_instruction2(r700_AssemblerBase *pAsm)
2437 {
2438 GLuint number_of_scalar_operations;
2439 GLboolean is_single_scalar_operation;
2440 GLuint scalar_channel_index;
2441
2442 PVSSRC * pcurrent_source;
2443 int current_source_index;
2444 GLuint contiguous_slots_needed;
2445
2446 GLuint uNumSrc = r700GetNumOperands(pAsm);
2447
2448 GLboolean bSplitInst = GL_FALSE;
2449
2450 if (1 == pAsm->D.dst.math)
2451 {
2452 is_single_scalar_operation = GL_TRUE;
2453 number_of_scalar_operations = 1;
2454 }
2455 else
2456 {
2457 is_single_scalar_operation = GL_FALSE;
2458 number_of_scalar_operations = 4;
2459 }
2460
2461 contiguous_slots_needed = 0;
2462
2463 if(GL_TRUE == is_reduction_opcode(&(pAsm->D)) )
2464 {
2465 contiguous_slots_needed = 4;
2466 }
2467
2468 initialize(pAsm);
2469
2470 for (scalar_channel_index=0;
2471 scalar_channel_index < number_of_scalar_operations;
2472 scalar_channel_index++)
2473 {
2474 R700ALUInstruction* alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
2475 if (alu_instruction_ptr == NULL)
2476 {
2477 return GL_FALSE;
2478 }
2479 Init_R700ALUInstruction(alu_instruction_ptr);
2480
2481 //src 0
2482 current_source_index = 0;
2483 pcurrent_source = &(pAsm->S[0].src);
2484
2485 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2486 current_source_index,
2487 pcurrent_source,
2488 scalar_channel_index) )
2489 {
2490 return GL_FALSE;
2491 }
2492
2493 if (uNumSrc > 1)
2494 {
2495 // Process source 1
2496 current_source_index = 1;
2497 pcurrent_source = &(pAsm->S[current_source_index].src);
2498
2499 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2500 current_source_index,
2501 pcurrent_source,
2502 scalar_channel_index) )
2503 {
2504 return GL_FALSE;
2505 }
2506 }
2507
2508 //other bits
2509 alu_instruction_ptr->m_Word0.f.index_mode = SQ_INDEX_LOOP;
2510
2511 if( (is_single_scalar_operation == GL_TRUE)
2512 || (GL_TRUE == bSplitInst) )
2513 {
2514 alu_instruction_ptr->m_Word0.f.last = 1;
2515 }
2516 else
2517 {
2518 alu_instruction_ptr->m_Word0.f.last = (scalar_channel_index == 3) ? 1 : 0;
2519 }
2520
2521 alu_instruction_ptr->m_Word0.f.pred_sel = (pAsm->D.dst.pred_inv > 0) ? 1 : 0;
2522 if(1 == pAsm->D.dst.predicated)
2523 {
2524 alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x1;
2525 alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x1;
2526 }
2527 else
2528 {
2529 alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x0;
2530 alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
2531 }
2532
2533 // dst
2534 if( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) ||
2535 (pAsm->D.dst.rtype == DST_REG_OUT) )
2536 {
2537 alu_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg;
2538 }
2539 else
2540 {
2541 radeon_error("Only temp destination registers supported for ALU dest regs.\n");
2542 return GL_FALSE;
2543 }
2544
2545 alu_instruction_ptr->m_Word1.f.dst_rel = SQ_ABSOLUTE; //D.rtype
2546
2547 if ( is_single_scalar_operation == GL_TRUE )
2548 {
2549 // Override scalar_channel_index since only one scalar value will be written
2550 if(pAsm->D.dst.writex)
2551 {
2552 scalar_channel_index = 0;
2553 }
2554 else if(pAsm->D.dst.writey)
2555 {
2556 scalar_channel_index = 1;
2557 }
2558 else if(pAsm->D.dst.writez)
2559 {
2560 scalar_channel_index = 2;
2561 }
2562 else if(pAsm->D.dst.writew)
2563 {
2564 scalar_channel_index = 3;
2565 }
2566 }
2567
2568 alu_instruction_ptr->m_Word1.f.dst_chan = scalar_channel_index;
2569
2570 alu_instruction_ptr->m_Word1.f.clamp = pAsm->D2.dst2.SaturateMode;
2571
2572 if (pAsm->D.dst.op3)
2573 {
2574 //op3
2575
2576 alu_instruction_ptr->m_Word1_OP3.f.alu_inst = pAsm->D.dst.opcode;
2577
2578 //There's 3rd src for op3
2579 current_source_index = 2;
2580 pcurrent_source = &(pAsm->S[current_source_index].src);
2581
2582 if ( GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2583 current_source_index,
2584 pcurrent_source,
2585 scalar_channel_index) )
2586 {
2587 return GL_FALSE;
2588 }
2589 }
2590 else
2591 {
2592 //op2
2593 if (pAsm->bR6xx)
2594 {
2595 alu_instruction_ptr->m_Word1_OP2.f6.alu_inst = pAsm->D.dst.opcode;
2596
2597 alu_instruction_ptr->m_Word1_OP2.f6.src0_abs = 0x0;
2598 alu_instruction_ptr->m_Word1_OP2.f6.src1_abs = 0x0;
2599
2600 //alu_instruction_ptr->m_Word1_OP2.f6.update_execute_mask = 0x0;
2601 //alu_instruction_ptr->m_Word1_OP2.f6.update_pred = 0x0;
2602 switch (scalar_channel_index)
2603 {
2604 case 0:
2605 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writex;
2606 break;
2607 case 1:
2608 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writey;
2609 break;
2610 case 2:
2611 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writez;
2612 break;
2613 case 3:
2614 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writew;
2615 break;
2616 default:
2617 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = 1; //SQ_SEL_MASK;
2618 break;
2619 }
2620 alu_instruction_ptr->m_Word1_OP2.f6.omod = SQ_ALU_OMOD_OFF;
2621 }
2622 else
2623 {
2624 alu_instruction_ptr->m_Word1_OP2.f.alu_inst = pAsm->D.dst.opcode;
2625
2626 alu_instruction_ptr->m_Word1_OP2.f.src0_abs = 0x0;
2627 alu_instruction_ptr->m_Word1_OP2.f.src1_abs = 0x0;
2628
2629 //alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
2630 //alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x0;
2631 switch (scalar_channel_index)
2632 {
2633 case 0:
2634 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writex;
2635 break;
2636 case 1:
2637 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writey;
2638 break;
2639 case 2:
2640 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writez;
2641 break;
2642 case 3:
2643 alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writew;
2644 break;
2645 default:
2646 alu_instruction_ptr->m_Word1_OP2.f.write_mask = 1; //SQ_SEL_MASK;
2647 break;
2648 }
2649 alu_instruction_ptr->m_Word1_OP2.f.omod = SQ_ALU_OMOD_OFF;
2650 }
2651 }
2652
2653 if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) )
2654 {
2655 return GL_FALSE;
2656 }
2657
2658 /*
2659 * Judge the type of current instruction, is it vector or scalar
2660 * instruction.
2661 */
2662 if (is_single_scalar_operation)
2663 {
2664 if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) )
2665 {
2666 return GL_FALSE;
2667 }
2668 }
2669 else
2670 {
2671 if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) )
2672 {
2673 return 1;
2674 }
2675 }
2676
2677 contiguous_slots_needed = 0;
2678 }
2679
2680 return GL_TRUE;
2681 }
2682
2683 GLboolean assemble_alu_instruction_literal(r700_AssemblerBase *pAsm, GLfloat * pLiteral)
2684 {
2685 R700ALUInstruction * alu_instruction_ptr;
2686 R700ALUInstructionHalfLiteral * alu_instruction_ptr_hl;
2687 R700ALUInstructionFullLiteral * alu_instruction_ptr_fl;
2688
2689 GLuint number_of_scalar_operations;
2690 GLboolean is_single_scalar_operation;
2691 GLuint scalar_channel_index;
2692
2693 GLuint contiguous_slots_needed;
2694 GLuint lastInstruction;
2695 GLuint not_masked[4];
2696
2697 GLuint uNumSrc = r700GetNumOperands(pAsm);
2698
2699 GLboolean bSplitInst = GL_FALSE;
2700
2701 number_of_scalar_operations = 0;
2702 contiguous_slots_needed = 0;
2703
2704 if(1 == pAsm->D.dst.writew)
2705 {
2706 lastInstruction = 3;
2707 number_of_scalar_operations++;
2708 not_masked[3] = 1;
2709 }
2710 else
2711 {
2712 not_masked[3] = 0;
2713 }
2714 if(1 == pAsm->D.dst.writez)
2715 {
2716 lastInstruction = 2;
2717 number_of_scalar_operations++;
2718 not_masked[2] = 1;
2719 }
2720 else
2721 {
2722 not_masked[2] = 0;
2723 }
2724 if(1 == pAsm->D.dst.writey)
2725 {
2726 lastInstruction = 1;
2727 number_of_scalar_operations++;
2728 not_masked[1] = 1;
2729 }
2730 else
2731 {
2732 not_masked[1] = 0;
2733 }
2734 if(1 == pAsm->D.dst.writex)
2735 {
2736 lastInstruction = 0;
2737 number_of_scalar_operations++;
2738 not_masked[0] = 1;
2739 }
2740 else
2741 {
2742 not_masked[0] = 0;
2743 }
2744
2745 if(GL_TRUE == is_reduction_opcode(&(pAsm->D)) )
2746 {
2747 contiguous_slots_needed = 4;
2748 }
2749 else
2750 {
2751 contiguous_slots_needed = number_of_scalar_operations;
2752 }
2753
2754 if(1 == pAsm->D2.dst2.literal)
2755 {
2756 contiguous_slots_needed += 1;
2757 }
2758 else if(2 == pAsm->D2.dst2.literal)
2759 {
2760 contiguous_slots_needed += 2;
2761 }
2762
2763 initialize(pAsm);
2764
2765 for (scalar_channel_index=0; scalar_channel_index < 4; scalar_channel_index++)
2766 {
2767 if(0 == not_masked[scalar_channel_index])
2768 {
2769 continue;
2770 }
2771
2772 if(scalar_channel_index == lastInstruction)
2773 {
2774 switch (pAsm->D2.dst2.literal)
2775 {
2776 case 0:
2777 alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
2778 if (alu_instruction_ptr == NULL)
2779 {
2780 return GL_FALSE;
2781 }
2782 Init_R700ALUInstruction(alu_instruction_ptr);
2783 break;
2784 case 1:
2785 alu_instruction_ptr_hl = (R700ALUInstructionHalfLiteral*) CALLOC_STRUCT(R700ALUInstructionHalfLiteral);
2786 if (alu_instruction_ptr_hl == NULL)
2787 {
2788 return GL_FALSE;
2789 }
2790 Init_R700ALUInstructionHalfLiteral(alu_instruction_ptr_hl, pLiteral[0], pLiteral[1]);
2791 alu_instruction_ptr = (R700ALUInstruction*)alu_instruction_ptr_hl;
2792 break;
2793 case 2:
2794 alu_instruction_ptr_fl = (R700ALUInstructionFullLiteral*) CALLOC_STRUCT(R700ALUInstructionFullLiteral);
2795 if (alu_instruction_ptr_fl == NULL)
2796 {
2797 return GL_FALSE;
2798 }
2799 Init_R700ALUInstructionFullLiteral(alu_instruction_ptr_fl, pLiteral[0], pLiteral[1], pLiteral[2], pLiteral[3]);
2800 alu_instruction_ptr = (R700ALUInstruction*)alu_instruction_ptr_fl;
2801 break;
2802 default:
2803 break;
2804 };
2805 }
2806 else
2807 {
2808 alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
2809 if (alu_instruction_ptr == NULL)
2810 {
2811 return GL_FALSE;
2812 }
2813 Init_R700ALUInstruction(alu_instruction_ptr);
2814 }
2815
2816 //src 0
2817 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2818 0,
2819 &(pAsm->S[0].src),
2820 scalar_channel_index) )
2821 {
2822 return GL_FALSE;
2823 }
2824
2825 if (uNumSrc > 1)
2826 {
2827 // Process source 1
2828 if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2829 1,
2830 &(pAsm->S[1].src),
2831 scalar_channel_index) )
2832 {
2833 return GL_FALSE;
2834 }
2835 }
2836
2837 //other bits
2838 alu_instruction_ptr->m_Word0.f.index_mode = SQ_INDEX_LOOP;
2839
2840 if(scalar_channel_index == lastInstruction)
2841 {
2842 alu_instruction_ptr->m_Word0.f.last = 1;
2843 }
2844
2845 alu_instruction_ptr->m_Word0.f.pred_sel = 0x0;
2846 if(1 == pAsm->D.dst.predicated)
2847 {
2848 alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0x1;
2849 alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x1;
2850 }
2851 else
2852 {
2853 alu_instruction_ptr->m_Word1_OP2.f.update_pred = 0;
2854 alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0;
2855 }
2856
2857 // dst
2858 if( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) ||
2859 (pAsm->D.dst.rtype == DST_REG_OUT) )
2860 {
2861 alu_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg;
2862 }
2863 else
2864 {
2865 radeon_error("Only temp destination registers supported for ALU dest regs.\n");
2866 return GL_FALSE;
2867 }
2868
2869 alu_instruction_ptr->m_Word1.f.dst_rel = SQ_ABSOLUTE; //D.rtype
2870
2871 alu_instruction_ptr->m_Word1.f.dst_chan = scalar_channel_index;
2872
2873 alu_instruction_ptr->m_Word1.f.clamp = pAsm->D2.dst2.SaturateMode;
2874
2875 if (pAsm->D.dst.op3)
2876 {
2877 //op3
2878 alu_instruction_ptr->m_Word1_OP3.f.alu_inst = pAsm->D.dst.opcode;
2879
2880 //There's 3rd src for op3
2881 if ( GL_FALSE == assemble_alu_src(alu_instruction_ptr,
2882 2,
2883 &(pAsm->S[2].src),
2884 scalar_channel_index) )
2885 {
2886 return GL_FALSE;
2887 }
2888 }
2889 else
2890 {
2891 //op2
2892 if (pAsm->bR6xx)
2893 {
2894 alu_instruction_ptr->m_Word1_OP2.f6.alu_inst = pAsm->D.dst.opcode;
2895 alu_instruction_ptr->m_Word1_OP2.f6.src0_abs = 0x0;
2896 alu_instruction_ptr->m_Word1_OP2.f6.src1_abs = 0x0;
2897 alu_instruction_ptr->m_Word1_OP2.f6.write_mask = 1;
2898 alu_instruction_ptr->m_Word1_OP2.f6.omod = SQ_ALU_OMOD_OFF;
2899 }
2900 else
2901 {
2902 alu_instruction_ptr->m_Word1_OP2.f.alu_inst = pAsm->D.dst.opcode;
2903 alu_instruction_ptr->m_Word1_OP2.f.src0_abs = 0x0;
2904 alu_instruction_ptr->m_Word1_OP2.f.src1_abs = 0x0;
2905 alu_instruction_ptr->m_Word1_OP2.f.write_mask = 1;
2906 alu_instruction_ptr->m_Word1_OP2.f.omod = SQ_ALU_OMOD_OFF;
2907 }
2908 }
2909
2910 if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) )
2911 {
2912 return GL_FALSE;
2913 }
2914
2915 if (1 == number_of_scalar_operations)
2916 {
2917 if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) )
2918 {
2919 return GL_FALSE;
2920 }
2921 }
2922 else
2923 {
2924 if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) )
2925 {
2926 return GL_FALSE;
2927 }
2928 }
2929
2930 contiguous_slots_needed -= 2;
2931 }
2932
2933 return GL_TRUE;
2934 }
2935
2936 GLboolean next_ins(r700_AssemblerBase *pAsm)
2937 {
2938 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
2939
2940 if( GL_TRUE == pAsm->is_tex )
2941 {
2942 if (pILInst->TexSrcTarget == TEXTURE_RECT_INDEX) {
2943 if( GL_FALSE == assemble_tex_instruction(pAsm, GL_FALSE) )
2944 {
2945 radeon_error("Error assembling TEX instruction\n");
2946 return GL_FALSE;
2947 }
2948 } else {
2949 if( GL_FALSE == assemble_tex_instruction(pAsm, GL_TRUE) )
2950 {
2951 radeon_error("Error assembling TEX instruction\n");
2952 return GL_FALSE;
2953 }
2954 }
2955 }
2956 else
2957 { //ALU
2958 if( GL_FALSE == assemble_alu_instruction(pAsm) )
2959 {
2960 radeon_error("Error assembling ALU instruction\n");
2961 return GL_FALSE;
2962 }
2963 }
2964
2965 if(pAsm->D.dst.rtype == DST_REG_OUT)
2966 {
2967 if(pAsm->D.dst.op3)
2968 {
2969 // There is no mask for OP3 instructions, so all channels are written
2970 pAsm->pucOutMask[pAsm->D.dst.reg - pAsm->starting_export_register_number] = 0xF;
2971 }
2972 else
2973 {
2974 pAsm->pucOutMask[pAsm->D.dst.reg - pAsm->starting_export_register_number]
2975 |= (unsigned char)pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask;
2976 }
2977 }
2978
2979 //reset for next inst.
2980 pAsm->D.bits = 0;
2981 pAsm->D2.bits = 0;
2982 pAsm->S[0].bits = 0;
2983 pAsm->S[1].bits = 0;
2984 pAsm->S[2].bits = 0;
2985 pAsm->is_tex = GL_FALSE;
2986 pAsm->need_tex_barrier = GL_FALSE;
2987
2988 return GL_TRUE;
2989 }
2990
2991 GLboolean next_ins2(r700_AssemblerBase *pAsm)
2992 {
2993 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
2994
2995 //ALU
2996 if( GL_FALSE == assemble_alu_instruction2(pAsm) )
2997 {
2998 radeon_error("Error assembling ALU instruction\n");
2999 return GL_FALSE;
3000 }
3001
3002 if(pAsm->D.dst.rtype == DST_REG_OUT)
3003 {
3004 if(pAsm->D.dst.op3)
3005 {
3006 // There is no mask for OP3 instructions, so all channels are written
3007 pAsm->pucOutMask[pAsm->D.dst.reg - pAsm->starting_export_register_number] = 0xF;
3008 }
3009 else
3010 {
3011 pAsm->pucOutMask[pAsm->D.dst.reg - pAsm->starting_export_register_number]
3012 |= (unsigned char)pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask;
3013 }
3014 }
3015
3016 //reset for next inst.
3017 pAsm->D.bits = 0;
3018 pAsm->D2.bits = 0;
3019 pAsm->S[0].bits = 0;
3020 pAsm->S[1].bits = 0;
3021 pAsm->S[2].bits = 0;
3022 pAsm->is_tex = GL_FALSE;
3023 pAsm->need_tex_barrier = GL_FALSE;
3024
3025 //richard nov.16 glsl
3026 pAsm->D2.bits = 0;
3027
3028 return GL_TRUE;
3029 }
3030
3031 /* not work yet */
3032 GLboolean next_ins_literal(r700_AssemblerBase *pAsm, GLfloat * pLiteral)
3033 {
3034 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
3035
3036 //ALU
3037 if( GL_FALSE == assemble_alu_instruction_literal(pAsm, pLiteral) )
3038 {
3039 radeon_error("Error assembling ALU instruction\n");
3040 return GL_FALSE;
3041 }
3042
3043 //reset for next inst.
3044 pAsm->D.bits = 0;
3045 pAsm->D2.bits = 0;
3046 pAsm->S[0].bits = 0;
3047 pAsm->S[1].bits = 0;
3048 pAsm->S[2].bits = 0;
3049 pAsm->is_tex = GL_FALSE;
3050 pAsm->need_tex_barrier = GL_FALSE;
3051 return GL_TRUE;
3052 }
3053
3054 GLboolean assemble_math_function(r700_AssemblerBase* pAsm, BITS opcode)
3055 {
3056 BITS tmp;
3057
3058 checkop1(pAsm);
3059
3060 tmp = gethelpr(pAsm);
3061
3062 // opcode tmp.x, a.x
3063 // MOV dst, tmp.x
3064
3065 pAsm->D.dst.opcode = opcode;
3066 pAsm->D.dst.math = 1;
3067
3068 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3069 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3070 pAsm->D.dst.reg = tmp;
3071 pAsm->D.dst.writex = 1;
3072
3073 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3074 {
3075 return GL_FALSE;
3076 }
3077
3078 if ( GL_FALSE == next_ins(pAsm) )
3079 {
3080 return GL_FALSE;
3081 }
3082
3083 // Now replicate result to all necessary channels in destination
3084 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3085
3086 if( GL_FALSE == assemble_dst(pAsm) )
3087 {
3088 return GL_FALSE;
3089 }
3090
3091 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3092 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3093 pAsm->S[0].src.reg = tmp;
3094
3095 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3096 noneg_PVSSRC(&(pAsm->S[0].src));
3097
3098 if( GL_FALSE == next_ins(pAsm) )
3099 {
3100 return GL_FALSE;
3101 }
3102
3103 return GL_TRUE;
3104 }
3105
3106 GLboolean assemble_ABS(r700_AssemblerBase *pAsm)
3107 {
3108 checkop1(pAsm);
3109
3110 pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
3111
3112 if( GL_FALSE == assemble_dst(pAsm) )
3113 {
3114 return GL_FALSE;
3115 }
3116 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3117 {
3118 return GL_FALSE;
3119 }
3120
3121 pAsm->S[1].bits = pAsm->S[0].bits;
3122 flipneg_PVSSRC(&(pAsm->S[1].src));
3123
3124 if ( GL_FALSE == next_ins(pAsm) )
3125 {
3126 return GL_FALSE;
3127 }
3128
3129 return GL_TRUE;
3130 }
3131
3132 GLboolean assemble_ADD(r700_AssemblerBase *pAsm)
3133 {
3134 if( GL_FALSE == checkop2(pAsm) )
3135 {
3136 return GL_FALSE;
3137 }
3138
3139 pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
3140
3141 if( GL_FALSE == assemble_dst(pAsm) )
3142 {
3143 return GL_FALSE;
3144 }
3145
3146 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3147 {
3148 return GL_FALSE;
3149 }
3150
3151 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
3152 {
3153 return GL_FALSE;
3154 }
3155
3156 if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_SUB)
3157 {
3158 flipneg_PVSSRC(&(pAsm->S[1].src));
3159 }
3160
3161 if( GL_FALSE == next_ins(pAsm) )
3162 {
3163 return GL_FALSE;
3164 }
3165
3166 return GL_TRUE;
3167 }
3168
3169 GLboolean assemble_ARL(r700_AssemblerBase *pAsm)
3170 { /* TODO: ar values dont' persist between clauses */
3171 if( GL_FALSE == checkop1(pAsm) )
3172 {
3173 return GL_FALSE;
3174 }
3175
3176 pAsm->D.dst.opcode = SQ_OP2_INST_MOVA_FLOOR;
3177 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3178 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3179 pAsm->D.dst.reg = 0;
3180 pAsm->D.dst.writex = 0;
3181 pAsm->D.dst.writey = 0;
3182 pAsm->D.dst.writez = 0;
3183 pAsm->D.dst.writew = 0;
3184
3185 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3186 {
3187 return GL_FALSE;
3188 }
3189
3190 if( GL_FALSE == next_ins(pAsm) )
3191 {
3192 return GL_FALSE;
3193 }
3194
3195 return GL_TRUE;
3196 }
3197
3198 GLboolean assemble_BAD(char *opcode_str)
3199 {
3200 radeon_error("Not yet implemented instruction (%s)\n", opcode_str);
3201 return GL_FALSE;
3202 }
3203
3204 GLboolean assemble_CMP(r700_AssemblerBase *pAsm)
3205 {
3206 int tmp;
3207
3208 if( GL_FALSE == checkop3(pAsm) )
3209 {
3210 return GL_FALSE;
3211 }
3212
3213 pAsm->D.dst.opcode = SQ_OP3_INST_CNDGE;
3214 pAsm->D.dst.op3 = 1;
3215
3216 tmp = (-1);
3217
3218 if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask)
3219 {
3220 //OP3 has no support for write mask
3221 tmp = gethelpr(pAsm);
3222
3223 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3224 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3225 pAsm->D.dst.reg = tmp;
3226
3227 nomask_PVSDST(&(pAsm->D.dst));
3228 }
3229 else
3230 {
3231 if( GL_FALSE == assemble_dst(pAsm) )
3232 {
3233 return GL_FALSE;
3234 }
3235 }
3236
3237 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3238 {
3239 return GL_FALSE;
3240 }
3241
3242 if( GL_FALSE == assemble_src(pAsm, 2, 1) )
3243 {
3244 return GL_FALSE;
3245 }
3246
3247 if( GL_FALSE == assemble_src(pAsm, 1, 2) )
3248 {
3249 return GL_FALSE;
3250 }
3251
3252 if ( GL_FALSE == next_ins(pAsm) )
3253 {
3254 return GL_FALSE;
3255 }
3256
3257 if (0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask)
3258 {
3259 if( GL_FALSE == assemble_dst(pAsm) )
3260 {
3261 return GL_FALSE;
3262 }
3263
3264 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3265
3266 //tmp for source
3267 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3268 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3269 pAsm->S[0].src.reg = tmp;
3270
3271 noneg_PVSSRC(&(pAsm->S[0].src));
3272 noswizzle_PVSSRC(&(pAsm->S[0].src));
3273
3274 if( GL_FALSE == next_ins(pAsm) )
3275 {
3276 return GL_FALSE;
3277 }
3278 }
3279
3280 return GL_TRUE;
3281 }
3282
3283 GLboolean assemble_COS(r700_AssemblerBase *pAsm)
3284 {
3285 return assemble_math_function(pAsm, SQ_OP2_INST_COS);
3286 }
3287
3288 GLboolean assemble_DOT(r700_AssemblerBase *pAsm)
3289 {
3290 if( GL_FALSE == checkop2(pAsm) )
3291 {
3292 return GL_FALSE;
3293 }
3294
3295 pAsm->D.dst.opcode = SQ_OP2_INST_DOT4;
3296
3297 if( GL_FALSE == assemble_dst(pAsm) )
3298 {
3299 return GL_FALSE;
3300 }
3301
3302 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3303 {
3304 return GL_FALSE;
3305 }
3306
3307 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
3308 {
3309 return GL_FALSE;
3310 }
3311
3312 if(OPCODE_DP3 == pAsm->pILInst[pAsm->uiCurInst].Opcode)
3313 {
3314 zerocomp_PVSSRC(&(pAsm->S[0].src), 3);
3315 zerocomp_PVSSRC(&(pAsm->S[1].src), 3);
3316 }
3317 else if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_DPH)
3318 {
3319 onecomp_PVSSRC(&(pAsm->S[0].src), 3);
3320 }
3321
3322 if ( GL_FALSE == next_ins(pAsm) )
3323 {
3324 return GL_FALSE;
3325 }
3326
3327 return GL_TRUE;
3328 }
3329
3330 GLboolean assemble_DST(r700_AssemblerBase *pAsm)
3331 {
3332 if( GL_FALSE == checkop2(pAsm) )
3333 {
3334 return GL_FALSE;
3335 }
3336
3337 pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
3338
3339 if( GL_FALSE == assemble_dst(pAsm) )
3340 {
3341 return GL_FALSE;
3342 }
3343
3344 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3345 {
3346 return GL_FALSE;
3347 }
3348
3349 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
3350 {
3351 return GL_FALSE;
3352 }
3353
3354 onecomp_PVSSRC(&(pAsm->S[0].src), 0);
3355 onecomp_PVSSRC(&(pAsm->S[0].src), 3);
3356
3357 onecomp_PVSSRC(&(pAsm->S[1].src), 0);
3358 onecomp_PVSSRC(&(pAsm->S[1].src), 2);
3359
3360 if ( GL_FALSE == next_ins(pAsm) )
3361 {
3362 return GL_FALSE;
3363 }
3364
3365 return GL_TRUE;
3366 }
3367
3368 GLboolean assemble_EX2(r700_AssemblerBase *pAsm)
3369 {
3370 return assemble_math_function(pAsm, SQ_OP2_INST_EXP_IEEE);
3371 }
3372
3373 GLboolean assemble_EXP(r700_AssemblerBase *pAsm)
3374 {
3375 BITS tmp;
3376
3377 checkop1(pAsm);
3378
3379 tmp = gethelpr(pAsm);
3380
3381 // FLOOR tmp.x, a.x
3382 // EX2 dst.x tmp.x
3383
3384 if (pAsm->pILInst->DstReg.WriteMask & 0x1) {
3385 pAsm->D.dst.opcode = SQ_OP2_INST_FLOOR;
3386
3387 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3388 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3389 pAsm->D.dst.reg = tmp;
3390 pAsm->D.dst.writex = 1;
3391
3392 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3393 {
3394 return GL_FALSE;
3395 }
3396
3397 if( GL_FALSE == next_ins(pAsm) )
3398 {
3399 return GL_FALSE;
3400 }
3401
3402 pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
3403 pAsm->D.dst.math = 1;
3404
3405 if( GL_FALSE == assemble_dst(pAsm) )
3406 {
3407 return GL_FALSE;
3408 }
3409
3410 pAsm->D.dst.writey = pAsm->D.dst.writez = pAsm->D.dst.writew = 0;
3411
3412 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3413 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3414 pAsm->S[0].src.reg = tmp;
3415
3416 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3417 noneg_PVSSRC(&(pAsm->S[0].src));
3418
3419 if( GL_FALSE == next_ins(pAsm) )
3420 {
3421 return GL_FALSE;
3422 }
3423 }
3424
3425 // FRACT dst.y a.x
3426
3427 if ((pAsm->pILInst->DstReg.WriteMask >> 1) & 0x1) {
3428 pAsm->D.dst.opcode = SQ_OP2_INST_FRACT;
3429
3430 if( GL_FALSE == assemble_dst(pAsm) )
3431 {
3432 return GL_FALSE;
3433 }
3434
3435 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3436 {
3437 return GL_FALSE;
3438 }
3439
3440 pAsm->D.dst.writex = pAsm->D.dst.writez = pAsm->D.dst.writew = 0;
3441
3442 if( GL_FALSE == next_ins(pAsm) )
3443 {
3444 return GL_FALSE;
3445 }
3446 }
3447
3448 // EX2 dst.z, a.x
3449
3450 if ((pAsm->pILInst->DstReg.WriteMask >> 2) & 0x1) {
3451 pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
3452 pAsm->D.dst.math = 1;
3453
3454 if( GL_FALSE == assemble_dst(pAsm) )
3455 {
3456 return GL_FALSE;
3457 }
3458
3459 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3460 {
3461 return GL_FALSE;
3462 }
3463
3464 pAsm->D.dst.writex = pAsm->D.dst.writey = pAsm->D.dst.writew = 0;
3465
3466 if( GL_FALSE == next_ins(pAsm) )
3467 {
3468 return GL_FALSE;
3469 }
3470 }
3471
3472 // MOV dst.w 1.0
3473
3474 if ((pAsm->pILInst->DstReg.WriteMask >> 3) & 0x1) {
3475 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3476
3477 if( GL_FALSE == assemble_dst(pAsm) )
3478 {
3479 return GL_FALSE;
3480 }
3481
3482 pAsm->D.dst.writex = pAsm->D.dst.writey = pAsm->D.dst.writez = 0;
3483
3484 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3485 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3486 pAsm->S[0].src.reg = tmp;
3487
3488 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_1);
3489 noneg_PVSSRC(&(pAsm->S[0].src));
3490
3491 if( GL_FALSE == next_ins(pAsm) )
3492 {
3493 return GL_FALSE;
3494 }
3495 }
3496
3497 return GL_TRUE;
3498 }
3499
3500 GLboolean assemble_FLR(r700_AssemblerBase *pAsm)
3501 {
3502 checkop1(pAsm);
3503
3504 pAsm->D.dst.opcode = SQ_OP2_INST_FLOOR;
3505
3506 if ( GL_FALSE == assemble_dst(pAsm) )
3507 {
3508 return GL_FALSE;
3509 }
3510
3511 if ( GL_FALSE == assemble_src(pAsm, 0, -1) )
3512 {
3513 return GL_FALSE;
3514 }
3515
3516 if ( GL_FALSE == next_ins(pAsm) )
3517 {
3518 return GL_FALSE;
3519 }
3520
3521 return GL_TRUE;
3522 }
3523
3524 GLboolean assemble_FLR_INT(r700_AssemblerBase *pAsm)
3525 {
3526 return assemble_math_function(pAsm, SQ_OP2_INST_FLT_TO_INT);
3527 }
3528
3529 GLboolean assemble_FRC(r700_AssemblerBase *pAsm)
3530 {
3531 checkop1(pAsm);
3532
3533 pAsm->D.dst.opcode = SQ_OP2_INST_FRACT;
3534
3535 if ( GL_FALSE == assemble_dst(pAsm) )
3536 {
3537 return GL_FALSE;
3538 }
3539
3540 if ( GL_FALSE == assemble_src(pAsm, 0, -1) )
3541 {
3542 return GL_FALSE;
3543 }
3544
3545 if ( GL_FALSE == next_ins(pAsm) )
3546 {
3547 return GL_FALSE;
3548 }
3549
3550 return GL_TRUE;
3551 }
3552
3553 GLboolean assemble_KIL(r700_AssemblerBase *pAsm)
3554 {
3555 /* TODO: doc says KILL has to be last(end) ALU clause */
3556
3557 checkop1(pAsm);
3558
3559 pAsm->D.dst.opcode = SQ_OP2_INST_KILLGT;
3560
3561 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3562 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3563 pAsm->D.dst.reg = 0;
3564 pAsm->D.dst.writex = 0;
3565 pAsm->D.dst.writey = 0;
3566 pAsm->D.dst.writez = 0;
3567 pAsm->D.dst.writew = 0;
3568
3569 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3570 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3571 pAsm->S[0].src.reg = 0;
3572
3573 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_0);
3574 noneg_PVSSRC(&(pAsm->S[0].src));
3575
3576 if ( GL_FALSE == assemble_src(pAsm, 0, 1) )
3577 {
3578 return GL_FALSE;
3579 }
3580
3581 if ( GL_FALSE == next_ins(pAsm) )
3582 {
3583 return GL_FALSE;
3584 }
3585
3586 pAsm->pR700Shader->killIsUsed = GL_TRUE;
3587
3588 return GL_TRUE;
3589 }
3590
3591 GLboolean assemble_LG2(r700_AssemblerBase *pAsm)
3592 {
3593 return assemble_math_function(pAsm, SQ_OP2_INST_LOG_IEEE);
3594 }
3595
3596 GLboolean assemble_LRP(r700_AssemblerBase *pAsm)
3597 {
3598 BITS tmp;
3599
3600 if( GL_FALSE == checkop3(pAsm) )
3601 {
3602 return GL_FALSE;
3603 }
3604
3605 tmp = gethelpr(pAsm);
3606
3607 pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
3608
3609 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3610 pAsm->D.dst.reg = tmp;
3611 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3612 nomask_PVSDST(&(pAsm->D.dst));
3613
3614
3615 if( GL_FALSE == assemble_src(pAsm, 1, 0) )
3616 {
3617 return GL_FALSE;
3618 }
3619
3620 if ( GL_FALSE == assemble_src(pAsm, 2, 1) )
3621 {
3622 return GL_FALSE;
3623 }
3624
3625 neg_PVSSRC(&(pAsm->S[1].src));
3626
3627 if( GL_FALSE == next_ins(pAsm) )
3628 {
3629 return GL_FALSE;
3630 }
3631
3632 pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
3633 pAsm->D.dst.op3 = 1;
3634
3635 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3636 pAsm->D.dst.reg = tmp;
3637 nomask_PVSDST(&(pAsm->D.dst));
3638 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3639
3640 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3641 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3642 pAsm->S[0].src.reg = tmp;
3643 noswizzle_PVSSRC(&(pAsm->S[0].src));
3644
3645
3646 if( GL_FALSE == assemble_src(pAsm, 0, 1) )
3647 {
3648 return GL_FALSE;
3649 }
3650 if( GL_FALSE == assemble_src(pAsm, 2, -1) )
3651 {
3652 return GL_FALSE;
3653 }
3654
3655 if( GL_FALSE == next_ins(pAsm) )
3656 {
3657 return GL_FALSE;
3658 }
3659
3660 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3661
3662 if( GL_FALSE == assemble_dst(pAsm) )
3663 {
3664 return GL_FALSE;
3665 }
3666
3667 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3668 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3669 pAsm->S[0].src.reg = tmp;
3670 noswizzle_PVSSRC(&(pAsm->S[0].src));
3671
3672 if( GL_FALSE == next_ins(pAsm) )
3673 {
3674 return GL_FALSE;
3675 }
3676
3677 return GL_TRUE;
3678 }
3679
3680 GLboolean assemble_LOG(r700_AssemblerBase *pAsm)
3681 {
3682 BITS tmp1, tmp2, tmp3;
3683
3684 checkop1(pAsm);
3685
3686 tmp1 = gethelpr(pAsm);
3687 tmp2 = gethelpr(pAsm);
3688 tmp3 = gethelpr(pAsm);
3689
3690 // FIXME: The hardware can do fabs() directly on input
3691 // elements, but the compiler doesn't have the
3692 // capability to use that.
3693
3694 // MAX tmp1.x, a.x, -a.x (fabs(a.x))
3695
3696 pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
3697
3698 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3699 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3700 pAsm->D.dst.reg = tmp1;
3701 pAsm->D.dst.writex = 1;
3702
3703 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3704 {
3705 return GL_FALSE;
3706 }
3707
3708 pAsm->S[1].bits = pAsm->S[0].bits;
3709 flipneg_PVSSRC(&(pAsm->S[1].src));
3710
3711 if ( GL_FALSE == next_ins(pAsm) )
3712 {
3713 return GL_FALSE;
3714 }
3715
3716 // Entire algo:
3717 //
3718 // LG2 tmp2.x, tmp1.x
3719 // FLOOR tmp3.x, tmp2.x
3720 // MOV dst.x, tmp3.x
3721 // ADD tmp3.x, tmp2.x, -tmp3.x
3722 // EX2 dst.y, tmp3.x
3723 // MOV dst.z, tmp2.x
3724 // MOV dst.w, 1.0
3725
3726 // LG2 tmp2.x, tmp1.x
3727 // FLOOR tmp3.x, tmp2.x
3728
3729 pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
3730 pAsm->D.dst.math = 1;
3731
3732 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3733 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3734 pAsm->D.dst.reg = tmp2;
3735 pAsm->D.dst.writex = 1;
3736
3737 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3738 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3739 pAsm->S[0].src.reg = tmp1;
3740
3741 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3742 noneg_PVSSRC(&(pAsm->S[0].src));
3743
3744 if( GL_FALSE == next_ins(pAsm) )
3745 {
3746 return GL_FALSE;
3747 }
3748
3749 pAsm->D.dst.opcode = SQ_OP2_INST_FLOOR;
3750
3751 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3752 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3753 pAsm->D.dst.reg = tmp3;
3754 pAsm->D.dst.writex = 1;
3755
3756 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3757 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3758 pAsm->S[0].src.reg = tmp2;
3759
3760 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3761 noneg_PVSSRC(&(pAsm->S[0].src));
3762
3763 if( GL_FALSE == next_ins(pAsm) )
3764 {
3765 return GL_FALSE;
3766 }
3767
3768 // MOV dst.x, tmp3.x
3769
3770 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3771
3772 if( GL_FALSE == assemble_dst(pAsm) )
3773 {
3774 return GL_FALSE;
3775 }
3776
3777 pAsm->D.dst.writey = pAsm->D.dst.writez = pAsm->D.dst.writew = 0;
3778
3779 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3780 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3781 pAsm->S[0].src.reg = tmp3;
3782
3783 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3784 noneg_PVSSRC(&(pAsm->S[0].src));
3785
3786 if( GL_FALSE == next_ins(pAsm) )
3787 {
3788 return GL_FALSE;
3789 }
3790
3791 // ADD tmp3.x, tmp2.x, -tmp3.x
3792 // EX2 dst.y, tmp3.x
3793
3794 pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
3795
3796 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3797 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3798 pAsm->D.dst.reg = tmp3;
3799 pAsm->D.dst.writex = 1;
3800
3801 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3802 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3803 pAsm->S[0].src.reg = tmp2;
3804
3805 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3806 noneg_PVSSRC(&(pAsm->S[0].src));
3807
3808 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
3809 pAsm->S[1].src.rtype = DST_REG_TEMPORARY;
3810 pAsm->S[1].src.reg = tmp3;
3811
3812 setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X);
3813 neg_PVSSRC(&(pAsm->S[1].src));
3814
3815 if( GL_FALSE == next_ins(pAsm) )
3816 {
3817 return GL_FALSE;
3818 }
3819
3820 pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
3821 pAsm->D.dst.math = 1;
3822
3823 if( GL_FALSE == assemble_dst(pAsm) )
3824 {
3825 return GL_FALSE;
3826 }
3827
3828 pAsm->D.dst.writex = pAsm->D.dst.writez = pAsm->D.dst.writew = 0;
3829
3830 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3831 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3832 pAsm->S[0].src.reg = tmp3;
3833
3834 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3835 noneg_PVSSRC(&(pAsm->S[0].src));
3836
3837 if( GL_FALSE == next_ins(pAsm) )
3838 {
3839 return GL_FALSE;
3840 }
3841
3842 // MOV dst.z, tmp2.x
3843
3844 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3845
3846 if( GL_FALSE == assemble_dst(pAsm) )
3847 {
3848 return GL_FALSE;
3849 }
3850
3851 pAsm->D.dst.writex = pAsm->D.dst.writey = pAsm->D.dst.writew = 0;
3852
3853 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3854 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
3855 pAsm->S[0].src.reg = tmp2;
3856
3857 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
3858 noneg_PVSSRC(&(pAsm->S[0].src));
3859
3860 if( GL_FALSE == next_ins(pAsm) )
3861 {
3862 return GL_FALSE;
3863 }
3864
3865 // MOV dst.w 1.0
3866
3867 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3868
3869 if( GL_FALSE == assemble_dst(pAsm) )
3870 {
3871 return GL_FALSE;
3872 }
3873
3874 pAsm->D.dst.writex = pAsm->D.dst.writey = pAsm->D.dst.writez = 0;
3875
3876 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3877 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3878 pAsm->S[0].src.reg = tmp1;
3879
3880 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_1);
3881 noneg_PVSSRC(&(pAsm->S[0].src));
3882
3883 if( GL_FALSE == next_ins(pAsm) )
3884 {
3885 return GL_FALSE;
3886 }
3887
3888 return GL_TRUE;
3889 }
3890
3891 GLboolean assemble_MAD(struct r700_AssemblerBase *pAsm)
3892 {
3893 int tmp, ii;
3894 GLboolean bReplaceDst = GL_FALSE;
3895 struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
3896
3897 if( GL_FALSE == checkop3(pAsm) )
3898 {
3899 return GL_FALSE;
3900 }
3901
3902 pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
3903 pAsm->D.dst.op3 = 1;
3904
3905 tmp = (-1);
3906
3907 if(PROGRAM_TEMPORARY == pILInst->DstReg.File)
3908 { /* TODO : more investigation on MAD src and dst using same register */
3909 for(ii=0; ii<3; ii++)
3910 {
3911 if( (PROGRAM_TEMPORARY == pILInst->SrcReg[ii].File)
3912 && (pILInst->DstReg.Index == pILInst->SrcReg[ii].Index) )
3913 {
3914 bReplaceDst = GL_TRUE;
3915 break;
3916 }
3917 }
3918 }
3919 if(0xF != pILInst->DstReg.WriteMask)
3920 { /* OP3 has no support for write mask */
3921 bReplaceDst = GL_TRUE;
3922 }
3923
3924 if(GL_TRUE == bReplaceDst)
3925 {
3926 tmp = gethelpr(pAsm);
3927
3928 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
3929 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
3930 pAsm->D.dst.reg = tmp;
3931
3932 nomask_PVSDST(&(pAsm->D.dst));
3933 }
3934 else
3935 {
3936 if( GL_FALSE == assemble_dst(pAsm) )
3937 {
3938 return GL_FALSE;
3939 }
3940 }
3941
3942 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
3943 {
3944 return GL_FALSE;
3945 }
3946
3947 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
3948 {
3949 return GL_FALSE;
3950 }
3951
3952 if( GL_FALSE == assemble_src(pAsm, 2, -1) )
3953 {
3954 return GL_FALSE;
3955 }
3956
3957 if ( GL_FALSE == next_ins(pAsm) )
3958 {
3959 return GL_FALSE;
3960 }
3961
3962 if (GL_TRUE == bReplaceDst)
3963 {
3964 if( GL_FALSE == assemble_dst(pAsm) )
3965 {
3966 return GL_FALSE;
3967 }
3968
3969 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
3970
3971 //tmp for source
3972 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
3973 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
3974 pAsm->S[0].src.reg = tmp;
3975
3976 noneg_PVSSRC(&(pAsm->S[0].src));
3977 noswizzle_PVSSRC(&(pAsm->S[0].src));
3978
3979 if( GL_FALSE == next_ins(pAsm) )
3980 {
3981 return GL_FALSE;
3982 }
3983 }
3984
3985 return GL_TRUE;
3986 }
3987
3988 /* LIT dst, src */
3989 GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
3990 {
3991 unsigned int dstReg;
3992 unsigned int dstType;
3993 unsigned int srcReg;
3994 unsigned int srcType;
3995 checkop1(pAsm);
3996 int tmp = gethelpr(pAsm);
3997
3998 if( GL_FALSE == assemble_dst(pAsm) )
3999 {
4000 return GL_FALSE;
4001 }
4002 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4003 {
4004 return GL_FALSE;
4005 }
4006 dstReg = pAsm->D.dst.reg;
4007 dstType = pAsm->D.dst.rtype;
4008 srcReg = pAsm->S[0].src.reg;
4009 srcType = pAsm->S[0].src.rtype;
4010
4011 /* dst.xw, <- 1.0 */
4012 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4013 pAsm->D.dst.rtype = dstType;
4014 pAsm->D.dst.reg = dstReg;
4015 pAsm->D.dst.writex = 1;
4016 pAsm->D.dst.writey = 0;
4017 pAsm->D.dst.writez = 0;
4018 pAsm->D.dst.writew = 1;
4019 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4020 pAsm->S[0].src.reg = tmp;
4021 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4022 noneg_PVSSRC(&(pAsm->S[0].src));
4023 pAsm->S[0].src.swizzlex = SQ_SEL_1;
4024 pAsm->S[0].src.swizzley = SQ_SEL_1;
4025 pAsm->S[0].src.swizzlez = SQ_SEL_1;
4026 pAsm->S[0].src.swizzlew = SQ_SEL_1;
4027 if( GL_FALSE == next_ins(pAsm) )
4028 {
4029 return GL_FALSE;
4030 }
4031
4032 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4033 {
4034 return GL_FALSE;
4035 }
4036
4037 /* dst.y = max(src.x, 0.0) */
4038 pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
4039 pAsm->D.dst.rtype = dstType;
4040 pAsm->D.dst.reg = dstReg;
4041 pAsm->D.dst.writex = 0;
4042 pAsm->D.dst.writey = 1;
4043 pAsm->D.dst.writez = 0;
4044 pAsm->D.dst.writew = 0;
4045 pAsm->S[0].src.rtype = srcType;
4046 pAsm->S[0].src.reg = srcReg;
4047 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4048 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X, SQ_SEL_X, SQ_SEL_X, SQ_SEL_X);
4049 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4050 pAsm->S[1].src.reg = tmp;
4051 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
4052 noneg_PVSSRC(&(pAsm->S[1].src));
4053 pAsm->S[1].src.swizzlex = SQ_SEL_0;
4054 pAsm->S[1].src.swizzley = SQ_SEL_0;
4055 pAsm->S[1].src.swizzlez = SQ_SEL_0;
4056 pAsm->S[1].src.swizzlew = SQ_SEL_0;
4057 if( GL_FALSE == next_ins(pAsm) )
4058 {
4059 return GL_FALSE;
4060 }
4061
4062 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4063 {
4064 return GL_FALSE;
4065 }
4066
4067 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y);
4068
4069 /* dst.z = log(src.y) */
4070 pAsm->D.dst.opcode = SQ_OP2_INST_LOG_CLAMPED;
4071 pAsm->D.dst.math = 1;
4072 pAsm->D.dst.rtype = dstType;
4073 pAsm->D.dst.reg = dstReg;
4074 pAsm->D.dst.writex = 0;
4075 pAsm->D.dst.writey = 0;
4076 pAsm->D.dst.writez = 1;
4077 pAsm->D.dst.writew = 0;
4078 pAsm->S[0].src.rtype = srcType;
4079 pAsm->S[0].src.reg = srcReg;
4080 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4081 if( GL_FALSE == next_ins(pAsm) )
4082 {
4083 return GL_FALSE;
4084 }
4085
4086 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4087 {
4088 return GL_FALSE;
4089 }
4090
4091 if( GL_FALSE == assemble_src(pAsm, 0, 2) )
4092 {
4093 return GL_FALSE;
4094 }
4095
4096 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_W, SQ_SEL_W, SQ_SEL_W, SQ_SEL_W);
4097
4098 swizzleagain_PVSSRC(&(pAsm->S[2].src), SQ_SEL_X, SQ_SEL_X, SQ_SEL_X, SQ_SEL_X);
4099
4100 /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
4101 pAsm->D.dst.opcode = SQ_OP3_INST_MUL_LIT;
4102 pAsm->D.dst.math = 1;
4103 pAsm->D.dst.op3 = 1;
4104 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4105 pAsm->D.dst.reg = tmp;
4106 pAsm->D.dst.writex = 1;
4107 pAsm->D.dst.writey = 0;
4108 pAsm->D.dst.writez = 0;
4109 pAsm->D.dst.writew = 0;
4110
4111 pAsm->S[0].src.rtype = srcType;
4112 pAsm->S[0].src.reg = srcReg;
4113 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4114
4115 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4116 pAsm->S[1].src.reg = dstReg;
4117 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
4118 noneg_PVSSRC(&(pAsm->S[1].src));
4119 pAsm->S[1].src.swizzlex = SQ_SEL_Z;
4120 pAsm->S[1].src.swizzley = SQ_SEL_Z;
4121 pAsm->S[1].src.swizzlez = SQ_SEL_Z;
4122 pAsm->S[1].src.swizzlew = SQ_SEL_Z;
4123
4124 pAsm->S[2].src.rtype = srcType;
4125 pAsm->S[2].src.reg = srcReg;
4126 setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
4127
4128 if( GL_FALSE == next_ins(pAsm) )
4129 {
4130 return GL_FALSE;
4131 }
4132
4133 /* dst.z = exp(tmp.x) */
4134 pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
4135 pAsm->D.dst.math = 1;
4136 pAsm->D.dst.rtype = dstType;
4137 pAsm->D.dst.reg = dstReg;
4138 pAsm->D.dst.writex = 0;
4139 pAsm->D.dst.writey = 0;
4140 pAsm->D.dst.writez = 1;
4141 pAsm->D.dst.writew = 0;
4142
4143 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4144 pAsm->S[0].src.reg = tmp;
4145 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4146 noneg_PVSSRC(&(pAsm->S[0].src));
4147 pAsm->S[0].src.swizzlex = SQ_SEL_X;
4148 pAsm->S[0].src.swizzley = SQ_SEL_X;
4149 pAsm->S[0].src.swizzlez = SQ_SEL_X;
4150 pAsm->S[0].src.swizzlew = SQ_SEL_X;
4151
4152 if( GL_FALSE == next_ins(pAsm) )
4153 {
4154 return GL_FALSE;
4155 }
4156
4157 return GL_TRUE;
4158 }
4159
4160 GLboolean assemble_MAX(r700_AssemblerBase *pAsm)
4161 {
4162 if( GL_FALSE == checkop2(pAsm) )
4163 {
4164 return GL_FALSE;
4165 }
4166
4167 pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
4168
4169 if( GL_FALSE == assemble_dst(pAsm) )
4170 {
4171 return GL_FALSE;
4172 }
4173
4174 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4175 {
4176 return GL_FALSE;
4177 }
4178
4179 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4180 {
4181 return GL_FALSE;
4182 }
4183
4184 if( GL_FALSE == next_ins(pAsm) )
4185 {
4186 return GL_FALSE;
4187 }
4188
4189 return GL_TRUE;
4190 }
4191
4192 GLboolean assemble_MIN(r700_AssemblerBase *pAsm)
4193 {
4194 if( GL_FALSE == checkop2(pAsm) )
4195 {
4196 return GL_FALSE;
4197 }
4198
4199 pAsm->D.dst.opcode = SQ_OP2_INST_MIN;
4200
4201 if( GL_FALSE == assemble_dst(pAsm) )
4202 {
4203 return GL_FALSE;
4204 }
4205
4206 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4207 {
4208 return GL_FALSE;
4209 }
4210
4211 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4212 {
4213 return GL_FALSE;
4214 }
4215
4216 if( GL_FALSE == next_ins(pAsm) )
4217 {
4218 return GL_FALSE;
4219 }
4220
4221 return GL_TRUE;
4222 }
4223
4224 GLboolean assemble_MOV(r700_AssemblerBase *pAsm)
4225 {
4226 checkop1(pAsm);
4227
4228 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4229
4230 if (GL_FALSE == assemble_dst(pAsm))
4231 {
4232 return GL_FALSE;
4233 }
4234
4235 if (GL_FALSE == assemble_src(pAsm, 0, -1))
4236 {
4237 return GL_FALSE;
4238 }
4239
4240 if ( GL_FALSE == next_ins(pAsm) )
4241 {
4242 return GL_FALSE;
4243 }
4244
4245 return GL_TRUE;
4246 }
4247
4248 GLboolean assemble_MUL(r700_AssemblerBase *pAsm)
4249 {
4250 if( GL_FALSE == checkop2(pAsm) )
4251 {
4252 return GL_FALSE;
4253 }
4254
4255 pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
4256
4257 if( GL_FALSE == assemble_dst(pAsm) )
4258 {
4259 return GL_FALSE;
4260 }
4261
4262 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4263 {
4264 return GL_FALSE;
4265 }
4266
4267 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4268 {
4269 return GL_FALSE;
4270 }
4271
4272 if( GL_FALSE == next_ins(pAsm) )
4273 {
4274 return GL_FALSE;
4275 }
4276
4277 return GL_TRUE;
4278 }
4279
4280 GLboolean assemble_POW(r700_AssemblerBase *pAsm)
4281 {
4282 BITS tmp;
4283
4284 checkop1(pAsm);
4285
4286 tmp = gethelpr(pAsm);
4287
4288 // LG2 tmp.x, a.swizzle
4289 pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
4290 pAsm->D.dst.math = 1;
4291
4292 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4293 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4294 pAsm->D.dst.reg = tmp;
4295 nomask_PVSDST(&(pAsm->D.dst));
4296
4297 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4298 {
4299 return GL_FALSE;
4300 }
4301
4302 if( GL_FALSE == next_ins(pAsm) )
4303 {
4304 return GL_FALSE;
4305 }
4306
4307 // MUL tmp.x, tmp.x, b.swizzle
4308 pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
4309
4310 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4311 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4312 pAsm->D.dst.reg = tmp;
4313 nomask_PVSDST(&(pAsm->D.dst));
4314
4315 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4316 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4317 pAsm->S[0].src.reg = tmp;
4318 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
4319 noneg_PVSSRC(&(pAsm->S[0].src));
4320
4321 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4322 {
4323 return GL_FALSE;
4324 }
4325
4326 if( GL_FALSE == next_ins(pAsm) )
4327 {
4328 return GL_FALSE;
4329 }
4330
4331 // EX2 dst.mask, tmp.x
4332 // EX2 tmp.x, tmp.x
4333 pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
4334 pAsm->D.dst.math = 1;
4335
4336 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4337 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4338 pAsm->D.dst.reg = tmp;
4339 nomask_PVSDST(&(pAsm->D.dst));
4340
4341 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4342 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4343 pAsm->S[0].src.reg = tmp;
4344 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
4345 noneg_PVSSRC(&(pAsm->S[0].src));
4346
4347 if( GL_FALSE == next_ins(pAsm) )
4348 {
4349 return GL_FALSE;
4350 }
4351
4352 // Now replicate result to all necessary channels in destination
4353 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4354
4355 if( GL_FALSE == assemble_dst(pAsm) )
4356 {
4357 return GL_FALSE;
4358 }
4359
4360 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4361 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
4362 pAsm->S[0].src.reg = tmp;
4363
4364 setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
4365 noneg_PVSSRC(&(pAsm->S[0].src));
4366
4367 if( GL_FALSE == next_ins(pAsm) )
4368 {
4369 return GL_FALSE;
4370 }
4371
4372 return GL_TRUE;
4373 }
4374
4375 GLboolean assemble_RCP(r700_AssemblerBase *pAsm)
4376 {
4377 return assemble_math_function(pAsm, SQ_OP2_INST_RECIP_IEEE);
4378 }
4379
4380 GLboolean assemble_RSQ(r700_AssemblerBase *pAsm)
4381 {
4382 return assemble_math_function(pAsm, SQ_OP2_INST_RECIPSQRT_IEEE);
4383 }
4384
4385 GLboolean assemble_SIN(r700_AssemblerBase *pAsm)
4386 {
4387 return assemble_math_function(pAsm, SQ_OP2_INST_SIN);
4388 }
4389
4390 GLboolean assemble_SCS(r700_AssemblerBase *pAsm)
4391 {
4392 BITS tmp;
4393
4394 checkop1(pAsm);
4395
4396 tmp = gethelpr(pAsm);
4397
4398 // COS tmp.x, a.x
4399 pAsm->D.dst.opcode = SQ_OP2_INST_COS;
4400 pAsm->D.dst.math = 1;
4401
4402 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4403 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4404 pAsm->D.dst.reg = tmp;
4405 pAsm->D.dst.writex = 1;
4406
4407 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4408 {
4409 return GL_FALSE;
4410 }
4411
4412 if ( GL_FALSE == next_ins(pAsm) )
4413 {
4414 return GL_FALSE;
4415 }
4416
4417 // SIN tmp.y, a.x
4418 pAsm->D.dst.opcode = SQ_OP2_INST_SIN;
4419 pAsm->D.dst.math = 1;
4420
4421 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4422 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4423 pAsm->D.dst.reg = tmp;
4424 pAsm->D.dst.writey = 1;
4425
4426 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4427 {
4428 return GL_FALSE;
4429 }
4430
4431 if( GL_FALSE == next_ins(pAsm) )
4432 {
4433 return GL_FALSE;
4434 }
4435
4436 // MOV dst.mask, tmp
4437 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4438
4439 if( GL_FALSE == assemble_dst(pAsm) )
4440 {
4441 return GL_FALSE;
4442 }
4443
4444 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4445 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
4446 pAsm->S[0].src.reg = tmp;
4447
4448 noswizzle_PVSSRC(&(pAsm->S[0].src));
4449 pAsm->S[0].src.swizzlez = SQ_SEL_0;
4450 pAsm->S[0].src.swizzlew = SQ_SEL_0;
4451
4452 if ( GL_FALSE == next_ins(pAsm) )
4453 {
4454 return GL_FALSE;
4455 }
4456
4457 return GL_TRUE;
4458 }
4459
4460 GLboolean assemble_LOGIC(r700_AssemblerBase *pAsm, BITS opcode)
4461 {
4462 if( GL_FALSE == checkop2(pAsm) )
4463 {
4464 return GL_FALSE;
4465 }
4466
4467 pAsm->D.dst.opcode = opcode;
4468 pAsm->D.dst.math = 1;
4469
4470 if( GL_FALSE == assemble_dst(pAsm) )
4471 {
4472 return GL_FALSE;
4473 }
4474
4475 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4476 {
4477 return GL_FALSE;
4478 }
4479
4480 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4481 {
4482 return GL_FALSE;
4483 }
4484
4485 if( GL_FALSE == next_ins(pAsm) )
4486 {
4487 return GL_FALSE;
4488 }
4489
4490 return GL_TRUE;
4491 }
4492
4493 GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode)
4494 {
4495 if( GL_FALSE == checkop2(pAsm) )
4496 {
4497 return GL_FALSE;
4498 }
4499
4500 pAsm->D.dst.opcode = opcode;
4501 pAsm->D.dst.math = 1;
4502 pAsm->D.dst.predicated = 1;
4503 pAsm->D2.dst2.SaturateMode = pAsm->pILInst[pAsm->uiCurInst].SaturateMode;
4504
4505 if( GL_FALSE == assemble_dst(pAsm) )
4506 {
4507 return GL_FALSE;
4508 }
4509
4510 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4511 {
4512 return GL_FALSE;
4513 }
4514
4515 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4516 {
4517 return GL_FALSE;
4518 }
4519
4520 if( GL_FALSE == next_ins2(pAsm) )
4521 {
4522 return GL_FALSE;
4523 }
4524
4525 return GL_TRUE;
4526 }
4527
4528 GLboolean assemble_SGE(r700_AssemblerBase *pAsm)
4529 {
4530 if( GL_FALSE == checkop2(pAsm) )
4531 {
4532 return GL_FALSE;
4533 }
4534
4535 pAsm->D.dst.opcode = SQ_OP2_INST_SETGE;
4536
4537 if( GL_FALSE == assemble_dst(pAsm) )
4538 {
4539 return GL_FALSE;
4540 }
4541
4542 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4543 {
4544 return GL_FALSE;
4545 }
4546
4547 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4548 {
4549 return GL_FALSE;
4550 }
4551
4552 if( GL_FALSE == next_ins(pAsm) )
4553 {
4554 return GL_FALSE;
4555 }
4556
4557 return GL_TRUE;
4558 }
4559
4560 GLboolean assemble_SLT(r700_AssemblerBase *pAsm)
4561 {
4562 if( GL_FALSE == checkop2(pAsm) )
4563 {
4564 return GL_FALSE;
4565 }
4566
4567 pAsm->D.dst.opcode = SQ_OP2_INST_SETGT;
4568
4569 if( GL_FALSE == assemble_dst(pAsm) )
4570 {
4571 return GL_FALSE;
4572 }
4573
4574 if( GL_FALSE == assemble_src(pAsm, 0, 1) )
4575 {
4576 return GL_FALSE;
4577 }
4578
4579 if( GL_FALSE == assemble_src(pAsm, 1, 0) )
4580 {
4581 return GL_FALSE;
4582 }
4583
4584 if( GL_FALSE == next_ins(pAsm) )
4585 {
4586 return GL_FALSE;
4587 }
4588
4589 return GL_TRUE;
4590 }
4591
4592 GLboolean assemble_STP(r700_AssemblerBase *pAsm)
4593 {
4594 return GL_TRUE;
4595 }
4596
4597 GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
4598 {
4599 GLboolean src_const;
4600 GLboolean need_barrier = GL_FALSE;
4601
4602 checkop1(pAsm);
4603
4604 switch (pAsm->pILInst[pAsm->uiCurInst].SrcReg[0].File)
4605 {
4606 case PROGRAM_CONSTANT:
4607 case PROGRAM_LOCAL_PARAM:
4608 case PROGRAM_ENV_PARAM:
4609 case PROGRAM_STATE_VAR:
4610 src_const = GL_TRUE;
4611 break;
4612 case PROGRAM_TEMPORARY:
4613 case PROGRAM_INPUT:
4614 default:
4615 src_const = GL_FALSE;
4616 break;
4617 }
4618
4619 if (GL_TRUE == src_const)
4620 {
4621 if ( GL_FALSE == mov_temp(pAsm, 0) )
4622 return GL_FALSE;
4623 need_barrier = GL_TRUE;
4624 }
4625
4626 switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
4627 {
4628 case OPCODE_TEX:
4629 break;
4630 case OPCODE_TXB:
4631 radeon_error("do not support TXB yet\n");
4632 return GL_FALSE;
4633 break;
4634 case OPCODE_TXP:
4635 break;
4636 default:
4637 radeon_error("Internal error: bad texture op (not TEX)\n");
4638 return GL_FALSE;
4639 break;
4640 }
4641
4642 if (pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
4643 {
4644 GLuint tmp = gethelpr(pAsm);
4645 pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
4646 pAsm->D.dst.math = 1;
4647 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4648 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4649 pAsm->D.dst.reg = tmp;
4650 pAsm->D.dst.writew = 1;
4651
4652 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4653 {
4654 return GL_FALSE;
4655 }
4656 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_W, SQ_SEL_W, SQ_SEL_W, SQ_SEL_W);
4657 if( GL_FALSE == next_ins(pAsm) )
4658 {
4659 return GL_FALSE;
4660 }
4661
4662 pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
4663 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4664 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4665 pAsm->D.dst.reg = tmp;
4666 pAsm->D.dst.writex = 1;
4667 pAsm->D.dst.writey = 1;
4668 pAsm->D.dst.writez = 1;
4669 pAsm->D.dst.writew = 0;
4670
4671 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4672 {
4673 return GL_FALSE;
4674 }
4675 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
4676 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4677 pAsm->S[1].src.reg = tmp;
4678 setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_W);
4679
4680 if( GL_FALSE == next_ins(pAsm) )
4681 {
4682 return GL_FALSE;
4683 }
4684
4685 pAsm->aArgSubst[1] = tmp;
4686 need_barrier = GL_TRUE;
4687 }
4688
4689 if (pAsm->pILInst[pAsm->uiCurInst].TexSrcTarget == TEXTURE_CUBE_INDEX )
4690 {
4691 GLuint tmp1 = gethelpr(pAsm);
4692 GLuint tmp2 = gethelpr(pAsm);
4693
4694 /* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */
4695 pAsm->D.dst.opcode = SQ_OP2_INST_CUBE;
4696 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4697 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4698 pAsm->D.dst.reg = tmp1;
4699 nomask_PVSDST(&(pAsm->D.dst));
4700
4701 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4702 {
4703 return GL_FALSE;
4704 }
4705
4706 if( GL_FALSE == assemble_src(pAsm, 0, 1) )
4707 {
4708 return GL_FALSE;
4709 }
4710
4711 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Z, SQ_SEL_Z, SQ_SEL_X, SQ_SEL_Y);
4712 swizzleagain_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Y, SQ_SEL_X, SQ_SEL_Z, SQ_SEL_Z);
4713
4714 if( GL_FALSE == next_ins(pAsm) )
4715 {
4716 return GL_FALSE;
4717 }
4718
4719 /* tmp1.z = ABS(tmp1.z) dont have abs support in assembler currently
4720 * have to do explicit instruction
4721 */
4722 pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
4723 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4724 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4725 pAsm->D.dst.reg = tmp1;
4726 pAsm->D.dst.writez = 1;
4727
4728 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4729 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4730 pAsm->S[0].src.reg = tmp1;
4731 noswizzle_PVSSRC(&(pAsm->S[0].src));
4732 pAsm->S[1].bits = pAsm->S[0].bits;
4733 flipneg_PVSSRC(&(pAsm->S[1].src));
4734
4735 next_ins(pAsm);
4736
4737 /* tmp1.z = RCP_e(|tmp1.z|) */
4738 pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
4739 pAsm->D.dst.math = 1;
4740 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4741 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4742 pAsm->D.dst.reg = tmp1;
4743 pAsm->D.dst.writez = 1;
4744
4745 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4746 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4747 pAsm->S[0].src.reg = tmp1;
4748 pAsm->S[0].src.swizzlex = SQ_SEL_Z;
4749
4750 next_ins(pAsm);
4751
4752 /* MULADD R0.x, R0.x, PS1, (0x3FC00000, 1.5f).x
4753 * MULADD R0.y, R0.y, PS1, (0x3FC00000, 1.5f).x
4754 * muladd has no writemask, have to use another temp
4755 * also no support for imm constants, so add 1 here
4756 */
4757 pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
4758 pAsm->D.dst.op3 = 1;
4759 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4760 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4761 pAsm->D.dst.reg = tmp2;
4762
4763 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4764 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4765 pAsm->S[0].src.reg = tmp1;
4766 noswizzle_PVSSRC(&(pAsm->S[0].src));
4767 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
4768 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4769 pAsm->S[1].src.reg = tmp1;
4770 setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Z);
4771 setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
4772 pAsm->S[2].src.rtype = SRC_REG_TEMPORARY;
4773 pAsm->S[2].src.reg = tmp1;
4774 setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_1);
4775
4776 next_ins(pAsm);
4777
4778 /* ADD the remaining .5 */
4779 pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
4780 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4781 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4782 pAsm->D.dst.reg = tmp2;
4783 pAsm->D.dst.writex = 1;
4784 pAsm->D.dst.writey = 1;
4785 pAsm->D.dst.writez = 0;
4786 pAsm->D.dst.writew = 0;
4787
4788 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4789 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4790 pAsm->S[0].src.reg = tmp2;
4791 noswizzle_PVSSRC(&(pAsm->S[0].src));
4792 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
4793 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4794 pAsm->S[1].src.reg = 252; // SQ_ALU_SRC_0_5
4795 noswizzle_PVSSRC(&(pAsm->S[1].src));
4796
4797 next_ins(pAsm);
4798
4799 /* tmp1.xy = temp2.xy */
4800 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4801 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4802 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4803 pAsm->D.dst.reg = tmp1;
4804 pAsm->D.dst.writex = 1;
4805 pAsm->D.dst.writey = 1;
4806 pAsm->D.dst.writez = 0;
4807 pAsm->D.dst.writew = 0;
4808
4809 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4810 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4811 pAsm->S[0].src.reg = tmp2;
4812 noswizzle_PVSSRC(&(pAsm->S[0].src));
4813
4814 next_ins(pAsm);
4815 pAsm->aArgSubst[1] = tmp1;
4816 need_barrier = GL_TRUE;
4817
4818 }
4819
4820 pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
4821 pAsm->is_tex = GL_TRUE;
4822 if ( GL_TRUE == need_barrier )
4823 {
4824 pAsm->need_tex_barrier = GL_TRUE;
4825 }
4826 // Set src1 to tex unit id
4827 pAsm->S[1].src.reg = pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit;
4828 pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
4829
4830 //No sw info from mesa compiler, so hard code here.
4831 pAsm->S[1].src.swizzlex = SQ_SEL_X;
4832 pAsm->S[1].src.swizzley = SQ_SEL_Y;
4833 pAsm->S[1].src.swizzlez = SQ_SEL_Z;
4834 pAsm->S[1].src.swizzlew = SQ_SEL_W;
4835
4836 if( GL_FALSE == tex_dst(pAsm) )
4837 {
4838 return GL_FALSE;
4839 }
4840
4841 if( GL_FALSE == tex_src(pAsm) )
4842 {
4843 return GL_FALSE;
4844 }
4845
4846 if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
4847 {
4848 /* hopefully did swizzles before */
4849 noswizzle_PVSSRC(&(pAsm->S[0].src));
4850 }
4851
4852 if(pAsm->pILInst[pAsm->uiCurInst].TexSrcTarget == TEXTURE_CUBE_INDEX)
4853 {
4854 /* SAMPLE dst, tmp.yxwy, CUBE */
4855 pAsm->S[0].src.swizzlex = SQ_SEL_Y;
4856 pAsm->S[0].src.swizzley = SQ_SEL_X;
4857 pAsm->S[0].src.swizzlez = SQ_SEL_W;
4858 pAsm->S[0].src.swizzlew = SQ_SEL_Y;
4859 }
4860
4861 if ( GL_FALSE == next_ins(pAsm) )
4862 {
4863 return GL_FALSE;
4864 }
4865
4866 return GL_TRUE;
4867 }
4868
4869 GLboolean assemble_XPD(r700_AssemblerBase *pAsm)
4870 {
4871 BITS tmp;
4872
4873 if( GL_FALSE == checkop2(pAsm) )
4874 {
4875 return GL_FALSE;
4876 }
4877
4878 tmp = gethelpr(pAsm);
4879
4880 pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
4881
4882 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4883 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4884 pAsm->D.dst.reg = tmp;
4885 nomask_PVSDST(&(pAsm->D.dst));
4886
4887 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4888 {
4889 return GL_FALSE;
4890 }
4891
4892 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4893 {
4894 return GL_FALSE;
4895 }
4896
4897 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Z, SQ_SEL_X, SQ_SEL_Y, SQ_SEL_0);
4898 swizzleagain_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Y, SQ_SEL_Z, SQ_SEL_X, SQ_SEL_0);
4899
4900 if( GL_FALSE == next_ins(pAsm) )
4901 {
4902 return GL_FALSE;
4903 }
4904
4905 pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
4906 pAsm->D.dst.op3 = 1;
4907
4908 if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask)
4909 {
4910 tmp = gethelpr(pAsm);
4911
4912 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
4913 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
4914 pAsm->D.dst.reg = tmp;
4915
4916 nomask_PVSDST(&(pAsm->D.dst));
4917 }
4918 else
4919 {
4920 if( GL_FALSE == assemble_dst(pAsm) )
4921 {
4922 return GL_FALSE;
4923 }
4924 }
4925
4926 if( GL_FALSE == assemble_src(pAsm, 0, -1) )
4927 {
4928 return GL_FALSE;
4929 }
4930
4931 if( GL_FALSE == assemble_src(pAsm, 1, -1) )
4932 {
4933 return GL_FALSE;
4934 }
4935
4936 swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Y, SQ_SEL_Z, SQ_SEL_X, SQ_SEL_0);
4937 swizzleagain_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Z, SQ_SEL_X, SQ_SEL_Y, SQ_SEL_0);
4938
4939 // result1 + (neg) result0
4940 setaddrmode_PVSSRC(&(pAsm->S[2].src),ADDR_ABSOLUTE);
4941 pAsm->S[2].src.rtype = SRC_REG_TEMPORARY;
4942 pAsm->S[2].src.reg = tmp;
4943
4944 neg_PVSSRC(&(pAsm->S[2].src));
4945 noswizzle_PVSSRC(&(pAsm->S[2].src));
4946
4947 if( GL_FALSE == next_ins(pAsm) )
4948 {
4949 return GL_FALSE;
4950 }
4951
4952
4953 if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask)
4954 {
4955 if( GL_FALSE == assemble_dst(pAsm) )
4956 {
4957 return GL_FALSE;
4958 }
4959
4960 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
4961
4962 // Use tmp as source
4963 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
4964 pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
4965 pAsm->S[0].src.reg = tmp;
4966
4967 noneg_PVSSRC(&(pAsm->S[0].src));
4968 noswizzle_PVSSRC(&(pAsm->S[0].src));
4969
4970 if( GL_FALSE == next_ins(pAsm) )
4971 {
4972 return GL_FALSE;
4973 }
4974 }
4975
4976 return GL_TRUE;
4977 }
4978
4979 GLboolean assemble_EXPORT(r700_AssemblerBase *pAsm)
4980 {
4981 return GL_TRUE;
4982 }
4983
4984 inline void checkStackDepth(r700_AssemblerBase *pAsm, GLuint uReason)
4985 {
4986 switch (uReason)
4987 {
4988 case FC_PUSH_VPM:
4989 break;
4990 case FC_PUSH_WQM:
4991 break;
4992 case FC_LOOP:
4993 break;
4994 case FC_REP:
4995 break;
4996 };
4997 }
4998
4999 GLboolean jumpToOffest(r700_AssemblerBase *pAsm, GLuint pops, GLint offset)
5000 {
5001 if(GL_FALSE == add_cf_instruction(pAsm) )
5002 {
5003 return GL_FALSE;
5004 }
5005
5006 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
5007 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5008 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5009
5010 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5011 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5012 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
5013 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5014
5015 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5016
5017 pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + offset;
5018
5019 return GL_TRUE;
5020 }
5021
5022 GLboolean pops(r700_AssemblerBase *pAsm, GLuint pops)
5023 {
5024 if(GL_FALSE == add_cf_instruction(pAsm) )
5025 {
5026 return GL_FALSE;
5027 }
5028
5029 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
5030 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5031 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5032
5033 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5034 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5035 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
5036
5037 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5038
5039 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5040 pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
5041
5042 return GL_TRUE;
5043 }
5044
5045 GLboolean assemble_IF(r700_AssemblerBase *pAsm, GLboolean bHasElse)
5046 {
5047 if(GL_FALSE == add_cf_instruction(pAsm) )
5048 {
5049 return GL_FALSE;
5050 }
5051
5052 if(GL_TRUE != bHasElse)
5053 {
5054 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5055 }
5056 else
5057 {
5058 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
5059 }
5060 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5061 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5062
5063 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5064 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5065 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
5066 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5067
5068 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5069
5070 pAsm->FCSP++;
5071 pAsm->fc_stack[pAsm->FCSP].type = FC_IF;
5072 pAsm->fc_stack[pAsm->FCSP].bpush = 0;
5073 pAsm->fc_stack[pAsm->FCSP].mid = NULL;
5074 pAsm->fc_stack[pAsm->FCSP].midLen= 0;
5075 pAsm->fc_stack[pAsm->FCSP].first = pAsm->cf_current_cf_clause_ptr;
5076
5077 #ifndef USE_CF_FOR_POP_AFTER
5078 if(GL_TRUE != bHasElse)
5079 {
5080 pAsm->alu_x_opcode = SQ_CF_INST_ALU_POP_AFTER;
5081 }
5082 #endif /* USE_CF_FOR_POP_AFTER */
5083
5084 pAsm->branch_depth++;
5085
5086 if(pAsm->branch_depth > pAsm->max_branch_depth)
5087 {
5088 pAsm->max_branch_depth = pAsm->branch_depth;
5089 }
5090 return GL_TRUE;
5091 }
5092
5093 GLboolean assemble_ELSE(r700_AssemblerBase *pAsm)
5094 {
5095 #ifdef USE_CF_FOR_POP_AFTER
5096 pops(pAsm, 1);
5097 #endif /* USE_CF_FOR_POP_AFTER */
5098
5099 if(GL_FALSE == add_cf_instruction(pAsm) )
5100 {
5101 return GL_FALSE;
5102 }
5103
5104 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; ///
5105 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5106 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5107
5108 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5109 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5110 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_ELSE;
5111 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5112
5113 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5114
5115 pAsm->fc_stack[pAsm->FCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( (void *)pAsm->fc_stack[pAsm->FCSP].mid,
5116 0,
5117 sizeof(R700ControlFlowGenericClause *) );
5118 pAsm->fc_stack[pAsm->FCSP].mid[0] = pAsm->cf_current_cf_clause_ptr;
5119 //pAsm->fc_stack[pAsm->FCSP].unNumMid = 1;
5120
5121 #ifndef USE_CF_FOR_POP_AFTER
5122 pAsm->alu_x_opcode = SQ_CF_INST_ALU_POP_AFTER;
5123 #endif /* USE_CF_FOR_POP_AFTER */
5124
5125 pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode - 1;
5126
5127 return GL_TRUE;
5128 }
5129
5130 GLboolean assemble_ENDIF(r700_AssemblerBase *pAsm)
5131 {
5132 #ifdef USE_CF_FOR_POP_AFTER
5133 pops(pAsm, 1);
5134 #endif /* USE_CF_FOR_POP_AFTER */
5135
5136 pAsm->alu_x_opcode = SQ_CF_INST_ALU;
5137
5138 if(NULL == pAsm->fc_stack[pAsm->FCSP].mid)
5139 {
5140 /* no else in between */
5141 pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode;
5142 }
5143 else
5144 {
5145 pAsm->fc_stack[pAsm->FCSP].mid[0]->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode;
5146 }
5147
5148 if(NULL != pAsm->fc_stack[pAsm->FCSP].mid)
5149 {
5150 FREE(pAsm->fc_stack[pAsm->FCSP].mid);
5151 }
5152
5153 if(pAsm->fc_stack[pAsm->FCSP].type != FC_IF)
5154 {
5155 radeon_error("if/endif in shader code are not paired. \n");
5156 return GL_FALSE;
5157 }
5158 pAsm->branch_depth--;
5159 pAsm->FCSP--;
5160
5161 return GL_TRUE;
5162 }
5163
5164 GLboolean assemble_BGNLOOP(r700_AssemblerBase *pAsm)
5165 {
5166 if(GL_FALSE == add_cf_instruction(pAsm) )
5167 {
5168 return GL_FALSE;
5169 }
5170
5171
5172 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
5173 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5174 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5175
5176 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5177 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5178 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_START_NO_AL;
5179 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5180
5181 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5182
5183 pAsm->FCSP++;
5184 pAsm->fc_stack[pAsm->FCSP].type = FC_LOOP;
5185 pAsm->fc_stack[pAsm->FCSP].bpush = 1;
5186 pAsm->fc_stack[pAsm->FCSP].mid = NULL;
5187 pAsm->fc_stack[pAsm->FCSP].unNumMid = 0;
5188 pAsm->fc_stack[pAsm->FCSP].midLen = 0;
5189 pAsm->fc_stack[pAsm->FCSP].first = pAsm->cf_current_cf_clause_ptr;
5190
5191 pAsm->branch_depth++;
5192
5193 if(pAsm->branch_depth > pAsm->max_branch_depth)
5194 {
5195 pAsm->max_branch_depth = pAsm->branch_depth;
5196 }
5197 return GL_TRUE;
5198 }
5199
5200 GLboolean assemble_BRK(r700_AssemblerBase *pAsm)
5201 {
5202 #ifdef USE_CF_FOR_CONTINUE_BREAK
5203 unsigned int unFCSP;
5204 for(unFCSP=pAsm->FCSP; unFCSP>0; unFCSP--)
5205 {
5206 if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
5207 {
5208 break;
5209 }
5210 }
5211 if(0 == FC_LOOP)
5212 {
5213 radeon_error("Break is not inside loop/endloop pair.\n");
5214 return GL_FALSE;
5215 }
5216
5217 if(GL_FALSE == add_cf_instruction(pAsm) )
5218 {
5219 return GL_FALSE;
5220 }
5221
5222
5223 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5224 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5225 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5226
5227 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5228 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5229 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
5230
5231 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5232
5233 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5234
5235 pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
5236 (void *)pAsm->fc_stack[unFCSP].mid,
5237 sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
5238 sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
5239 pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
5240 pAsm->fc_stack[unFCSP].unNumMid++;
5241
5242 if(GL_FALSE == add_cf_instruction(pAsm) )
5243 {
5244 return GL_FALSE;
5245 }
5246
5247 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5248 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5249 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5250
5251 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5252 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5253 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
5254
5255 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5256
5257 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5258 pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
5259
5260 #endif //USE_CF_FOR_CONTINUE_BREAK
5261 return GL_TRUE;
5262 }
5263
5264 GLboolean assemble_CONT(r700_AssemblerBase *pAsm)
5265 {
5266 #ifdef USE_CF_FOR_CONTINUE_BREAK
5267 unsigned int unFCSP;
5268 for(unFCSP=pAsm->FCSP; unFCSP>0; unFCSP--)
5269 {
5270 if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
5271 {
5272 break;
5273 }
5274 }
5275 if(0 == FC_LOOP)
5276 {
5277 radeon_error("Continue is not inside loop/endloop pair.\n");
5278 return GL_FALSE;
5279 }
5280
5281 if(GL_FALSE == add_cf_instruction(pAsm) )
5282 {
5283 return GL_FALSE;
5284 }
5285
5286
5287 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5288 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5289 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5290
5291 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5292 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5293 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_CONTINUE;
5294
5295 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5296
5297 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5298
5299 pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
5300 (void *)pAsm->fc_stack[unFCSP].mid,
5301 sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
5302 sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
5303 pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
5304 pAsm->fc_stack[unFCSP].unNumMid++;
5305
5306 if(GL_FALSE == add_cf_instruction(pAsm) )
5307 {
5308 return GL_FALSE;
5309 }
5310
5311 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5312 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5313 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5314
5315 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5316 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5317 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
5318
5319 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5320
5321 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5322 pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
5323
5324 #endif /* USE_CF_FOR_CONTINUE_BREAK */
5325
5326 return GL_TRUE;
5327 }
5328
5329 GLboolean assemble_ENDLOOP(r700_AssemblerBase *pAsm)
5330 {
5331 GLuint i;
5332
5333 if(GL_FALSE == add_cf_instruction(pAsm) )
5334 {
5335 return GL_FALSE;
5336 }
5337
5338
5339 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
5340 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5341 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5342
5343 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5344 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5345 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_END;
5346 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5347
5348 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5349
5350 pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->fc_stack[pAsm->FCSP].first->m_uIndex + 1;
5351 pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
5352
5353 #ifdef USE_CF_FOR_CONTINUE_BREAK
5354 for(i=0; i<pAsm->fc_stack[pAsm->FCSP].unNumMid; i++)
5355 {
5356 pAsm->fc_stack[pAsm->FCSP].mid[i]->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex;
5357 }
5358 if(NULL != pAsm->fc_stack[pAsm->FCSP].mid)
5359 {
5360 FREE(pAsm->fc_stack[pAsm->FCSP].mid);
5361 }
5362 #endif
5363
5364 if(pAsm->fc_stack[pAsm->FCSP].type != FC_LOOP)
5365 {
5366 radeon_error("loop/endloop in shader code are not paired. \n");
5367 return GL_FALSE;
5368 }
5369
5370 unsigned int unFCSP = 0;
5371 if((pAsm->unCFflags & HAS_CURRENT_LOOPRET) > 0)
5372 {
5373 for(unFCSP=(pAsm->FCSP-1); unFCSP>pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry; unFCSP--)
5374 {
5375 if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
5376 {
5377 break;
5378 }
5379 }
5380 if(unFCSP <= pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry)
5381 {
5382 unFCSP = 0;
5383
5384 returnOnFlag(pAsm);
5385 pAsm->unCFflags &= ~HAS_CURRENT_LOOPRET;
5386 }
5387 }
5388
5389 pAsm->branch_depth--;
5390 pAsm->FCSP--;
5391
5392 if(unFCSP > 0)
5393 {
5394 breakLoopOnFlag(pAsm, unFCSP);
5395 }
5396
5397 return GL_TRUE;
5398 }
5399
5400 void add_return_inst(r700_AssemblerBase *pAsm)
5401 {
5402 if(GL_FALSE == add_cf_instruction(pAsm) )
5403 {
5404 return GL_FALSE;
5405 }
5406 //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5407 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
5408 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5409 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5410
5411 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5412 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5413 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_RETURN;
5414 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5415
5416 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5417 }
5418
5419 GLboolean assemble_BGNSUB(r700_AssemblerBase *pAsm, GLint nILindex)
5420 {
5421 /* Put in sub */
5422 if( (pAsm->unSubArrayPointer + 1) > pAsm->unSubArraySize )
5423 {
5424 pAsm->subs = (SUB_OFFSET*)_mesa_realloc( (void *)pAsm->subs,
5425 sizeof(SUB_OFFSET) * pAsm->unSubArraySize,
5426 sizeof(SUB_OFFSET) * (pAsm->unSubArraySize + 10) );
5427 if(NULL == pAsm->subs)
5428 {
5429 return GL_FALSE;
5430 }
5431 pAsm->unSubArraySize += 10;
5432 }
5433
5434 pAsm->subs[pAsm->unSubArrayPointer].subIL_Offset = nILindex;
5435 pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.pHead=NULL;
5436 pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.pTail=NULL;
5437 pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.uNumOfNode=0;
5438
5439 pAsm->CALLSP++;
5440 pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry = pAsm->FCSP;
5441 pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local
5442 = &(pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local);
5443 pAsm->CALLSTACK[pAsm->CALLSP].stackUsage.bits = 0;
5444 SetActiveCFlist(pAsm->pR700Shader,
5445 pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local);
5446
5447 pAsm->unSubArrayPointer++;
5448
5449 /* start sub */
5450 pAsm->alu_x_opcode = SQ_CF_INST_ALU;
5451
5452 return GL_TRUE;
5453 }
5454
5455 GLboolean assemble_ENDSUB(r700_AssemblerBase *pAsm)
5456 {
5457 pAsm->CALLSP--;
5458 SetActiveCFlist(pAsm->pR700Shader,
5459 pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local);
5460
5461 pAsm->alu_x_opcode = SQ_CF_INST_ALU;
5462
5463 return GL_TRUE;
5464 }
5465
5466 GLboolean assemble_RET(r700_AssemblerBase *pAsm)
5467 {
5468 if(pAsm->CALLSP > 0)
5469 { /* in sub */
5470 unsigned int unFCSP;
5471 for(unFCSP=pAsm->FCSP; unFCSP>pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry; unFCSP--)
5472 {
5473 if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
5474 {
5475 setRetInLoopFlag(pAsm, SQ_SEL_1);
5476 breakLoopOnFlag(pAsm, unFCSP);
5477 pAsm->unCFflags |= LOOPRET_FLAGS;
5478
5479 return GL_TRUE;
5480 }
5481 }
5482 }
5483
5484 add_return_inst(pAsm);
5485
5486 return GL_TRUE;
5487 }
5488
5489 GLboolean assemble_CAL(r700_AssemblerBase *pAsm,
5490 GLint nILindex,
5491 GLuint uiNumberInsts,
5492 struct prog_instruction *pILInst)
5493 {
5494 pAsm->alu_x_opcode = SQ_CF_INST_ALU;
5495
5496 if(GL_FALSE == add_cf_instruction(pAsm) )
5497 {
5498 return GL_FALSE;
5499 }
5500
5501 pAsm->cf_current_cf_clause_ptr->m_Word1.f.call_count = 1;
5502 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
5503 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5504 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5505
5506 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5507 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5508 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_CALL;
5509 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5510
5511 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5512
5513 /* Put in caller */
5514 if( (pAsm->unCallerArrayPointer + 1) > pAsm->unCallerArraySize )
5515 {
5516 pAsm->callers = (CALLER_POINTER*)_mesa_realloc( (void *)pAsm->callers,
5517 sizeof(CALLER_POINTER) * pAsm->unCallerArraySize,
5518 sizeof(CALLER_POINTER) * (pAsm->unCallerArraySize + 10) );
5519 if(NULL == pAsm->callers)
5520 {
5521 return GL_FALSE;
5522 }
5523 pAsm->unCallerArraySize += 10;
5524 }
5525
5526 pAsm->callers[pAsm->unCallerArrayPointer].subIL_Offset = nILindex;
5527 pAsm->callers[pAsm->unCallerArrayPointer].cf_ptr = pAsm->cf_current_cf_clause_ptr;
5528
5529 pAsm->unCallerArrayPointer++;
5530
5531 int j;
5532 for(j=0; j<pAsm->unSubArrayPointer; j++)
5533 {
5534 if(nILindex == pAsm->subs[j].subIL_Offset)
5535 { /* compiled before */
5536 pAsm->callers[pAsm->unCallerArrayPointer - 1].subDescIndex = j;
5537 return GL_TRUE;
5538 }
5539 }
5540
5541 pAsm->callers[pAsm->unCallerArrayPointer - 1].subDescIndex = pAsm->unSubArrayPointer;
5542
5543 return AssembleInstr(nILindex, uiNumberInsts, pILInst, pAsm);
5544 }
5545
5546 GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue)
5547 {
5548 GLfloat fLiteral[2] = {0.1, 0.0};
5549
5550 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
5551 pAsm->D.dst.op3 = 0;
5552 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
5553 pAsm->D.dst.reg = pAsm->flag_reg_index;
5554 pAsm->D.dst.writex = 1;
5555 pAsm->D.dst.writey = 0;
5556 pAsm->D.dst.writez = 0;
5557 pAsm->D.dst.writew = 0;
5558 pAsm->D2.dst2.literal = 1;
5559 pAsm->D2.dst2.SaturateMode = SATURATE_OFF;
5560 pAsm->D.dst.predicated = 0;
5561 #if 0
5562 pAsm->S[0].src.rtype = SRC_REC_LITERAL;
5563 //pAsm->S[0].src.reg = 0;
5564 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
5565 noneg_PVSSRC(&(pAsm->S[0].src));
5566 pAsm->S[0].src.swizzlex = SQ_SEL_X;
5567 pAsm->S[0].src.swizzley = SQ_SEL_Y;
5568 pAsm->S[0].src.swizzlez = SQ_SEL_Z;
5569 pAsm->S[0].src.swizzlew = SQ_SEL_W;
5570
5571 if( GL_FALSE == next_ins_literal(pAsm, &(fLiteral[0])) )
5572 {
5573 return GL_FALSE;
5574 }
5575 #else
5576 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
5577 pAsm->S[0].src.reg = 0;
5578 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
5579 noneg_PVSSRC(&(pAsm->S[0].src));
5580 pAsm->S[0].src.swizzlex = flagValue;
5581 pAsm->S[0].src.swizzley = flagValue;
5582 pAsm->S[0].src.swizzlez = flagValue;
5583 pAsm->S[0].src.swizzlew = flagValue;
5584
5585 if( GL_FALSE == next_ins2(pAsm) )
5586 {
5587 return GL_FALSE;
5588 }
5589 #endif
5590
5591 return GL_TRUE;
5592 }
5593
5594 GLboolean testFlag(r700_AssemblerBase *pAsm)
5595 {
5596 GLfloat fLiteral[2] = {0.1, 0.0};
5597
5598 //Test flag
5599 GLuint tmp = gethelpr(pAsm);
5600 pAsm->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5601
5602 pAsm->D.dst.opcode = SQ_OP2_INST_PRED_SETE;
5603 pAsm->D.dst.math = 1;
5604 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
5605 pAsm->D.dst.reg = tmp;
5606 pAsm->D.dst.writex = 1;
5607 pAsm->D.dst.writey = 0;
5608 pAsm->D.dst.writez = 0;
5609 pAsm->D.dst.writew = 0;
5610 pAsm->D2.dst2.literal = 1;
5611 pAsm->D2.dst2.SaturateMode = SATURATE_OFF;
5612 pAsm->D.dst.predicated = 1;
5613
5614 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
5615 pAsm->S[0].src.reg = pAsm->flag_reg_index;
5616 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
5617 noneg_PVSSRC(&(pAsm->S[0].src));
5618 pAsm->S[0].src.swizzlex = SQ_SEL_X;
5619 pAsm->S[0].src.swizzley = SQ_SEL_Y;
5620 pAsm->S[0].src.swizzlez = SQ_SEL_Z;
5621 pAsm->S[0].src.swizzlew = SQ_SEL_W;
5622 #if 0
5623 pAsm->S[1].src.rtype = SRC_REC_LITERAL;
5624 //pAsm->S[1].src.reg = 0;
5625 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
5626 noneg_PVSSRC(&(pAsm->S[1].src));
5627 pAsm->S[1].src.swizzlex = SQ_SEL_X;
5628 pAsm->S[1].src.swizzley = SQ_SEL_Y;
5629 pAsm->S[1].src.swizzlez = SQ_SEL_Z;
5630 pAsm->S[1].src.swizzlew = SQ_SEL_W;
5631
5632 if( GL_FALSE == next_ins_literal(pAsm, &(fLiteral[0])) )
5633 {
5634 return GL_FALSE;
5635 }
5636 #else
5637 pAsm->S[1].src.rtype = DST_REG_TEMPORARY;
5638 pAsm->S[1].src.reg = 0;
5639 setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
5640 noneg_PVSSRC(&(pAsm->S[1].src));
5641 pAsm->S[1].src.swizzlex = SQ_SEL_1;
5642 pAsm->S[1].src.swizzley = SQ_SEL_1;
5643 pAsm->S[1].src.swizzlez = SQ_SEL_1;
5644 pAsm->S[1].src.swizzlew = SQ_SEL_1;
5645
5646 if( GL_FALSE == next_ins2(pAsm) )
5647 {
5648 return GL_FALSE;
5649 }
5650 #endif
5651
5652 return GL_TRUE;
5653 }
5654
5655 GLboolean returnOnFlag(r700_AssemblerBase *pAsm)
5656 {
5657 testFlag(pAsm);
5658 jumpToOffest(pAsm, 1, 4);
5659 setRetInLoopFlag(pAsm, SQ_SEL_0);
5660 pops(pAsm, 1);
5661 add_return_inst(pAsm);
5662
5663 return GL_TRUE;
5664 }
5665
5666 GLboolean breakLoopOnFlag(r700_AssemblerBase *pAsm, GLuint unFCSP)
5667 {
5668 testFlag(pAsm);
5669
5670 //break
5671 if(GL_FALSE == add_cf_instruction(pAsm) )
5672 {
5673 return GL_FALSE;
5674 }
5675
5676 pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
5677 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
5678 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
5679
5680 pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
5681 pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
5682 pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
5683 pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
5684
5685 pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
5686
5687 pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
5688 (void *)pAsm->fc_stack[unFCSP].mid,
5689 sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
5690 sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
5691 pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
5692 pAsm->fc_stack[unFCSP].unNumMid++;
5693
5694 pops(pAsm, 1);
5695
5696 return GL_TRUE;
5697 }
5698
5699 GLboolean AssembleInstr(GLuint uiFirstInst,
5700 GLuint uiNumberInsts,
5701 struct prog_instruction *pILInst,
5702 r700_AssemblerBase *pR700AsmCode)
5703 {
5704 GLuint i;
5705
5706 pR700AsmCode->pILInst = pILInst;
5707 for(i=uiFirstInst; i<uiNumberInsts; i++)
5708 {
5709 pR700AsmCode->uiCurInst = i;
5710
5711 #ifndef USE_CF_FOR_CONTINUE_BREAK
5712 if(OPCODE_BRK == pILInst[i+1].Opcode)
5713 {
5714 switch(pILInst[i].Opcode)
5715 {
5716 case OPCODE_SLE:
5717 pILInst[i].Opcode = OPCODE_SGT;
5718 break;
5719 case OPCODE_SLT:
5720 pILInst[i].Opcode = OPCODE_SGE;
5721 break;
5722 case OPCODE_SGE:
5723 pILInst[i].Opcode = OPCODE_SLT;
5724 break;
5725 case OPCODE_SGT:
5726 pILInst[i].Opcode = OPCODE_SLE;
5727 break;
5728 case OPCODE_SEQ:
5729 pILInst[i].Opcode = OPCODE_SNE;
5730 break;
5731 case OPCODE_SNE:
5732 pILInst[i].Opcode = OPCODE_SEQ;
5733 break;
5734 default:
5735 break;
5736 }
5737 }
5738 #endif
5739
5740 switch (pILInst[i].Opcode)
5741 {
5742 case OPCODE_ABS:
5743 if ( GL_FALSE == assemble_ABS(pR700AsmCode) )
5744 return GL_FALSE;
5745 break;
5746 case OPCODE_ADD:
5747 case OPCODE_SUB:
5748 if ( GL_FALSE == assemble_ADD(pR700AsmCode) )
5749 return GL_FALSE;
5750 break;
5751
5752 case OPCODE_ARL:
5753 if ( GL_FALSE == assemble_ARL(pR700AsmCode) )
5754 return GL_FALSE;
5755 break;
5756 case OPCODE_ARR:
5757 radeon_error("Not yet implemented instruction OPCODE_ARR \n");
5758 //if ( GL_FALSE == assemble_BAD("ARR") )
5759 return GL_FALSE;
5760 break;
5761
5762 case OPCODE_CMP:
5763 if ( GL_FALSE == assemble_CMP(pR700AsmCode) )
5764 return GL_FALSE;
5765 break;
5766 case OPCODE_COS:
5767 if ( GL_FALSE == assemble_COS(pR700AsmCode) )
5768 return GL_FALSE;
5769 break;
5770
5771 case OPCODE_DP3:
5772 case OPCODE_DP4:
5773 case OPCODE_DPH:
5774 if ( GL_FALSE == assemble_DOT(pR700AsmCode) )
5775 return GL_FALSE;
5776 break;
5777
5778 case OPCODE_DST:
5779 if ( GL_FALSE == assemble_DST(pR700AsmCode) )
5780 return GL_FALSE;
5781 break;
5782
5783 case OPCODE_EX2:
5784 if ( GL_FALSE == assemble_EX2(pR700AsmCode) )
5785 return GL_FALSE;
5786 break;
5787 case OPCODE_EXP:
5788 if ( GL_FALSE == assemble_EXP(pR700AsmCode) )
5789 return GL_FALSE;
5790 break;
5791
5792 case OPCODE_FLR:
5793 if ( GL_FALSE == assemble_FLR(pR700AsmCode) )
5794 return GL_FALSE;
5795 break;
5796 //case OP_FLR_INT:
5797 // if ( GL_FALSE == assemble_FLR_INT() )
5798 // return GL_FALSE;
5799 // break;
5800
5801 case OPCODE_FRC:
5802 if ( GL_FALSE == assemble_FRC(pR700AsmCode) )
5803 return GL_FALSE;
5804 break;
5805
5806 case OPCODE_KIL:
5807 if ( GL_FALSE == assemble_KIL(pR700AsmCode) )
5808 return GL_FALSE;
5809 break;
5810 case OPCODE_LG2:
5811 if ( GL_FALSE == assemble_LG2(pR700AsmCode) )
5812 return GL_FALSE;
5813 break;
5814 case OPCODE_LIT:
5815 if ( GL_FALSE == assemble_LIT(pR700AsmCode) )
5816 return GL_FALSE;
5817 break;
5818 case OPCODE_LRP:
5819 if ( GL_FALSE == assemble_LRP(pR700AsmCode) )
5820 return GL_FALSE;
5821 break;
5822 case OPCODE_LOG:
5823 if ( GL_FALSE == assemble_LOG(pR700AsmCode) )
5824 return GL_FALSE;
5825 break;
5826
5827 case OPCODE_MAD:
5828 if ( GL_FALSE == assemble_MAD(pR700AsmCode) )
5829 return GL_FALSE;
5830 break;
5831 case OPCODE_MAX:
5832 if ( GL_FALSE == assemble_MAX(pR700AsmCode) )
5833 return GL_FALSE;
5834 break;
5835 case OPCODE_MIN:
5836 if ( GL_FALSE == assemble_MIN(pR700AsmCode) )
5837 return GL_FALSE;
5838 break;
5839
5840 case OPCODE_MOV:
5841 if ( GL_FALSE == assemble_MOV(pR700AsmCode) )
5842 return GL_FALSE;
5843 break;
5844 case OPCODE_MUL:
5845 if ( GL_FALSE == assemble_MUL(pR700AsmCode) )
5846 return GL_FALSE;
5847 break;
5848
5849 case OPCODE_POW:
5850 if ( GL_FALSE == assemble_POW(pR700AsmCode) )
5851 return GL_FALSE;
5852 break;
5853 case OPCODE_RCP:
5854 if ( GL_FALSE == assemble_RCP(pR700AsmCode) )
5855 return GL_FALSE;
5856 break;
5857 case OPCODE_RSQ:
5858 if ( GL_FALSE == assemble_RSQ(pR700AsmCode) )
5859 return GL_FALSE;
5860 break;
5861 case OPCODE_SIN:
5862 if ( GL_FALSE == assemble_SIN(pR700AsmCode) )
5863 return GL_FALSE;
5864 break;
5865 case OPCODE_SCS:
5866 if ( GL_FALSE == assemble_SCS(pR700AsmCode) )
5867 return GL_FALSE;
5868 break;
5869
5870 case OPCODE_SEQ:
5871 if(OPCODE_IF == pILInst[i+1].Opcode)
5872 {
5873 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5874 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETE) )
5875 {
5876 return GL_FALSE;
5877 }
5878 }
5879 else if(OPCODE_BRK == pILInst[i+1].Opcode)
5880 {
5881 #ifdef USE_CF_FOR_CONTINUE_BREAK
5882 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5883 #else
5884 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
5885 #endif
5886 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETE) )
5887 {
5888 return GL_FALSE;
5889 }
5890 }
5891 else if(OPCODE_CONT == pILInst[i+1].Opcode)
5892 {
5893 #ifdef USE_CF_FOR_CONTINUE_BREAK
5894 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5895 #else
5896 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
5897 #endif
5898 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETE) )
5899 {
5900 return GL_FALSE;
5901 }
5902 }
5903 else
5904 {
5905 if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETE) )
5906 {
5907 return GL_FALSE;
5908 }
5909 }
5910 break;
5911
5912 case OPCODE_SGT:
5913 if(OPCODE_IF == pILInst[i+1].Opcode)
5914 {
5915 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5916 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
5917 {
5918 return GL_FALSE;
5919 }
5920 }
5921 else if(OPCODE_BRK == pILInst[i+1].Opcode)
5922 {
5923 #ifdef USE_CF_FOR_CONTINUE_BREAK
5924 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5925 #else
5926 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
5927 #endif
5928 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
5929 {
5930 return GL_FALSE;
5931 }
5932 }
5933 else if(OPCODE_CONT == pILInst[i+1].Opcode)
5934 {
5935 #ifdef USE_CF_FOR_CONTINUE_BREAK
5936 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5937 #else
5938 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
5939 #endif
5940
5941 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
5942 {
5943 return GL_FALSE;
5944 }
5945 }
5946 else
5947 {
5948 if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGT) )
5949 {
5950 return GL_FALSE;
5951 }
5952 }
5953 break;
5954
5955 case OPCODE_SGE:
5956 if(OPCODE_IF == pILInst[i+1].Opcode)
5957 {
5958 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5959 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
5960 {
5961 return GL_FALSE;
5962 }
5963 }
5964 else if(OPCODE_BRK == pILInst[i+1].Opcode)
5965 {
5966 #ifdef USE_CF_FOR_CONTINUE_BREAK
5967 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5968 #else
5969 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
5970 #endif
5971 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
5972 {
5973 return GL_FALSE;
5974 }
5975 }
5976 else if(OPCODE_CONT == pILInst[i+1].Opcode)
5977 {
5978 #ifdef USE_CF_FOR_CONTINUE_BREAK
5979 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
5980 #else
5981 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
5982 #endif
5983
5984 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
5985 {
5986 return GL_FALSE;
5987 }
5988 }
5989 else
5990 {
5991 if ( GL_FALSE == assemble_SGE(pR700AsmCode) )
5992 {
5993 return GL_FALSE;
5994 }
5995 }
5996 break;
5997
5998 /* NO LT, LE, TODO : use GE => LE, GT => LT : reverse 2 src order would be simpliest. Or use SQ_CF_COND_FALSE for SQ_CF_COND_ACTIVE.*/
5999 case OPCODE_SLT:
6000 {
6001 struct prog_src_register SrcRegSave[2];
6002 SrcRegSave[0] = pILInst[i].SrcReg[0];
6003 SrcRegSave[1] = pILInst[i].SrcReg[1];
6004 pILInst[i].SrcReg[0] = SrcRegSave[1];
6005 pILInst[i].SrcReg[1] = SrcRegSave[0];
6006 if(OPCODE_IF == pILInst[i+1].Opcode)
6007 {
6008 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6009 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
6010 {
6011 pILInst[i].SrcReg[0] = SrcRegSave[0];
6012 pILInst[i].SrcReg[1] = SrcRegSave[1];
6013 return GL_FALSE;
6014 }
6015 }
6016 else if(OPCODE_BRK == pILInst[i+1].Opcode)
6017 {
6018 #ifdef USE_CF_FOR_CONTINUE_BREAK
6019 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6020 #else
6021 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
6022 #endif
6023 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
6024 {
6025 pILInst[i].SrcReg[0] = SrcRegSave[0];
6026 pILInst[i].SrcReg[1] = SrcRegSave[1];
6027 return GL_FALSE;
6028 }
6029 }
6030 else if(OPCODE_CONT == pILInst[i+1].Opcode)
6031 {
6032 #ifdef USE_CF_FOR_CONTINUE_BREAK
6033 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6034 #else
6035 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
6036 #endif
6037
6038 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGT) )
6039 {
6040 pILInst[i].SrcReg[0] = SrcRegSave[0];
6041 pILInst[i].SrcReg[1] = SrcRegSave[1];
6042 return GL_FALSE;
6043 }
6044 }
6045 else
6046 {
6047 if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGT) )
6048 {
6049 pILInst[i].SrcReg[0] = SrcRegSave[0];
6050 pILInst[i].SrcReg[1] = SrcRegSave[1];
6051 return GL_FALSE;
6052 }
6053 }
6054 pILInst[i].SrcReg[0] = SrcRegSave[0];
6055 pILInst[i].SrcReg[1] = SrcRegSave[1];
6056 }
6057 break;
6058
6059 case OPCODE_SLE:
6060 {
6061 struct prog_src_register SrcRegSave[2];
6062 SrcRegSave[0] = pILInst[i].SrcReg[0];
6063 SrcRegSave[1] = pILInst[i].SrcReg[1];
6064 pILInst[i].SrcReg[0] = SrcRegSave[1];
6065 pILInst[i].SrcReg[1] = SrcRegSave[0];
6066 if(OPCODE_IF == pILInst[i+1].Opcode)
6067 {
6068 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6069 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
6070 {
6071 pILInst[i].SrcReg[0] = SrcRegSave[0];
6072 pILInst[i].SrcReg[1] = SrcRegSave[1];
6073 return GL_FALSE;
6074 }
6075 }
6076 else if(OPCODE_BRK == pILInst[i+1].Opcode)
6077 {
6078 #ifdef USE_CF_FOR_CONTINUE_BREAK
6079 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6080 #else
6081 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
6082 #endif
6083 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
6084 {
6085 pILInst[i].SrcReg[0] = SrcRegSave[0];
6086 pILInst[i].SrcReg[1] = SrcRegSave[1];
6087 return GL_FALSE;
6088 }
6089 }
6090 else if(OPCODE_CONT == pILInst[i+1].Opcode)
6091 {
6092 #ifdef USE_CF_FOR_CONTINUE_BREAK
6093 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6094 #else
6095 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
6096 #endif
6097
6098 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETGE) )
6099 {
6100 pILInst[i].SrcReg[0] = SrcRegSave[0];
6101 pILInst[i].SrcReg[1] = SrcRegSave[1];
6102 return GL_FALSE;
6103 }
6104 }
6105 else
6106 {
6107 if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGE) )
6108 {
6109 pILInst[i].SrcReg[0] = SrcRegSave[0];
6110 pILInst[i].SrcReg[1] = SrcRegSave[1];
6111 return GL_FALSE;
6112 }
6113 }
6114 pILInst[i].SrcReg[0] = SrcRegSave[0];
6115 pILInst[i].SrcReg[1] = SrcRegSave[1];
6116 }
6117 break;
6118
6119 case OPCODE_SNE:
6120 if(OPCODE_IF == pILInst[i+1].Opcode)
6121 {
6122 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6123 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETNE) )
6124 {
6125 return GL_FALSE;
6126 }
6127 }
6128 else if(OPCODE_BRK == pILInst[i+1].Opcode)
6129 {
6130 #ifdef USE_CF_FOR_CONTINUE_BREAK
6131 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6132 #else
6133 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_BREAK;
6134 #endif
6135 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETNE) )
6136 {
6137 return GL_FALSE;
6138 }
6139 }
6140 else if(OPCODE_CONT == pILInst[i+1].Opcode)
6141 {
6142 #ifdef USE_CF_FOR_CONTINUE_BREAK
6143 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
6144 #else
6145 pR700AsmCode->alu_x_opcode = SQ_CF_INST_ALU_CONTINUE;
6146 #endif
6147 if ( GL_FALSE == assemble_LOGIC_PRED(pR700AsmCode, SQ_OP2_INST_PRED_SETNE) )
6148 {
6149 return GL_FALSE;
6150 }
6151 }
6152 else
6153 {
6154 if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETNE) )
6155 {
6156 return GL_FALSE;
6157 }
6158 }
6159 break;
6160
6161 //case OP_STP:
6162 // if ( GL_FALSE == assemble_STP(pR700AsmCode) )
6163 // return GL_FALSE;
6164 // break;
6165
6166 case OPCODE_SWZ:
6167 if ( GL_FALSE == assemble_MOV(pR700AsmCode) )
6168 {
6169 return GL_FALSE;
6170 }
6171 else
6172 {
6173 if( (i+1)<uiNumberInsts )
6174 {
6175 if(OPCODE_END != pILInst[i+1].Opcode)
6176 {
6177 if( GL_TRUE == IsTex(pILInst[i+1].Opcode) )
6178 {
6179 pR700AsmCode->pInstDeps[i+1].nDstDep = i+1; //=1?
6180 }
6181 }
6182 }
6183 }
6184 break;
6185
6186 case OPCODE_TEX:
6187 case OPCODE_TXB:
6188 case OPCODE_TXP:
6189 if ( GL_FALSE == assemble_TEX(pR700AsmCode) )
6190 return GL_FALSE;
6191 break;
6192
6193 case OPCODE_XPD:
6194 if ( GL_FALSE == assemble_XPD(pR700AsmCode) )
6195 return GL_FALSE;
6196 break;
6197
6198 case OPCODE_IF :
6199 {
6200 GLboolean bHasElse = GL_FALSE;
6201
6202 if(pILInst[pILInst[i].BranchTarget - 1].Opcode == OPCODE_ELSE)
6203 {
6204 bHasElse = GL_TRUE;
6205 }
6206
6207 if ( GL_FALSE == assemble_IF(pR700AsmCode, bHasElse) )
6208 {
6209 return GL_FALSE;
6210 }
6211 }
6212 break;
6213
6214 case OPCODE_ELSE :
6215 if ( GL_FALSE == assemble_ELSE(pR700AsmCode) )
6216 return GL_FALSE;
6217 break;
6218
6219 case OPCODE_ENDIF:
6220 if ( GL_FALSE == assemble_ENDIF(pR700AsmCode) )
6221 return GL_FALSE;
6222 break;
6223
6224 case OPCODE_BGNLOOP:
6225 if( GL_FALSE == assemble_BGNLOOP(pR700AsmCode) )
6226 {
6227 return GL_FALSE;
6228 }
6229 break;
6230
6231 case OPCODE_BRK:
6232 if( GL_FALSE == assemble_BRK(pR700AsmCode) )
6233 {
6234 return GL_FALSE;
6235 }
6236 break;
6237
6238 case OPCODE_CONT:
6239 if( GL_FALSE == assemble_CONT(pR700AsmCode) )
6240 {
6241 return GL_FALSE;
6242 }
6243 break;
6244
6245 case OPCODE_ENDLOOP:
6246 if( GL_FALSE == assemble_ENDLOOP(pR700AsmCode) )
6247 {
6248 return GL_FALSE;
6249 }
6250 break;
6251
6252 case OPCODE_BGNSUB:
6253 if( GL_FALSE == assemble_BGNSUB(pR700AsmCode, i) )
6254 {
6255 return GL_FALSE;
6256 }
6257 break;
6258
6259 case OPCODE_RET:
6260 if( GL_FALSE == assemble_RET(pR700AsmCode) )
6261 {
6262 return GL_FALSE;
6263 }
6264 break;
6265
6266 case OPCODE_CAL:
6267 if( GL_FALSE == assemble_CAL(pR700AsmCode,
6268 pILInst[i].BranchTarget,
6269 uiNumberInsts,
6270 pILInst) )
6271 {
6272 return GL_FALSE;
6273 }
6274 break;
6275
6276 //case OPCODE_EXPORT:
6277 // if ( GL_FALSE == assemble_EXPORT() )
6278 // return GL_FALSE;
6279 // break;
6280
6281 case OPCODE_ENDSUB:
6282 return assemble_ENDSUB(pR700AsmCode);
6283
6284 case OPCODE_END:
6285 //pR700AsmCode->uiCurInst = i;
6286 //This is to remaind that if in later exoort there is depth/stencil
6287 //export, we need a mov to re-arrange DST channel, where using a
6288 //psuedo inst, we will use this end inst to do it.
6289 return GL_TRUE;
6290
6291 default:
6292 radeon_error("internal: unknown instruction\n");
6293 return GL_FALSE;
6294 }
6295 }
6296
6297 return GL_TRUE;
6298 }
6299
6300 GLboolean InitShaderProgram(r700_AssemblerBase * pAsm)
6301 {
6302 setRetInLoopFlag(pAsm, SQ_SEL_0);
6303 return GL_TRUE;
6304 }
6305
6306 GLboolean RelocProgram(r700_AssemblerBase * pAsm)
6307 {
6308 GLuint i;
6309 GLuint unCFoffset;
6310 TypedShaderList * plstCFmain;
6311 TypedShaderList * plstCFsub;
6312
6313 R700ShaderInstruction * pInst;
6314 R700ControlFlowGenericClause * pCFInst;
6315
6316 if(0 == pAsm->unSubArrayPointer)
6317 {
6318 return GL_TRUE;
6319 }
6320
6321 plstCFmain = pAsm->CALLSTACK[0].plstCFInstructions_local;
6322 unCFoffset = plstCFmain->uNumOfNode;
6323
6324 /* Reloc subs */
6325 for(i=0; i<pAsm->unSubArrayPointer; i++)
6326 {
6327 pAsm->subs[i].unCFoffset = unCFoffset;
6328 plstCFsub = &(pAsm->subs[i].lstCFInstructions_local);
6329
6330 pInst = plstCFsub->pHead;
6331
6332 /* reloc instructions */
6333 while(pInst)
6334 {
6335 if(SIT_CF_GENERIC == pInst->m_ShaderInstType)
6336 {
6337 pCFInst = (R700ControlFlowGenericClause *)pInst;
6338
6339 switch (pCFInst->m_Word1.f.cf_inst)
6340 {
6341 case SQ_CF_INST_POP:
6342 case SQ_CF_INST_JUMP:
6343 case SQ_CF_INST_ELSE:
6344 case SQ_CF_INST_LOOP_END:
6345 case SQ_CF_INST_LOOP_START:
6346 case SQ_CF_INST_LOOP_START_NO_AL:
6347 case SQ_CF_INST_LOOP_CONTINUE:
6348 case SQ_CF_INST_LOOP_BREAK:
6349 pCFInst->m_Word0.f.addr += unCFoffset;
6350 break;
6351 default:
6352 break;
6353 }
6354 }
6355
6356 pInst->m_uIndex += unCFoffset;
6357
6358 pInst = pInst->pNextInst;
6359 };
6360
6361 /* Put sub into main */
6362 plstCFmain->pTail->pNextInst = plstCFsub->pHead;
6363 plstCFmain->pTail = plstCFsub->pTail;
6364 plstCFmain->uNumOfNode += plstCFsub->uNumOfNode;
6365
6366 unCFoffset += plstCFsub->uNumOfNode;
6367 }
6368
6369 /* reloc callers */
6370 for(i=0; i<pAsm->unCallerArrayPointer; i++)
6371 {
6372 pAsm->callers[i].cf_ptr->m_Word0.f.addr
6373 = pAsm->subs[pAsm->callers[i].subDescIndex].unCFoffset;
6374 }
6375
6376 /* remove flags init if they are not used */
6377 if((pAsm->unCFflags & HAS_LOOPRET) == 0)
6378 {
6379 R700ControlFlowALUClause * pCF_ALU;
6380 pInst = plstCFmain->pHead;
6381 while(pInst)
6382 {
6383 if(SIT_CF_ALU == pInst->m_ShaderInstType)
6384 {
6385 pCF_ALU = (R700ControlFlowALUClause *)pInst;
6386 if(1 == pCF_ALU->m_Word1.f.count)
6387 {
6388 pCF_ALU->m_Word1.f.cf_inst = SQ_CF_INST_NOP;
6389 }
6390 else
6391 {
6392 R700ALUInstruction * pALU = pCF_ALU->m_pLinkedALUInstruction;
6393
6394 pALU->m_pLinkedALUClause = NULL;
6395 pALU = (R700ALUInstruction *)(pALU->pNextInst);
6396 pALU->m_pLinkedALUClause = pCF_ALU;
6397 pCF_ALU->m_pLinkedALUInstruction = pALU;
6398
6399 pCF_ALU->m_Word1.f.count--;
6400 }
6401 break;
6402 }
6403 pInst = pInst->pNextInst;
6404 };
6405 }
6406
6407 return GL_TRUE;
6408 }
6409
6410 GLboolean Process_Export(r700_AssemblerBase* pAsm,
6411 GLuint type,
6412 GLuint export_starting_index,
6413 GLuint export_count,
6414 GLuint starting_register_number,
6415 GLboolean is_depth_export)
6416 {
6417 unsigned char ucWriteMask;
6418
6419 check_current_clause(pAsm, CF_EMPTY_CLAUSE);
6420 check_current_clause(pAsm, CF_EXPORT_CLAUSE); //alloc the cf_current_export_clause_ptr
6421
6422 pAsm->cf_current_export_clause_ptr->m_Word0.f.type = type;
6423
6424 switch (type)
6425 {
6426 case SQ_EXPORT_PIXEL:
6427 if(GL_TRUE == is_depth_export)
6428 {
6429 pAsm->cf_current_export_clause_ptr->m_Word0.f.array_base = SQ_CF_PIXEL_Z;
6430 }
6431 else
6432 {
6433 pAsm->cf_current_export_clause_ptr->m_Word0.f.array_base = SQ_CF_PIXEL_MRT0 + export_starting_index;
6434 }
6435 break;
6436
6437 case SQ_EXPORT_POS:
6438 pAsm->cf_current_export_clause_ptr->m_Word0.f.array_base = SQ_CF_POS_0 + export_starting_index;
6439 break;
6440
6441 case SQ_EXPORT_PARAM:
6442 pAsm->cf_current_export_clause_ptr->m_Word0.f.array_base = 0x0 + export_starting_index;
6443 break;
6444
6445 default:
6446 radeon_error("Unknown export type: %d\n", type);
6447 return GL_FALSE;
6448 break;
6449 }
6450
6451 pAsm->cf_current_export_clause_ptr->m_Word0.f.rw_gpr = starting_register_number;
6452
6453 pAsm->cf_current_export_clause_ptr->m_Word0.f.rw_rel = SQ_ABSOLUTE;
6454 pAsm->cf_current_export_clause_ptr->m_Word0.f.index_gpr = 0x0;
6455 pAsm->cf_current_export_clause_ptr->m_Word0.f.elem_size = 0x3;
6456
6457 pAsm->cf_current_export_clause_ptr->m_Word1.f.burst_count = (export_count - 1);
6458 pAsm->cf_current_export_clause_ptr->m_Word1.f.end_of_program = 0x0;
6459 pAsm->cf_current_export_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
6460 pAsm->cf_current_export_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT; // _DONE
6461 pAsm->cf_current_export_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
6462 pAsm->cf_current_export_clause_ptr->m_Word1.f.barrier = 0x1;
6463
6464 if (export_count == 1)
6465 {
6466 ucWriteMask = pAsm->pucOutMask[starting_register_number - pAsm->starting_export_register_number];
6467 /* exports Z as a float into Red channel */
6468 if (GL_TRUE == is_depth_export)
6469 ucWriteMask = 0x1;
6470
6471 if( (ucWriteMask & 0x1) != 0)
6472 {
6473 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_x = SQ_SEL_X;
6474 }
6475 else
6476 {
6477 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_x = SQ_SEL_MASK;
6478 }
6479 if( ((ucWriteMask>>1) & 0x1) != 0)
6480 {
6481 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_y = SQ_SEL_Y;
6482 }
6483 else
6484 {
6485 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_y = SQ_SEL_MASK;
6486 }
6487 if( ((ucWriteMask>>2) & 0x1) != 0)
6488 {
6489 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_z = SQ_SEL_Z;
6490 }
6491 else
6492 {
6493 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_z = SQ_SEL_MASK;
6494 }
6495 if( ((ucWriteMask>>3) & 0x1) != 0)
6496 {
6497 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_w = SQ_SEL_W;
6498 }
6499 else
6500 {
6501 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_w = SQ_SEL_MASK;
6502 }
6503 }
6504 else
6505 {
6506 // This should only be used if all components for all registers have been written
6507 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_x = SQ_SEL_X;
6508 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_y = SQ_SEL_Y;
6509 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_z = SQ_SEL_Z;
6510 pAsm->cf_current_export_clause_ptr->m_Word1_SWIZ.f.sel_w = SQ_SEL_W;
6511 }
6512
6513 pAsm->cf_last_export_ptr = pAsm->cf_current_export_clause_ptr;
6514
6515 return GL_TRUE;
6516 }
6517
6518 GLboolean Move_Depth_Exports_To_Correct_Channels(r700_AssemblerBase *pAsm, BITS depth_channel_select)
6519 {
6520 gl_inst_opcode Opcode_save = pAsm->pILInst[pAsm->uiCurInst].Opcode; //Should be OPCODE_END
6521 pAsm->pILInst[pAsm->uiCurInst].Opcode = OPCODE_MOV;
6522
6523 // MOV depth_export_register.hw_depth_channel, depth_export_register.depth_channel_select
6524
6525 pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
6526
6527 setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
6528 pAsm->D.dst.rtype = DST_REG_TEMPORARY;
6529 pAsm->D.dst.reg = pAsm->depth_export_register_number;
6530
6531 pAsm->D.dst.writex = 1; // depth goes in R channel for HW
6532
6533 setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
6534 pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
6535 pAsm->S[0].src.reg = pAsm->depth_export_register_number;
6536
6537 setswizzle_PVSSRC(&(pAsm->S[0].src), depth_channel_select);
6538
6539 noneg_PVSSRC(&(pAsm->S[0].src));
6540
6541 if( GL_FALSE == next_ins(pAsm) )
6542 {
6543 return GL_FALSE;
6544 }
6545
6546 pAsm->pILInst[pAsm->uiCurInst].Opcode = Opcode_save;
6547
6548 return GL_TRUE;
6549 }
6550
6551 GLboolean Process_Fragment_Exports(r700_AssemblerBase *pR700AsmCode,
6552 GLbitfield OutputsWritten)
6553 {
6554 unsigned int unBit;
6555 GLuint export_count = 0;
6556
6557 if(pR700AsmCode->depth_export_register_number >= 0)
6558 {
6559 if( GL_FALSE == Move_Depth_Exports_To_Correct_Channels(pR700AsmCode, SQ_SEL_Z) ) // depth
6560 {
6561 return GL_FALSE;
6562 }
6563 }
6564
6565 unBit = 1 << FRAG_RESULT_COLOR;
6566 if(OutputsWritten & unBit)
6567 {
6568 if( GL_FALSE == Process_Export(pR700AsmCode,
6569 SQ_EXPORT_PIXEL,
6570 0,
6571 1,
6572 pR700AsmCode->uiFP_OutputMap[FRAG_RESULT_COLOR],
6573 GL_FALSE) )
6574 {
6575 return GL_FALSE;
6576 }
6577 export_count++;
6578 }
6579 unBit = 1 << FRAG_RESULT_DEPTH;
6580 if(OutputsWritten & unBit)
6581 {
6582 if( GL_FALSE == Process_Export(pR700AsmCode,
6583 SQ_EXPORT_PIXEL,
6584 0,
6585 1,
6586 pR700AsmCode->uiFP_OutputMap[FRAG_RESULT_DEPTH],
6587 GL_TRUE))
6588 {
6589 return GL_FALSE;
6590 }
6591 export_count++;
6592 }
6593 /* Need to export something, otherwise we'll hang
6594 * results are undefined anyway */
6595 if(export_count == 0)
6596 {
6597 Process_Export(pR700AsmCode, SQ_EXPORT_PIXEL, 0, 1, 0, GL_FALSE);
6598 }
6599
6600 if(pR700AsmCode->cf_last_export_ptr != NULL)
6601 {
6602 pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
6603 pR700AsmCode->cf_last_export_ptr->m_Word1.f.end_of_program = 0x1;
6604 }
6605
6606 return GL_TRUE;
6607 }
6608
6609 GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode,
6610 GLbitfield OutputsWritten)
6611 {
6612 unsigned int unBit;
6613 unsigned int i;
6614
6615 GLuint export_starting_index = 0;
6616 GLuint export_count = pR700AsmCode->number_of_exports;
6617
6618 unBit = 1 << VERT_RESULT_HPOS;
6619 if(OutputsWritten & unBit)
6620 {
6621 if( GL_FALSE == Process_Export(pR700AsmCode,
6622 SQ_EXPORT_POS,
6623 export_starting_index,
6624 1,
6625 pR700AsmCode->ucVP_OutputMap[VERT_RESULT_HPOS],
6626 GL_FALSE) )
6627 {
6628 return GL_FALSE;
6629 }
6630
6631 export_count--;
6632
6633 pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
6634 }
6635
6636 pR700AsmCode->number_of_exports = export_count;
6637
6638 unBit = 1 << VERT_RESULT_COL0;
6639 if(OutputsWritten & unBit)
6640 {
6641 if( GL_FALSE == Process_Export(pR700AsmCode,
6642 SQ_EXPORT_PARAM,
6643 export_starting_index,
6644 1,
6645 pR700AsmCode->ucVP_OutputMap[VERT_RESULT_COL0],
6646 GL_FALSE) )
6647 {
6648 return GL_FALSE;
6649 }
6650
6651 export_starting_index++;
6652 }
6653
6654 unBit = 1 << VERT_RESULT_COL1;
6655 if(OutputsWritten & unBit)
6656 {
6657 if( GL_FALSE == Process_Export(pR700AsmCode,
6658 SQ_EXPORT_PARAM,
6659 export_starting_index,
6660 1,
6661 pR700AsmCode->ucVP_OutputMap[VERT_RESULT_COL1],
6662 GL_FALSE) )
6663 {
6664 return GL_FALSE;
6665 }
6666
6667 export_starting_index++;
6668 }
6669
6670 unBit = 1 << VERT_RESULT_FOGC;
6671 if(OutputsWritten & unBit)
6672 {
6673 if( GL_FALSE == Process_Export(pR700AsmCode,
6674 SQ_EXPORT_PARAM,
6675 export_starting_index,
6676 1,
6677 pR700AsmCode->ucVP_OutputMap[VERT_RESULT_FOGC],
6678 GL_FALSE) )
6679 {
6680 return GL_FALSE;
6681 }
6682
6683 export_starting_index++;
6684 }
6685
6686 for(i=0; i<8; i++)
6687 {
6688 unBit = 1 << (VERT_RESULT_TEX0 + i);
6689 if(OutputsWritten & unBit)
6690 {
6691 if( GL_FALSE == Process_Export(pR700AsmCode,
6692 SQ_EXPORT_PARAM,
6693 export_starting_index,
6694 1,
6695 pR700AsmCode->ucVP_OutputMap[VERT_RESULT_TEX0 + i],
6696 GL_FALSE) )
6697 {
6698 return GL_FALSE;
6699 }
6700
6701 export_starting_index++;
6702 }
6703 }
6704
6705 for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
6706 {
6707 unBit = 1 << i;
6708 if(OutputsWritten & unBit)
6709 {
6710 if( GL_FALSE == Process_Export(pR700AsmCode,
6711 SQ_EXPORT_PARAM,
6712 export_starting_index,
6713 1,
6714 pR700AsmCode->ucVP_OutputMap[i],
6715 GL_FALSE) )
6716 {
6717 return GL_FALSE;
6718 }
6719
6720 export_starting_index++;
6721 }
6722 }
6723
6724 // At least one param should be exported
6725 if (export_count)
6726 {
6727 pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
6728 }
6729 else
6730 {
6731 if( GL_FALSE == Process_Export(pR700AsmCode,
6732 SQ_EXPORT_PARAM,
6733 0,
6734 1,
6735 pR700AsmCode->starting_export_register_number,
6736 GL_FALSE) )
6737 {
6738 return GL_FALSE;
6739 }
6740
6741 pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_x = SQ_SEL_0;
6742 pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_y = SQ_SEL_0;
6743 pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_z = SQ_SEL_0;
6744 pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_w = SQ_SEL_1;
6745 pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
6746 }
6747
6748 pR700AsmCode->cf_last_export_ptr->m_Word1.f.end_of_program = 0x1;
6749
6750 return GL_TRUE;
6751 }
6752
6753 GLboolean Clean_Up_Assembler(r700_AssemblerBase *pR700AsmCode)
6754 {
6755 FREE(pR700AsmCode->pucOutMask);
6756 FREE(pR700AsmCode->pInstDeps);
6757
6758 if(NULL != pR700AsmCode->subs)
6759 {
6760 FREE(pR700AsmCode->subs);
6761 }
6762 if(NULL != pR700AsmCode->callers)
6763 {
6764 FREE(pR700AsmCode->callers);
6765 }
6766
6767 return GL_TRUE;
6768 }
6769