Path: blob/21.2-virgl/src/gallium/drivers/r300/compiler/radeon_program_print.c
4574 views
/*1* Copyright 2009 Nicolai Hähnle <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE. */2122#include "radeon_program.h"2324#include <stdio.h>2526static const char * textarget_to_string(rc_texture_target target)27{28switch(target) {29case RC_TEXTURE_2D_ARRAY: return "2D_ARRAY";30case RC_TEXTURE_1D_ARRAY: return "1D_ARRAY";31case RC_TEXTURE_CUBE: return "CUBE";32case RC_TEXTURE_3D: return "3D";33case RC_TEXTURE_RECT: return "RECT";34case RC_TEXTURE_2D: return "2D";35case RC_TEXTURE_1D: return "1D";36default: return "BAD_TEXTURE_TARGET";37}38}3940static const char * presubtract_op_to_string(rc_presubtract_op op)41{42switch(op) {43case RC_PRESUB_NONE:44return "NONE";45case RC_PRESUB_BIAS:46return "(1 - 2 * src0)";47case RC_PRESUB_SUB:48return "(src1 - src0)";49case RC_PRESUB_ADD:50return "(src1 + src0)";51case RC_PRESUB_INV:52return "(1 - src0)";53default:54return "BAD_PRESUBTRACT_OP";55}56}5758static void print_omod_op(FILE * f, rc_omod_op op)59{60const char * omod_str;6162switch(op) {63case RC_OMOD_MUL_1:64case RC_OMOD_DISABLE:65return;66case RC_OMOD_MUL_2:67omod_str = "* 2";68break;69case RC_OMOD_MUL_4:70omod_str = "* 4";71break;72case RC_OMOD_MUL_8:73omod_str = "* 8";74break;75case RC_OMOD_DIV_2:76omod_str = "/ 2";77break;78case RC_OMOD_DIV_4:79omod_str = "/ 4";80break;81case RC_OMOD_DIV_8:82omod_str = "/ 8";83break;84default:85return;86}87fprintf(f, " %s", omod_str);88}8990static void rc_print_comparefunc(FILE * f, const char * lhs, rc_compare_func func, const char * rhs)91{92if (func == RC_COMPARE_FUNC_NEVER) {93fprintf(f, "false");94} else if (func == RC_COMPARE_FUNC_ALWAYS) {95fprintf(f, "true");96} else {97const char * op;98switch(func) {99case RC_COMPARE_FUNC_LESS: op = "<"; break;100case RC_COMPARE_FUNC_EQUAL: op = "=="; break;101case RC_COMPARE_FUNC_LEQUAL: op = "<="; break;102case RC_COMPARE_FUNC_GREATER: op = ">"; break;103case RC_COMPARE_FUNC_NOTEQUAL: op = "!="; break;104case RC_COMPARE_FUNC_GEQUAL: op = ">="; break;105default: op = "???"; break;106}107fprintf(f, "%s %s %s", lhs, op, rhs);108}109}110111static void rc_print_inline_float(FILE * f, int index)112{113int r300_exponent = (index >> 3) & 0xf;114unsigned r300_mantissa = index & 0x7;115unsigned float_exponent;116unsigned real_float;117float * print_float = (float*) &real_float;118119r300_exponent -= 7;120float_exponent = r300_exponent + 127;121real_float = (r300_mantissa << 20) | (float_exponent << 23);122123fprintf(f, "%f (0x%x)", *print_float, index);124125}126127static void rc_print_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)128{129if (file == RC_FILE_NONE) {130fprintf(f, "none");131} else if (file == RC_FILE_SPECIAL) {132switch(index) {133case RC_SPECIAL_ALU_RESULT: fprintf(f, "aluresult"); break;134default: fprintf(f, "special[%i]", index); break;135}136} else if (file == RC_FILE_INLINE) {137rc_print_inline_float(f, index);138} else {139const char * filename;140switch(file) {141case RC_FILE_TEMPORARY: filename = "temp"; break;142case RC_FILE_INPUT: filename = "input"; break;143case RC_FILE_OUTPUT: filename = "output"; break;144case RC_FILE_ADDRESS: filename = "addr"; break;145case RC_FILE_CONSTANT: filename = "const"; break;146default: filename = "BAD FILE"; break;147}148fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");149}150}151152static void rc_print_mask(FILE * f, unsigned int mask)153{154if (mask & RC_MASK_X) fprintf(f, "x");155if (mask & RC_MASK_Y) fprintf(f, "y");156if (mask & RC_MASK_Z) fprintf(f, "z");157if (mask & RC_MASK_W) fprintf(f, "w");158}159160static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)161{162rc_print_register(f, dst.File, dst.Index, 0);163if (dst.WriteMask != RC_MASK_XYZW) {164fprintf(f, ".");165rc_print_mask(f, dst.WriteMask);166}167}168169static char rc_swizzle_char(unsigned int swz)170{171switch(swz) {172case RC_SWIZZLE_X: return 'x';173case RC_SWIZZLE_Y: return 'y';174case RC_SWIZZLE_Z: return 'z';175case RC_SWIZZLE_W: return 'w';176case RC_SWIZZLE_ZERO: return '0';177case RC_SWIZZLE_ONE: return '1';178case RC_SWIZZLE_HALF: return 'H';179case RC_SWIZZLE_UNUSED: return '_';180}181fprintf(stderr, "bad swz: %u\n", swz);182return '?';183}184185static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)186{187unsigned int comp;188for(comp = 0; comp < 4; ++comp) {189rc_swizzle swz = GET_SWZ(swizzle, comp);190if (GET_BIT(negate, comp))191fprintf(f, "-");192fprintf(f, "%c", rc_swizzle_char(swz));193}194}195196static void rc_print_presub_instruction(FILE * f,197struct rc_presub_instruction inst)198{199fprintf(f,"(");200switch(inst.Opcode){201case RC_PRESUB_BIAS:202fprintf(f, "1 - 2 * ");203rc_print_register(f, inst.SrcReg[0].File,204inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);205break;206case RC_PRESUB_SUB:207rc_print_register(f, inst.SrcReg[1].File,208inst.SrcReg[1].Index,inst.SrcReg[1].RelAddr);209fprintf(f, " - ");210rc_print_register(f, inst.SrcReg[0].File,211inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);212break;213case RC_PRESUB_ADD:214rc_print_register(f, inst.SrcReg[1].File,215inst.SrcReg[1].Index,inst.SrcReg[1].RelAddr);216fprintf(f, " + ");217rc_print_register(f, inst.SrcReg[0].File,218inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);219break;220case RC_PRESUB_INV:221fprintf(f, "1 - ");222rc_print_register(f, inst.SrcReg[0].File,223inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);224break;225default:226break;227}228fprintf(f, ")");229}230231static void rc_print_src_register(FILE * f, struct rc_instruction * inst,232struct rc_src_register src)233{234int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);235236if (src.Negate == RC_MASK_XYZW)237fprintf(f, "-");238if (src.Abs)239fprintf(f, "|");240241if(src.File == RC_FILE_PRESUB)242rc_print_presub_instruction(f, inst->U.I.PreSub);243else244rc_print_register(f, src.File, src.Index, src.RelAddr);245246if (src.Abs && !trivial_negate)247fprintf(f, "|");248249if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {250fprintf(f, ".");251rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);252}253254if (src.Abs && trivial_negate)255fprintf(f, "|");256}257258static unsigned update_branch_depth(rc_opcode opcode, unsigned *branch_depth)259{260switch (opcode) {261case RC_OPCODE_IF:262case RC_OPCODE_BGNLOOP:263return (*branch_depth)++ * 2;264265case RC_OPCODE_ENDIF:266case RC_OPCODE_ENDLOOP:267assert(*branch_depth > 0);268return --(*branch_depth) * 2;269270case RC_OPCODE_ELSE:271assert(*branch_depth > 0);272return (*branch_depth - 1) * 2;273274default:275return *branch_depth * 2;276}277}278279static void rc_print_normal_instruction(FILE * f, struct rc_instruction * inst, unsigned *branch_depth)280{281const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);282unsigned int reg;283unsigned spaces = update_branch_depth(inst->U.I.Opcode, branch_depth);284285for (unsigned i = 0; i < spaces; i++)286fprintf(f, " ");287288fprintf(f, "%s", opcode->Name);289290switch(inst->U.I.SaturateMode) {291case RC_SATURATE_NONE: break;292case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;293case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;294default: fprintf(f, "_BAD_SAT"); break;295}296297if (opcode->HasDstReg) {298fprintf(f, " ");299rc_print_dst_register(f, inst->U.I.DstReg);300print_omod_op(f, inst->U.I.Omod);301if (opcode->NumSrcRegs)302fprintf(f, ",");303}304305for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {306if (reg > 0)307fprintf(f, ",");308fprintf(f, " ");309rc_print_src_register(f, inst, inst->U.I.SrcReg[reg]);310}311312if (opcode->HasTexture) {313fprintf(f, ", %s%s[%u]%s%s",314textarget_to_string(inst->U.I.TexSrcTarget),315inst->U.I.TexShadow ? "SHADOW" : "",316inst->U.I.TexSrcUnit,317inst->U.I.TexSemWait ? " SEM_WAIT" : "",318inst->U.I.TexSemAcquire ? " SEM_ACQUIRE" : "");319}320321fprintf(f, ";");322323if (inst->U.I.WriteALUResult) {324fprintf(f, " [aluresult = (");325rc_print_comparefunc(f,326(inst->U.I.WriteALUResult == RC_ALURESULT_X) ? "x" : "w",327inst->U.I.ALUResultCompare, "0");328fprintf(f, ")]");329}330331if (inst->U.I.DstReg.Pred == RC_PRED_SET) {332fprintf(f, " PRED_SET");333} else if (inst->U.I.DstReg.Pred == RC_PRED_INV) {334fprintf(f, " PRED_INV");335}336337fprintf(f, "\n");338}339340static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst, unsigned *branch_depth)341{342struct rc_pair_instruction * inst = &fullinst->U.P;343int printedsrc = 0;344unsigned spaces = update_branch_depth(inst->RGB.Opcode != RC_OPCODE_NOP ?345inst->RGB.Opcode : inst->Alpha.Opcode, branch_depth);346347for (unsigned i = 0; i < spaces; i++)348fprintf(f, " ");349350for(unsigned int src = 0; src < 3; ++src) {351if (inst->RGB.Src[src].Used) {352if (printedsrc)353fprintf(f, ", ");354fprintf(f, "src%i.xyz = ", src);355rc_print_register(f, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, 0);356printedsrc = 1;357}358if (inst->Alpha.Src[src].Used) {359if (printedsrc)360fprintf(f, ", ");361fprintf(f, "src%i.w = ", src);362rc_print_register(f, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, 0);363printedsrc = 1;364}365}366if(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Used) {367fprintf(f, ", srcp.xyz = %s",368presubtract_op_to_string(369inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index));370}371if(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) {372fprintf(f, ", srcp.w = %s",373presubtract_op_to_string(374inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index));375}376if (inst->SemWait) {377fprintf(f, " SEM_WAIT");378}379fprintf(f, "\n");380381if (inst->RGB.Opcode != RC_OPCODE_NOP) {382const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->RGB.Opcode);383384for (unsigned i = 0; i < spaces; i++)385fprintf(f, " ");386387fprintf(f, " %s%s", opcode->Name, inst->RGB.Saturate ? "_SAT" : "");388if (inst->RGB.WriteMask)389fprintf(f, " temp[%i].%s%s%s", inst->RGB.DestIndex,390(inst->RGB.WriteMask & 1) ? "x" : "",391(inst->RGB.WriteMask & 2) ? "y" : "",392(inst->RGB.WriteMask & 4) ? "z" : "");393if (inst->RGB.OutputWriteMask)394fprintf(f, " color[%i].%s%s%s", inst->RGB.Target,395(inst->RGB.OutputWriteMask & 1) ? "x" : "",396(inst->RGB.OutputWriteMask & 2) ? "y" : "",397(inst->RGB.OutputWriteMask & 4) ? "z" : "");398if (inst->WriteALUResult == RC_ALURESULT_X)399fprintf(f, " aluresult");400401print_omod_op(f, inst->RGB.Omod);402403for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) {404const char* abs = inst->RGB.Arg[arg].Abs ? "|" : "";405const char* neg = inst->RGB.Arg[arg].Negate ? "-" : "";406fprintf(f, ", %s%ssrc", neg, abs);407if(inst->RGB.Arg[arg].Source == RC_PAIR_PRESUB_SRC)408fprintf(f,"p");409else410fprintf(f,"%d", inst->RGB.Arg[arg].Source);411fprintf(f,".%c%c%c%s",412rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 0)),413rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 1)),414rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 2)),415abs);416}417fprintf(f, "\n");418}419420if (inst->Alpha.Opcode != RC_OPCODE_NOP) {421const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Alpha.Opcode);422423for (unsigned i = 0; i < spaces; i++)424fprintf(f, " ");425426fprintf(f, " %s%s", opcode->Name, inst->Alpha.Saturate ? "_SAT" : "");427if (inst->Alpha.WriteMask)428fprintf(f, " temp[%i].w", inst->Alpha.DestIndex);429if (inst->Alpha.OutputWriteMask)430fprintf(f, " color[%i].w", inst->Alpha.Target);431if (inst->Alpha.DepthWriteMask)432fprintf(f, " depth.w");433if (inst->WriteALUResult == RC_ALURESULT_W)434fprintf(f, " aluresult");435436print_omod_op(f, inst->Alpha.Omod);437438for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) {439const char* abs = inst->Alpha.Arg[arg].Abs ? "|" : "";440const char* neg = inst->Alpha.Arg[arg].Negate ? "-" : "";441fprintf(f, ", %s%ssrc", neg, abs);442if(inst->Alpha.Arg[arg].Source == RC_PAIR_PRESUB_SRC)443fprintf(f,"p");444else445fprintf(f,"%d", inst->Alpha.Arg[arg].Source);446fprintf(f,".%c%s",447rc_swizzle_char(GET_SWZ(inst->Alpha.Arg[arg].Swizzle, 0)), abs);448}449fprintf(f, "\n");450}451452if (inst->WriteALUResult) {453for (unsigned i = 0; i < spaces; i++)454fprintf(f, " ");455456fprintf(f, " [aluresult = (");457rc_print_comparefunc(f, "result", inst->ALUResultCompare, "0");458fprintf(f, ")]\n");459}460}461462/**463* Print program to stderr, default options.464*/465void rc_print_program(const struct rc_program *prog)466{467unsigned int linenum = 0;468unsigned branch_depth = 0;469struct rc_instruction *inst;470471fprintf(stderr, "# Radeon Compiler Program\n");472473for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {474fprintf(stderr, "%3d: ", linenum);475476if (inst->Type == RC_INSTRUCTION_PAIR)477rc_print_pair_instruction(stderr, inst, &branch_depth);478else479rc_print_normal_instruction(stderr, inst, &branch_depth);480481linenum++;482}483}484485486