Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2005 Ben Skeggs.
      3  *
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining
      7  * a copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sublicense, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial
     16  * portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  */
     27 
     28 #include "r300_fragprog.h"
     29 
     30 #include <stdio.h>
     31 
     32 #include "r300_reg.h"
     33 
     34 static void presub_string(char out[10], unsigned int inst)
     35 {
     36 	switch(inst & 0x600000){
     37 	case R300_ALU_SRCP_1_MINUS_2_SRC0:
     38 		sprintf(out, "bias");
     39 		break;
     40 	case R300_ALU_SRCP_SRC1_MINUS_SRC0:
     41 		sprintf(out, "sub");
     42 		break;
     43 	case R300_ALU_SRCP_SRC1_PLUS_SRC0:
     44 		sprintf(out, "add");
     45 		break;
     46 	case R300_ALU_SRCP_1_MINUS_SRC0:
     47 		sprintf(out, "inv ");
     48 		break;
     49 	}
     50 }
     51 
     52 static int get_msb(unsigned int bit, unsigned int r400_ext_addr)
     53 {
     54 	return (r400_ext_addr & bit) ? 1 << 5 : 0;
     55 }
     56 
     57 /* just some random things... */
     58 void r300FragmentProgramDump(struct radeon_compiler *c, void *user)
     59 {
     60 	struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c;
     61 	struct r300_fragment_program_code *code = &compiler->code->code.r300;
     62 	int n, i, j;
     63 	static int pc = 0;
     64 
     65 	fprintf(stderr, "pc=%d*************************************\n", pc++);
     66 
     67 	fprintf(stderr, "Hardware program\n");
     68 	fprintf(stderr, "----------------\n");
     69 	if (c->is_r400) {
     70 		fprintf(stderr, "code_offset_ext: %08x\n", code->r400_code_offset_ext);
     71 	}
     72 
     73 	for (n = 0; n <= (code->config & 3); n++) {
     74 		uint32_t code_addr = code->code_addr[3 - (code->config & 3) + n];
     75 		unsigned int alu_offset = ((code_addr & R300_ALU_START_MASK) >> R300_ALU_START_SHIFT) +
     76 				(((code->r400_code_offset_ext >> (24 - (n * 6))) & 0x7) << 6);
     77 		unsigned int alu_end = ((code_addr & R300_ALU_SIZE_MASK) >> R300_ALU_SIZE_SHIFT) +
     78 				(((code->r400_code_offset_ext >> (27 - (n * 6))) & 0x7) << 6);
     79 		int tex_offset = (code_addr & R300_TEX_START_MASK) >> R300_TEX_START_SHIFT;
     80 		int tex_end = (code_addr & R300_TEX_SIZE_MASK) >> R300_TEX_SIZE_SHIFT;
     81 
     82 		fprintf(stderr, "NODE %d: alu_offset: %u, tex_offset: %d, "
     83 			"alu_end: %u, tex_end: %d  (code_addr: %08x)\n", n,
     84 			alu_offset, tex_offset, alu_end, tex_end, code_addr);
     85 
     86 		if (n > 0 || (code->config & R300_PFS_CNTL_FIRST_NODE_HAS_TEX)) {
     87 			fprintf(stderr, "  TEX:\n");
     88 			for (i = tex_offset;
     89 			     i <= tex_offset + tex_end;
     90 			     ++i) {
     91 				const char *instr;
     92 
     93 				switch ((code->tex.
     94 					 inst[i] >> R300_TEX_INST_SHIFT) &
     95 					15) {
     96 				case R300_TEX_OP_LD:
     97 					instr = "TEX";
     98 					break;
     99 				case R300_TEX_OP_KIL:
    100 					instr = "KIL";
    101 					break;
    102 				case R300_TEX_OP_TXP:
    103 					instr = "TXP";
    104 					break;
    105 				case R300_TEX_OP_TXB:
    106 					instr = "TXB";
    107 					break;
    108 				default:
    109 					instr = "UNKNOWN";
    110 				}
    111 
    112 				fprintf(stderr,
    113 					"    %s t%i, %c%i, texture[%i]   (%08x)\n",
    114 					instr,
    115 					(code->tex.
    116 					 inst[i] >> R300_DST_ADDR_SHIFT) & 31,
    117 					't',
    118 					(code->tex.
    119 					 inst[i] >> R300_SRC_ADDR_SHIFT) & 31,
    120 					(code->tex.
    121 					 inst[i] & R300_TEX_ID_MASK) >>
    122 					R300_TEX_ID_SHIFT,
    123 					code->tex.inst[i]);
    124 			}
    125 		}
    126 
    127 		for (i = alu_offset;
    128 		     i <= alu_offset + alu_end; ++i) {
    129 			char srcc[4][10], dstc[20];
    130 			char srca[4][10], dsta[20];
    131 			char argc[3][20];
    132 			char arga[3][20];
    133 			char flags[5], tmp[10];
    134 
    135 			for (j = 0; j < 3; ++j) {
    136 				int regc = code->alu.inst[i].rgb_addr >> (j * 6);
    137 				int rega = code->alu.inst[i].alpha_addr >> (j * 6);
    138 				int msbc = get_msb(R400_ADDR_EXT_RGB_MSB_BIT(j),
    139 					code->alu.inst[i].r400_ext_addr);
    140 				int msba = get_msb(R400_ADDR_EXT_A_MSB_BIT(j),
    141 					code->alu.inst[i].r400_ext_addr);
    142 
    143 				sprintf(srcc[j], "%c%i",
    144 					(regc & 32) ? 'c' : 't', (regc & 31) | msbc);
    145 				sprintf(srca[j], "%c%i",
    146 					(rega & 32) ? 'c' : 't', (rega & 31) | msba);
    147 			}
    148 
    149 			dstc[0] = 0;
    150 			sprintf(flags, "%s%s%s",
    151 				(code->alu.inst[i].
    152 				 rgb_addr & R300_ALU_DSTC_REG_X) ? "x" : "",
    153 				(code->alu.inst[i].
    154 				 rgb_addr & R300_ALU_DSTC_REG_Y) ? "y" : "",
    155 				(code->alu.inst[i].
    156 				 rgb_addr & R300_ALU_DSTC_REG_Z) ? "z" : "");
    157 			if (flags[0] != 0) {
    158 				unsigned int msb = get_msb(
    159 					R400_ADDRD_EXT_RGB_MSB_BIT,
    160 					code->alu.inst[i].r400_ext_addr);
    161 
    162 				sprintf(dstc, "t%i.%s ",
    163 					((code->alu.inst[i].
    164 					 rgb_addr >> R300_ALU_DSTC_SHIFT)
    165 					 & 31) | msb,
    166 					flags);
    167 			}
    168 			sprintf(flags, "%s%s%s",
    169 				(code->alu.inst[i].
    170 				 rgb_addr & R300_ALU_DSTC_OUTPUT_X) ? "x" : "",
    171 				(code->alu.inst[i].
    172 				 rgb_addr & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "",
    173 				(code->alu.inst[i].
    174 				 rgb_addr & R300_ALU_DSTC_OUTPUT_Z) ? "z" : "");
    175 			if (flags[0] != 0) {
    176 				sprintf(tmp, "o%i.%s",
    177 					(code->alu.inst[i].
    178 					 rgb_addr >> 29) & 3,
    179 					flags);
    180 				strcat(dstc, tmp);
    181 			}
    182 			/* Presub */
    183 			presub_string(srcc[3], code->alu.inst[i].rgb_inst);
    184 			presub_string(srca[3], code->alu.inst[i].alpha_inst);
    185 
    186 			dsta[0] = 0;
    187 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_REG) {
    188 				unsigned int msb = get_msb(
    189 					R400_ADDRD_EXT_A_MSB_BIT,
    190 					code->alu.inst[i].r400_ext_addr);
    191 				sprintf(dsta, "t%i.w ",
    192 					((code->alu.inst[i].
    193 					 alpha_addr >> R300_ALU_DSTA_SHIFT) & 31)
    194 					 | msb);
    195 			}
    196 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) {
    197 				sprintf(tmp, "o%i.w ",
    198 					(code->alu.inst[i].
    199 					 alpha_addr >> 25) & 3);
    200 				strcat(dsta, tmp);
    201 			}
    202 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) {
    203 				strcat(dsta, "Z");
    204 			}
    205 
    206 			fprintf(stderr,
    207 				"%3i: xyz: %3s %3s %3s %5s-> %-20s (%08x)\n"
    208 				"       w: %3s %3s %3s %5s-> %-20s (%08x)\n", i,
    209 				srcc[0], srcc[1], srcc[2], srcc[3], dstc,
    210 				code->alu.inst[i].rgb_addr, srca[0], srca[1],
    211 				srca[2], srca[3], dsta,
    212 				code->alu.inst[i].alpha_addr);
    213 
    214 			for (j = 0; j < 3; ++j) {
    215 				int regc = code->alu.inst[i].rgb_inst >> (j * 7);
    216 				int rega = code->alu.inst[i].alpha_inst >> (j * 7);
    217 				int d;
    218 				char buf[20];
    219 
    220 				d = regc & 31;
    221 				if (d < 12) {
    222 					switch (d % 4) {
    223 					case R300_ALU_ARGC_SRC0C_XYZ:
    224 						sprintf(buf, "%s.xyz",
    225 							srcc[d / 4]);
    226 						break;
    227 					case R300_ALU_ARGC_SRC0C_XXX:
    228 						sprintf(buf, "%s.xxx",
    229 							srcc[d / 4]);
    230 						break;
    231 					case R300_ALU_ARGC_SRC0C_YYY:
    232 						sprintf(buf, "%s.yyy",
    233 							srcc[d / 4]);
    234 						break;
    235 					case R300_ALU_ARGC_SRC0C_ZZZ:
    236 						sprintf(buf, "%s.zzz",
    237 							srcc[d / 4]);
    238 						break;
    239 					}
    240 				} else if (d < 15) {
    241 					sprintf(buf, "%s.www", srca[d - 12]);
    242 				} else if (d < 20 ) {
    243 					switch(d) {
    244 					case R300_ALU_ARGC_SRCP_XYZ:
    245 						sprintf(buf, "srcp.xyz");
    246 						break;
    247 					case R300_ALU_ARGC_SRCP_XXX:
    248 						sprintf(buf, "srcp.xxx");
    249 						break;
    250 					case R300_ALU_ARGC_SRCP_YYY:
    251 						sprintf(buf, "srcp.yyy");
    252 						break;
    253 					case R300_ALU_ARGC_SRCP_ZZZ:
    254 						sprintf(buf, "srcp.zzz");
    255 						break;
    256 					case R300_ALU_ARGC_SRCP_WWW:
    257 						sprintf(buf, "srcp.www");
    258 						break;
    259 					}
    260 				} else if (d == 20) {
    261 					sprintf(buf, "0.0");
    262 				} else if (d == 21) {
    263 					sprintf(buf, "1.0");
    264 				} else if (d == 22) {
    265 					sprintf(buf, "0.5");
    266 				} else if (d >= 23 && d < 32) {
    267 					d -= 23;
    268 					switch (d / 3) {
    269 					case 0:
    270 						sprintf(buf, "%s.yzx",
    271 							srcc[d % 3]);
    272 						break;
    273 					case 1:
    274 						sprintf(buf, "%s.zxy",
    275 							srcc[d % 3]);
    276 						break;
    277 					case 2:
    278 						sprintf(buf, "%s.Wzy",
    279 							srcc[d % 3]);
    280 						break;
    281 					}
    282 				} else {
    283 					sprintf(buf, "%i", d);
    284 				}
    285 
    286 				sprintf(argc[j], "%s%s%s%s",
    287 					(regc & 32) ? "-" : "",
    288 					(regc & 64) ? "|" : "",
    289 					buf, (regc & 64) ? "|" : "");
    290 
    291 				d = rega & 31;
    292 				if (d < 9) {
    293 					sprintf(buf, "%s.%c", srcc[d / 3],
    294 						'x' + (char)(d % 3));
    295 				} else if (d < 12) {
    296 					sprintf(buf, "%s.w", srca[d - 9]);
    297 				} else if (d < 16) {
    298 					switch(d) {
    299 					case R300_ALU_ARGA_SRCP_X:
    300 						sprintf(buf, "srcp.x");
    301 						break;
    302 					case R300_ALU_ARGA_SRCP_Y:
    303 						sprintf(buf, "srcp.y");
    304 						break;
    305 					case R300_ALU_ARGA_SRCP_Z:
    306 						sprintf(buf, "srcp.z");
    307 						break;
    308 					case R300_ALU_ARGA_SRCP_W:
    309 						sprintf(buf, "srcp.w");
    310 						break;
    311 					}
    312 				} else if (d == 16) {
    313 					sprintf(buf, "0.0");
    314 				} else if (d == 17) {
    315 					sprintf(buf, "1.0");
    316 				} else if (d == 18) {
    317 					sprintf(buf, "0.5");
    318 				} else {
    319 					sprintf(buf, "%i", d);
    320 				}
    321 
    322 				sprintf(arga[j], "%s%s%s%s",
    323 					(rega & 32) ? "-" : "",
    324 					(rega & 64) ? "|" : "",
    325 					buf, (rega & 64) ? "|" : "");
    326 			}
    327 
    328 			fprintf(stderr, "     xyz: %8s %8s %8s    op: %08x %s\n"
    329 				"       w: %8s %8s %8s    op: %08x\n",
    330 				argc[0], argc[1], argc[2],
    331 				code->alu.inst[i].rgb_inst,
    332 				code->alu.inst[i].rgb_inst & R300_ALU_INSERT_NOP ?
    333 				"NOP" : "",
    334 				arga[0], arga[1],arga[2],
    335 				code->alu.inst[i].alpha_inst);
    336 		}
    337 	}
    338 }
    339