1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 7bf215546Sopenharmony_ci * a copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial 16bf215546Sopenharmony_ci * portions of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22bf215546Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23bf215546Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24bf215546Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "r500_fragprog.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include <stdio.h> 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "radeon_compiler_util.h" 33bf215546Sopenharmony_ci#include "radeon_list.h" 34bf215546Sopenharmony_ci#include "radeon_variable.h" 35bf215546Sopenharmony_ci#include "r300_reg.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "util/compiler.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci/** 40bf215546Sopenharmony_ci * Rewrite IF instructions to use the ALU result special register. 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_ciint r500_transform_IF( 43bf215546Sopenharmony_ci struct radeon_compiler * c, 44bf215546Sopenharmony_ci struct rc_instruction * inst_if, 45bf215546Sopenharmony_ci void *data) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci if (inst_if->U.I.Opcode != RC_OPCODE_IF) 48bf215546Sopenharmony_ci return 0; 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci struct rc_variable * writer; 51bf215546Sopenharmony_ci struct rc_list * writer_list, * list_ptr; 52bf215546Sopenharmony_ci struct rc_list * var_list = rc_get_variables(c); 53bf215546Sopenharmony_ci unsigned int generic_if = 0; 54bf215546Sopenharmony_ci unsigned int alu_chan; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci writer_list = rc_variable_list_get_writers( 57bf215546Sopenharmony_ci var_list, inst_if->Type, &inst_if->U.I.SrcReg[0]); 58bf215546Sopenharmony_ci if (!writer_list) { 59bf215546Sopenharmony_ci generic_if = 1; 60bf215546Sopenharmony_ci } else { 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci /* Make sure it is safe for the writers to write to 63bf215546Sopenharmony_ci * ALU Result */ 64bf215546Sopenharmony_ci for (list_ptr = writer_list; list_ptr; 65bf215546Sopenharmony_ci list_ptr = list_ptr->Next) { 66bf215546Sopenharmony_ci struct rc_instruction * inst; 67bf215546Sopenharmony_ci writer = list_ptr->Item; 68bf215546Sopenharmony_ci /* We are going to modify the destination register 69bf215546Sopenharmony_ci * of writer, so if it has a reader other than 70bf215546Sopenharmony_ci * inst_if (aka ReaderCount > 1) we must fall back to 71bf215546Sopenharmony_ci * our generic IF. 72bf215546Sopenharmony_ci * If the writer has a lower IP than inst_if, this 73bf215546Sopenharmony_ci * means that inst_if is above the writer in a loop. 74bf215546Sopenharmony_ci * I'm not sure why this would ever happen, but 75bf215546Sopenharmony_ci * if it does we want to make sure we fall back 76bf215546Sopenharmony_ci * to our generic IF. */ 77bf215546Sopenharmony_ci if (writer->ReaderCount > 1 || writer->Inst->IP < inst_if->IP) { 78bf215546Sopenharmony_ci generic_if = 1; 79bf215546Sopenharmony_ci break; 80bf215546Sopenharmony_ci } 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci /* The ALU Result is not preserved across IF 83bf215546Sopenharmony_ci * instructions, so if there is another IF 84bf215546Sopenharmony_ci * instruction between writer and inst_if, then 85bf215546Sopenharmony_ci * we need to fall back to generic IF. */ 86bf215546Sopenharmony_ci for (inst = writer->Inst; inst != inst_if; inst = inst->Next) { 87bf215546Sopenharmony_ci const struct rc_opcode_info * info = 88bf215546Sopenharmony_ci rc_get_opcode_info(inst->U.I.Opcode); 89bf215546Sopenharmony_ci if (info->IsFlowControl) { 90bf215546Sopenharmony_ci generic_if = 1; 91bf215546Sopenharmony_ci break; 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci if (generic_if) { 95bf215546Sopenharmony_ci break; 96bf215546Sopenharmony_ci } 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci if (GET_SWZ(inst_if->U.I.SrcReg[0].Swizzle, 0) == RC_SWIZZLE_X) { 101bf215546Sopenharmony_ci alu_chan = RC_ALURESULT_X; 102bf215546Sopenharmony_ci } else { 103bf215546Sopenharmony_ci alu_chan = RC_ALURESULT_W; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci if (generic_if) { 106bf215546Sopenharmony_ci struct rc_instruction * inst_mov = 107bf215546Sopenharmony_ci rc_insert_new_instruction(c, inst_if->Prev); 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci inst_mov->U.I.Opcode = RC_OPCODE_MOV; 110bf215546Sopenharmony_ci inst_mov->U.I.DstReg.WriteMask = 0; 111bf215546Sopenharmony_ci inst_mov->U.I.DstReg.File = RC_FILE_NONE; 112bf215546Sopenharmony_ci inst_mov->U.I.ALUResultCompare = RC_COMPARE_FUNC_NOTEQUAL; 113bf215546Sopenharmony_ci inst_mov->U.I.WriteALUResult = alu_chan; 114bf215546Sopenharmony_ci inst_mov->U.I.SrcReg[0] = inst_if->U.I.SrcReg[0]; 115bf215546Sopenharmony_ci if (alu_chan == RC_ALURESULT_X) { 116bf215546Sopenharmony_ci inst_mov->U.I.SrcReg[0].Swizzle = combine_swizzles4( 117bf215546Sopenharmony_ci inst_mov->U.I.SrcReg[0].Swizzle, 118bf215546Sopenharmony_ci RC_SWIZZLE_X, RC_SWIZZLE_UNUSED, 119bf215546Sopenharmony_ci RC_SWIZZLE_UNUSED, RC_SWIZZLE_UNUSED); 120bf215546Sopenharmony_ci } else { 121bf215546Sopenharmony_ci inst_mov->U.I.SrcReg[0].Swizzle = combine_swizzles4( 122bf215546Sopenharmony_ci inst_mov->U.I.SrcReg[0].Swizzle, 123bf215546Sopenharmony_ci RC_SWIZZLE_UNUSED, RC_SWIZZLE_UNUSED, 124bf215546Sopenharmony_ci RC_SWIZZLE_UNUSED, RC_SWIZZLE_Z); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci } else { 127bf215546Sopenharmony_ci rc_compare_func compare_func = RC_COMPARE_FUNC_NEVER; 128bf215546Sopenharmony_ci unsigned int reverse_srcs = 0; 129bf215546Sopenharmony_ci unsigned int preserve_opcode = 0; 130bf215546Sopenharmony_ci for (list_ptr = writer_list; list_ptr; 131bf215546Sopenharmony_ci list_ptr = list_ptr->Next) { 132bf215546Sopenharmony_ci writer = list_ptr->Item; 133bf215546Sopenharmony_ci switch(writer->Inst->U.I.Opcode) { 134bf215546Sopenharmony_ci case RC_OPCODE_SEQ: 135bf215546Sopenharmony_ci compare_func = RC_COMPARE_FUNC_EQUAL; 136bf215546Sopenharmony_ci break; 137bf215546Sopenharmony_ci case RC_OPCODE_SNE: 138bf215546Sopenharmony_ci compare_func = RC_COMPARE_FUNC_NOTEQUAL; 139bf215546Sopenharmony_ci break; 140bf215546Sopenharmony_ci case RC_OPCODE_SLE: 141bf215546Sopenharmony_ci reverse_srcs = 1; 142bf215546Sopenharmony_ci FALLTHROUGH; 143bf215546Sopenharmony_ci case RC_OPCODE_SGE: 144bf215546Sopenharmony_ci compare_func = RC_COMPARE_FUNC_GEQUAL; 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci case RC_OPCODE_SGT: 147bf215546Sopenharmony_ci reverse_srcs = 1; 148bf215546Sopenharmony_ci FALLTHROUGH; 149bf215546Sopenharmony_ci case RC_OPCODE_SLT: 150bf215546Sopenharmony_ci compare_func = RC_COMPARE_FUNC_LESS; 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci default: 153bf215546Sopenharmony_ci compare_func = RC_COMPARE_FUNC_NOTEQUAL; 154bf215546Sopenharmony_ci preserve_opcode = 1; 155bf215546Sopenharmony_ci break; 156bf215546Sopenharmony_ci } 157bf215546Sopenharmony_ci if (!preserve_opcode) { 158bf215546Sopenharmony_ci writer->Inst->U.I.Opcode = RC_OPCODE_SUB; 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci writer->Inst->U.I.DstReg.WriteMask = 0; 161bf215546Sopenharmony_ci writer->Inst->U.I.DstReg.File = RC_FILE_NONE; 162bf215546Sopenharmony_ci writer->Inst->U.I.WriteALUResult = alu_chan; 163bf215546Sopenharmony_ci writer->Inst->U.I.ALUResultCompare = compare_func; 164bf215546Sopenharmony_ci if (reverse_srcs) { 165bf215546Sopenharmony_ci struct rc_src_register temp_src; 166bf215546Sopenharmony_ci temp_src = writer->Inst->U.I.SrcReg[0]; 167bf215546Sopenharmony_ci writer->Inst->U.I.SrcReg[0] = 168bf215546Sopenharmony_ci writer->Inst->U.I.SrcReg[1]; 169bf215546Sopenharmony_ci writer->Inst->U.I.SrcReg[1] = temp_src; 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci } 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci inst_if->U.I.SrcReg[0].File = RC_FILE_SPECIAL; 175bf215546Sopenharmony_ci inst_if->U.I.SrcReg[0].Index = RC_SPECIAL_ALU_RESULT; 176bf215546Sopenharmony_ci inst_if->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE( 177bf215546Sopenharmony_ci RC_SWIZZLE_X, RC_SWIZZLE_UNUSED, 178bf215546Sopenharmony_ci RC_SWIZZLE_UNUSED, RC_SWIZZLE_UNUSED); 179bf215546Sopenharmony_ci inst_if->U.I.SrcReg[0].Negate = 0; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci return 1; 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_cistatic int r500_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci unsigned int relevant; 187bf215546Sopenharmony_ci int i; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci if (opcode == RC_OPCODE_TEX || 190bf215546Sopenharmony_ci opcode == RC_OPCODE_TXB || 191bf215546Sopenharmony_ci opcode == RC_OPCODE_TXP || 192bf215546Sopenharmony_ci opcode == RC_OPCODE_TXD || 193bf215546Sopenharmony_ci opcode == RC_OPCODE_TXL || 194bf215546Sopenharmony_ci opcode == RC_OPCODE_KIL) { 195bf215546Sopenharmony_ci if (reg.Abs) 196bf215546Sopenharmony_ci return 0; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci if (opcode == RC_OPCODE_KIL && (reg.Swizzle != RC_SWIZZLE_XYZW || reg.Negate != RC_MASK_NONE)) 199bf215546Sopenharmony_ci return 0; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci for(i = 0; i < 4; ++i) { 202bf215546Sopenharmony_ci unsigned int swz = GET_SWZ(reg.Swizzle, i); 203bf215546Sopenharmony_ci if (swz == RC_SWIZZLE_UNUSED) { 204bf215546Sopenharmony_ci reg.Negate &= ~(1 << i); 205bf215546Sopenharmony_ci continue; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci if (swz >= 4) 208bf215546Sopenharmony_ci return 0; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (reg.Negate) 212bf215546Sopenharmony_ci return 0; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci return 1; 215bf215546Sopenharmony_ci } else if (opcode == RC_OPCODE_DDX || opcode == RC_OPCODE_DDY) { 216bf215546Sopenharmony_ci /* DDX/MDH and DDY/MDV explicitly ignore incoming swizzles; 217bf215546Sopenharmony_ci * if it doesn't fit perfectly into a .xyzw case... */ 218bf215546Sopenharmony_ci if (reg.Swizzle == RC_SWIZZLE_XYZW && !reg.Abs && !reg.Negate) 219bf215546Sopenharmony_ci return 1; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci return 0; 222bf215546Sopenharmony_ci } else { 223bf215546Sopenharmony_ci /* ALU instructions support almost everything */ 224bf215546Sopenharmony_ci relevant = 0; 225bf215546Sopenharmony_ci for(i = 0; i < 3; ++i) { 226bf215546Sopenharmony_ci unsigned int swz = GET_SWZ(reg.Swizzle, i); 227bf215546Sopenharmony_ci if (swz != RC_SWIZZLE_UNUSED && swz != RC_SWIZZLE_ZERO) 228bf215546Sopenharmony_ci relevant |= 1 << i; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant)) 231bf215546Sopenharmony_ci return 0; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci return 1; 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci} 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci/** 238bf215546Sopenharmony_ci * Split source register access. 239bf215546Sopenharmony_ci * 240bf215546Sopenharmony_ci * The only thing we *cannot* do in an ALU instruction is per-component 241bf215546Sopenharmony_ci * negation. 242bf215546Sopenharmony_ci */ 243bf215546Sopenharmony_cistatic void r500_swizzle_split(struct rc_src_register src, unsigned int usemask, 244bf215546Sopenharmony_ci struct rc_swizzle_split * split) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci unsigned int negatebase[2] = { 0, 0 }; 247bf215546Sopenharmony_ci int i; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci for(i = 0; i < 4; ++i) { 250bf215546Sopenharmony_ci unsigned int swz = GET_SWZ(src.Swizzle, i); 251bf215546Sopenharmony_ci if (swz == RC_SWIZZLE_UNUSED || !GET_BIT(usemask, i)) 252bf215546Sopenharmony_ci continue; 253bf215546Sopenharmony_ci negatebase[GET_BIT(src.Negate, i)] |= 1 << i; 254bf215546Sopenharmony_ci } 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci split->NumPhases = 0; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci for(i = 0; i <= 1; ++i) { 259bf215546Sopenharmony_ci if (!negatebase[i]) 260bf215546Sopenharmony_ci continue; 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci split->Phase[split->NumPhases++] = negatebase[i]; 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ciconst struct rc_swizzle_caps r500_swizzle_caps = { 267bf215546Sopenharmony_ci .IsNative = r500_swizzle_is_native, 268bf215546Sopenharmony_ci .Split = r500_swizzle_split 269bf215546Sopenharmony_ci}; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_cistatic char *toswiz(int swiz_val) { 272bf215546Sopenharmony_ci switch(swiz_val) { 273bf215546Sopenharmony_ci case 0: return "R"; 274bf215546Sopenharmony_ci case 1: return "G"; 275bf215546Sopenharmony_ci case 2: return "B"; 276bf215546Sopenharmony_ci case 3: return "A"; 277bf215546Sopenharmony_ci case 4: return "0"; 278bf215546Sopenharmony_ci case 5: return "H"; 279bf215546Sopenharmony_ci case 6: return "1"; 280bf215546Sopenharmony_ci case 7: return "U"; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci return NULL; 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cistatic char *toop(int op_val) 286bf215546Sopenharmony_ci{ 287bf215546Sopenharmony_ci char *str = NULL; 288bf215546Sopenharmony_ci switch (op_val) { 289bf215546Sopenharmony_ci case 0: str = "MAD"; break; 290bf215546Sopenharmony_ci case 1: str = "DP3"; break; 291bf215546Sopenharmony_ci case 2: str = "DP4"; break; 292bf215546Sopenharmony_ci case 3: str = "D2A"; break; 293bf215546Sopenharmony_ci case 4: str = "MIN"; break; 294bf215546Sopenharmony_ci case 5: str = "MAX"; break; 295bf215546Sopenharmony_ci case 6: str = "Reserved"; break; 296bf215546Sopenharmony_ci case 7: str = "CND"; break; 297bf215546Sopenharmony_ci case 8: str = "CMP"; break; 298bf215546Sopenharmony_ci case 9: str = "FRC"; break; 299bf215546Sopenharmony_ci case 10: str = "SOP"; break; 300bf215546Sopenharmony_ci case 11: str = "MDH"; break; 301bf215546Sopenharmony_ci case 12: str = "MDV"; break; 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci return str; 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_cistatic char *to_alpha_op(int op_val) 307bf215546Sopenharmony_ci{ 308bf215546Sopenharmony_ci char *str = NULL; 309bf215546Sopenharmony_ci switch (op_val) { 310bf215546Sopenharmony_ci case 0: str = "MAD"; break; 311bf215546Sopenharmony_ci case 1: str = "DP"; break; 312bf215546Sopenharmony_ci case 2: str = "MIN"; break; 313bf215546Sopenharmony_ci case 3: str = "MAX"; break; 314bf215546Sopenharmony_ci case 4: str = "Reserved"; break; 315bf215546Sopenharmony_ci case 5: str = "CND"; break; 316bf215546Sopenharmony_ci case 6: str = "CMP"; break; 317bf215546Sopenharmony_ci case 7: str = "FRC"; break; 318bf215546Sopenharmony_ci case 8: str = "EX2"; break; 319bf215546Sopenharmony_ci case 9: str = "LN2"; break; 320bf215546Sopenharmony_ci case 10: str = "RCP"; break; 321bf215546Sopenharmony_ci case 11: str = "RSQ"; break; 322bf215546Sopenharmony_ci case 12: str = "SIN"; break; 323bf215546Sopenharmony_ci case 13: str = "COS"; break; 324bf215546Sopenharmony_ci case 14: str = "MDH"; break; 325bf215546Sopenharmony_ci case 15: str = "MDV"; break; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci return str; 328bf215546Sopenharmony_ci} 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_cistatic char *to_mask(int val) 331bf215546Sopenharmony_ci{ 332bf215546Sopenharmony_ci char *str = NULL; 333bf215546Sopenharmony_ci switch(val) { 334bf215546Sopenharmony_ci case 0: str = "NONE"; break; 335bf215546Sopenharmony_ci case 1: str = "R"; break; 336bf215546Sopenharmony_ci case 2: str = "G"; break; 337bf215546Sopenharmony_ci case 3: str = "RG"; break; 338bf215546Sopenharmony_ci case 4: str = "B"; break; 339bf215546Sopenharmony_ci case 5: str = "RB"; break; 340bf215546Sopenharmony_ci case 6: str = "GB"; break; 341bf215546Sopenharmony_ci case 7: str = "RGB"; break; 342bf215546Sopenharmony_ci case 8: str = "A"; break; 343bf215546Sopenharmony_ci case 9: str = "AR"; break; 344bf215546Sopenharmony_ci case 10: str = "AG"; break; 345bf215546Sopenharmony_ci case 11: str = "ARG"; break; 346bf215546Sopenharmony_ci case 12: str = "AB"; break; 347bf215546Sopenharmony_ci case 13: str = "ARB"; break; 348bf215546Sopenharmony_ci case 14: str = "AGB"; break; 349bf215546Sopenharmony_ci case 15: str = "ARGB"; break; 350bf215546Sopenharmony_ci } 351bf215546Sopenharmony_ci return str; 352bf215546Sopenharmony_ci} 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_cistatic char *to_texop(int val) 355bf215546Sopenharmony_ci{ 356bf215546Sopenharmony_ci switch(val) { 357bf215546Sopenharmony_ci case 0: return "NOP"; 358bf215546Sopenharmony_ci case 1: return "LD"; 359bf215546Sopenharmony_ci case 2: return "TEXKILL"; 360bf215546Sopenharmony_ci case 3: return "PROJ"; 361bf215546Sopenharmony_ci case 4: return "LODBIAS"; 362bf215546Sopenharmony_ci case 5: return "LOD"; 363bf215546Sopenharmony_ci case 6: return "DXDY"; 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci return NULL; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_civoid r500FragmentProgramDump(struct radeon_compiler *c, void *user) 369bf215546Sopenharmony_ci{ 370bf215546Sopenharmony_ci struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; 371bf215546Sopenharmony_ci struct r500_fragment_program_code *code = &compiler->code->code.r500; 372bf215546Sopenharmony_ci int n, i; 373bf215546Sopenharmony_ci uint32_t inst; 374bf215546Sopenharmony_ci uint32_t inst0; 375bf215546Sopenharmony_ci char *str = NULL; 376bf215546Sopenharmony_ci fprintf(stderr, "R500 Fragment Program:\n--------\n"); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci for (n = 0; n < code->inst_end+1; n++) { 379bf215546Sopenharmony_ci inst0 = inst = code->inst[n].inst0; 380bf215546Sopenharmony_ci fprintf(stderr,"%d\t0:CMN_INST 0x%08x:", n, inst); 381bf215546Sopenharmony_ci switch(inst & 0x3) { 382bf215546Sopenharmony_ci case R500_INST_TYPE_ALU: str = "ALU"; break; 383bf215546Sopenharmony_ci case R500_INST_TYPE_OUT: str = "OUT"; break; 384bf215546Sopenharmony_ci case R500_INST_TYPE_FC: str = "FC"; break; 385bf215546Sopenharmony_ci case R500_INST_TYPE_TEX: str = "TEX"; break; 386bf215546Sopenharmony_ci } 387bf215546Sopenharmony_ci fprintf(stderr,"%s %s %s %s %s ", str, 388bf215546Sopenharmony_ci inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", 389bf215546Sopenharmony_ci inst & R500_INST_LAST ? "LAST" : "", 390bf215546Sopenharmony_ci inst & R500_INST_NOP ? "NOP" : "", 391bf215546Sopenharmony_ci inst & R500_INST_ALU_WAIT ? "ALU WAIT" : ""); 392bf215546Sopenharmony_ci fprintf(stderr,"wmask: %s omask: %s\n", to_mask((inst >> 11) & 0xf), 393bf215546Sopenharmony_ci to_mask((inst >> 15) & 0xf)); 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci switch(inst0 & 0x3) { 396bf215546Sopenharmony_ci case R500_INST_TYPE_ALU: 397bf215546Sopenharmony_ci case R500_INST_TYPE_OUT: 398bf215546Sopenharmony_ci fprintf(stderr,"\t1:RGB_ADDR 0x%08x:", code->inst[n].inst1); 399bf215546Sopenharmony_ci inst = code->inst[n].inst1; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci fprintf(stderr,"Addr0: %d%c, Addr1: %d%c, Addr2: %d%c, srcp:%d\n", 402bf215546Sopenharmony_ci inst & 0xff, (inst & (1<<8)) ? 'c' : 't', 403bf215546Sopenharmony_ci (inst >> 10) & 0xff, (inst & (1<<18)) ? 'c' : 't', 404bf215546Sopenharmony_ci (inst >> 20) & 0xff, (inst & (1<<28)) ? 'c' : 't', 405bf215546Sopenharmony_ci (inst >> 30)); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci fprintf(stderr,"\t2:ALPHA_ADDR 0x%08x:", code->inst[n].inst2); 408bf215546Sopenharmony_ci inst = code->inst[n].inst2; 409bf215546Sopenharmony_ci fprintf(stderr,"Addr0: %d%c, Addr1: %d%c, Addr2: %d%c, srcp:%d\n", 410bf215546Sopenharmony_ci inst & 0xff, (inst & (1<<8)) ? 'c' : 't', 411bf215546Sopenharmony_ci (inst >> 10) & 0xff, (inst & (1<<18)) ? 'c' : 't', 412bf215546Sopenharmony_ci (inst >> 20) & 0xff, (inst & (1<<28)) ? 'c' : 't', 413bf215546Sopenharmony_ci (inst >> 30)); 414bf215546Sopenharmony_ci fprintf(stderr,"\t3 RGB_INST: 0x%08x:", code->inst[n].inst3); 415bf215546Sopenharmony_ci inst = code->inst[n].inst3; 416bf215546Sopenharmony_ci fprintf(stderr,"rgb_A_src:%d %s/%s/%s %d rgb_B_src:%d %s/%s/%s %d targ: %d\n", 417bf215546Sopenharmony_ci (inst) & 0x3, toswiz((inst >> 2) & 0x7), toswiz((inst >> 5) & 0x7), toswiz((inst >> 8) & 0x7), 418bf215546Sopenharmony_ci (inst >> 11) & 0x3, 419bf215546Sopenharmony_ci (inst >> 13) & 0x3, toswiz((inst >> 15) & 0x7), toswiz((inst >> 18) & 0x7), toswiz((inst >> 21) & 0x7), 420bf215546Sopenharmony_ci (inst >> 24) & 0x3, (inst >> 29) & 0x3); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci fprintf(stderr,"\t4 ALPHA_INST:0x%08x:", code->inst[n].inst4); 424bf215546Sopenharmony_ci inst = code->inst[n].inst4; 425bf215546Sopenharmony_ci fprintf(stderr,"%s dest:%d%s alp_A_src:%d %s %d alp_B_src:%d %s %d targ %d w:%d\n", to_alpha_op(inst & 0xf), 426bf215546Sopenharmony_ci (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"", 427bf215546Sopenharmony_ci (inst >> 12) & 0x3, toswiz((inst >> 14) & 0x7), (inst >> 17) & 0x3, 428bf215546Sopenharmony_ci (inst >> 19) & 0x3, toswiz((inst >> 21) & 0x7), (inst >> 24) & 0x3, 429bf215546Sopenharmony_ci (inst >> 29) & 0x3, 430bf215546Sopenharmony_ci (inst >> 31) & 0x1); 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci fprintf(stderr,"\t5 RGBA_INST: 0x%08x:", code->inst[n].inst5); 433bf215546Sopenharmony_ci inst = code->inst[n].inst5; 434bf215546Sopenharmony_ci fprintf(stderr,"%s dest:%d%s rgb_C_src:%d %s/%s/%s %d alp_C_src:%d %s %d\n", toop(inst & 0xf), 435bf215546Sopenharmony_ci (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"", 436bf215546Sopenharmony_ci (inst >> 12) & 0x3, toswiz((inst >> 14) & 0x7), toswiz((inst >> 17) & 0x7), toswiz((inst >> 20) & 0x7), 437bf215546Sopenharmony_ci (inst >> 23) & 0x3, 438bf215546Sopenharmony_ci (inst >> 25) & 0x3, toswiz((inst >> 27) & 0x7), (inst >> 30) & 0x3); 439bf215546Sopenharmony_ci break; 440bf215546Sopenharmony_ci case R500_INST_TYPE_FC: 441bf215546Sopenharmony_ci fprintf(stderr, "\t2:FC_INST 0x%08x:", code->inst[n].inst2); 442bf215546Sopenharmony_ci inst = code->inst[n].inst2; 443bf215546Sopenharmony_ci /* JUMP_FUNC JUMP_ANY*/ 444bf215546Sopenharmony_ci fprintf(stderr, "0x%02x %1x ", inst >> 8 & 0xff, 445bf215546Sopenharmony_ci (inst & R500_FC_JUMP_ANY) >> 5); 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci /* OP */ 448bf215546Sopenharmony_ci switch(inst & 0x7){ 449bf215546Sopenharmony_ci case R500_FC_OP_JUMP: 450bf215546Sopenharmony_ci fprintf(stderr, "JUMP"); 451bf215546Sopenharmony_ci break; 452bf215546Sopenharmony_ci case R500_FC_OP_LOOP: 453bf215546Sopenharmony_ci fprintf(stderr, "LOOP"); 454bf215546Sopenharmony_ci break; 455bf215546Sopenharmony_ci case R500_FC_OP_ENDLOOP: 456bf215546Sopenharmony_ci fprintf(stderr, "ENDLOOP"); 457bf215546Sopenharmony_ci break; 458bf215546Sopenharmony_ci case R500_FC_OP_REP: 459bf215546Sopenharmony_ci fprintf(stderr, "REP"); 460bf215546Sopenharmony_ci break; 461bf215546Sopenharmony_ci case R500_FC_OP_ENDREP: 462bf215546Sopenharmony_ci fprintf(stderr, "ENDREP"); 463bf215546Sopenharmony_ci break; 464bf215546Sopenharmony_ci case R500_FC_OP_BREAKLOOP: 465bf215546Sopenharmony_ci fprintf(stderr, "BREAKLOOP"); 466bf215546Sopenharmony_ci break; 467bf215546Sopenharmony_ci case R500_FC_OP_BREAKREP: 468bf215546Sopenharmony_ci fprintf(stderr, "BREAKREP"); 469bf215546Sopenharmony_ci break; 470bf215546Sopenharmony_ci case R500_FC_OP_CONTINUE: 471bf215546Sopenharmony_ci fprintf(stderr, "CONTINUE"); 472bf215546Sopenharmony_ci break; 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci fprintf(stderr," "); 475bf215546Sopenharmony_ci /* A_OP */ 476bf215546Sopenharmony_ci switch(inst & (0x3 << 6)){ 477bf215546Sopenharmony_ci case R500_FC_A_OP_NONE: 478bf215546Sopenharmony_ci fprintf(stderr, "NONE"); 479bf215546Sopenharmony_ci break; 480bf215546Sopenharmony_ci case R500_FC_A_OP_POP: 481bf215546Sopenharmony_ci fprintf(stderr, "POP"); 482bf215546Sopenharmony_ci break; 483bf215546Sopenharmony_ci case R500_FC_A_OP_PUSH: 484bf215546Sopenharmony_ci fprintf(stderr, "PUSH"); 485bf215546Sopenharmony_ci break; 486bf215546Sopenharmony_ci } 487bf215546Sopenharmony_ci /* B_OP0 B_OP1 */ 488bf215546Sopenharmony_ci for(i=0; i<2; i++){ 489bf215546Sopenharmony_ci fprintf(stderr, " "); 490bf215546Sopenharmony_ci switch(inst & (0x3 << (24 + (i * 2)))){ 491bf215546Sopenharmony_ci /* R500_FC_B_OP0_NONE 492bf215546Sopenharmony_ci * R500_FC_B_OP1_NONE */ 493bf215546Sopenharmony_ci case 0: 494bf215546Sopenharmony_ci fprintf(stderr, "NONE"); 495bf215546Sopenharmony_ci break; 496bf215546Sopenharmony_ci case R500_FC_B_OP0_DECR: 497bf215546Sopenharmony_ci case R500_FC_B_OP1_DECR: 498bf215546Sopenharmony_ci fprintf(stderr, "DECR"); 499bf215546Sopenharmony_ci break; 500bf215546Sopenharmony_ci case R500_FC_B_OP0_INCR: 501bf215546Sopenharmony_ci case R500_FC_B_OP1_INCR: 502bf215546Sopenharmony_ci fprintf(stderr, "INCR"); 503bf215546Sopenharmony_ci break; 504bf215546Sopenharmony_ci } 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci /*POP_CNT B_ELSE */ 507bf215546Sopenharmony_ci fprintf(stderr, " %d %1x", (inst >> 16) & 0x1f, (inst & R500_FC_B_ELSE) >> 4); 508bf215546Sopenharmony_ci inst = code->inst[n].inst3; 509bf215546Sopenharmony_ci /* JUMP_ADDR */ 510bf215546Sopenharmony_ci fprintf(stderr, " %d", inst >> 16); 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci if(code->inst[n].inst2 & R500_FC_IGNORE_UNCOVERED){ 513bf215546Sopenharmony_ci fprintf(stderr, " IGN_UNC"); 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci inst = code->inst[n].inst3; 516bf215546Sopenharmony_ci fprintf(stderr, "\n\t3:FC_ADDR 0x%08x:", inst); 517bf215546Sopenharmony_ci fprintf(stderr, "BOOL: 0x%02x, INT: 0x%02x, JUMP_ADDR: %d, JMP_GLBL: %1x\n", 518bf215546Sopenharmony_ci inst & 0x1f, (inst >> 8) & 0x1f, (inst >> 16) & 0x1ff, inst >> 31); 519bf215546Sopenharmony_ci break; 520bf215546Sopenharmony_ci case R500_INST_TYPE_TEX: 521bf215546Sopenharmony_ci inst = code->inst[n].inst1; 522bf215546Sopenharmony_ci fprintf(stderr,"\t1:TEX_INST: 0x%08x: id: %d op:%s, %s, %s %s\n", inst, (inst >> 16) & 0xf, 523bf215546Sopenharmony_ci to_texop((inst >> 22) & 0x7), (inst & (1<<25)) ? "ACQ" : "", 524bf215546Sopenharmony_ci (inst & (1<<26)) ? "IGNUNC" : "", (inst & (1<<27)) ? "UNSCALED" : "SCALED"); 525bf215546Sopenharmony_ci inst = code->inst[n].inst2; 526bf215546Sopenharmony_ci fprintf(stderr,"\t2:TEX_ADDR: 0x%08x: src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", inst, 527bf215546Sopenharmony_ci inst & 127, inst & (1<<7) ? "(rel)" : "", 528bf215546Sopenharmony_ci toswiz((inst >> 8) & 0x3), toswiz((inst >> 10) & 0x3), 529bf215546Sopenharmony_ci toswiz((inst >> 12) & 0x3), toswiz((inst >> 14) & 0x3), 530bf215546Sopenharmony_ci (inst >> 16) & 127, inst & (1<<23) ? "(rel)" : "", 531bf215546Sopenharmony_ci toswiz((inst >> 24) & 0x3), toswiz((inst >> 26) & 0x3), 532bf215546Sopenharmony_ci toswiz((inst >> 28) & 0x3), toswiz((inst >> 30) & 0x3)); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci fprintf(stderr,"\t3:TEX_DXDY: 0x%08x\n", code->inst[n].inst3); 535bf215546Sopenharmony_ci break; 536bf215546Sopenharmony_ci } 537bf215546Sopenharmony_ci fprintf(stderr,"\n"); 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci} 541