"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/r300/compiler/radeon_program_print.c" (16 Sep 2020, 13659 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "radeon_program_print.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
    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  * on the rights to use, copy, modify, merge, publish, distribute, sub
    8  * license, and/or sell copies of the Software, and to permit persons to whom
    9  * the Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
   18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
   19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
   20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
   21  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
   22 
   23 #include "radeon_program.h"
   24 
   25 #include <stdio.h>
   26 
   27 static const char * textarget_to_string(rc_texture_target target)
   28 {
   29     switch(target) {
   30     case RC_TEXTURE_2D_ARRAY: return "2D_ARRAY";
   31     case RC_TEXTURE_1D_ARRAY: return "1D_ARRAY";
   32     case RC_TEXTURE_CUBE: return "CUBE";
   33     case RC_TEXTURE_3D: return "3D";
   34     case RC_TEXTURE_RECT: return "RECT";
   35     case RC_TEXTURE_2D: return "2D";
   36     case RC_TEXTURE_1D: return "1D";
   37     default: return "BAD_TEXTURE_TARGET";
   38     }
   39 }
   40 
   41 static const char * presubtract_op_to_string(rc_presubtract_op op)
   42 {
   43     switch(op) {
   44     case RC_PRESUB_NONE:
   45         return "NONE";
   46     case RC_PRESUB_BIAS:
   47         return "(1 - 2 * src0)";
   48     case RC_PRESUB_SUB:
   49         return "(src1 - src0)";
   50     case RC_PRESUB_ADD:
   51         return "(src1 + src0)";
   52     case RC_PRESUB_INV:
   53         return "(1 - src0)";
   54     default:
   55         return "BAD_PRESUBTRACT_OP";
   56     }
   57 }
   58 
   59 static void print_omod_op(FILE * f, rc_omod_op op)
   60 {
   61     const char * omod_str;
   62 
   63     switch(op) {
   64     case RC_OMOD_MUL_1:
   65     case RC_OMOD_DISABLE:
   66         return;
   67     case RC_OMOD_MUL_2:
   68         omod_str = "* 2";
   69         break;
   70     case RC_OMOD_MUL_4:
   71         omod_str = "* 4";
   72         break;
   73     case RC_OMOD_MUL_8:
   74         omod_str = "* 8";
   75         break;
   76     case RC_OMOD_DIV_2:
   77         omod_str = "/ 2";
   78         break;
   79     case RC_OMOD_DIV_4:
   80         omod_str = "/ 4";
   81         break;
   82     case RC_OMOD_DIV_8:
   83         omod_str = "/ 8";
   84         break;
   85     default:
   86         return;
   87     }
   88     fprintf(f, " %s", omod_str);
   89 }
   90 
   91 static void rc_print_comparefunc(FILE * f, const char * lhs, rc_compare_func func, const char * rhs)
   92 {
   93     if (func == RC_COMPARE_FUNC_NEVER) {
   94         fprintf(f, "false");
   95     } else if (func == RC_COMPARE_FUNC_ALWAYS) {
   96         fprintf(f, "true");
   97     } else {
   98         const char * op;
   99         switch(func) {
  100         case RC_COMPARE_FUNC_LESS: op = "<"; break;
  101         case RC_COMPARE_FUNC_EQUAL: op = "=="; break;
  102         case RC_COMPARE_FUNC_LEQUAL: op = "<="; break;
  103         case RC_COMPARE_FUNC_GREATER: op = ">"; break;
  104         case RC_COMPARE_FUNC_NOTEQUAL: op = "!="; break;
  105         case RC_COMPARE_FUNC_GEQUAL: op = ">="; break;
  106         default: op = "???"; break;
  107         }
  108         fprintf(f, "%s %s %s", lhs, op, rhs);
  109     }
  110 }
  111 
  112 static void rc_print_inline_float(FILE * f, int index)
  113 {
  114     int r300_exponent = (index >> 3) & 0xf;
  115     unsigned r300_mantissa = index & 0x7;
  116     unsigned float_exponent;
  117     unsigned real_float;
  118     float * print_float = (float*) &real_float;
  119 
  120     r300_exponent -= 7;
  121     float_exponent = r300_exponent + 127;
  122     real_float = (r300_mantissa << 20) | (float_exponent << 23);
  123 
  124     fprintf(f, "%f (0x%x)", *print_float, index);
  125 
  126 }
  127 
  128 static void rc_print_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)
  129 {
  130     if (file == RC_FILE_NONE) {
  131         fprintf(f, "none");
  132     } else if (file == RC_FILE_SPECIAL) {
  133         switch(index) {
  134         case RC_SPECIAL_ALU_RESULT: fprintf(f, "aluresult"); break;
  135         default: fprintf(f, "special[%i]", index); break;
  136         }
  137     } else if (file == RC_FILE_INLINE) {
  138         rc_print_inline_float(f, index);
  139     } else {
  140         const char * filename;
  141         switch(file) {
  142         case RC_FILE_TEMPORARY: filename = "temp"; break;
  143         case RC_FILE_INPUT: filename = "input"; break;
  144         case RC_FILE_OUTPUT: filename = "output"; break;
  145         case RC_FILE_ADDRESS: filename = "addr"; break;
  146         case RC_FILE_CONSTANT: filename = "const"; break;
  147         default: filename = "BAD FILE"; break;
  148         }
  149         fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");
  150     }
  151 }
  152 
  153 static void rc_print_mask(FILE * f, unsigned int mask)
  154 {
  155     if (mask & RC_MASK_X) fprintf(f, "x");
  156     if (mask & RC_MASK_Y) fprintf(f, "y");
  157     if (mask & RC_MASK_Z) fprintf(f, "z");
  158     if (mask & RC_MASK_W) fprintf(f, "w");
  159 }
  160 
  161 static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)
  162 {
  163     rc_print_register(f, dst.File, dst.Index, 0);
  164     if (dst.WriteMask != RC_MASK_XYZW) {
  165         fprintf(f, ".");
  166         rc_print_mask(f, dst.WriteMask);
  167     }
  168 }
  169 
  170 static char rc_swizzle_char(unsigned int swz)
  171 {
  172     switch(swz) {
  173     case RC_SWIZZLE_X: return 'x';
  174     case RC_SWIZZLE_Y: return 'y';
  175     case RC_SWIZZLE_Z: return 'z';
  176     case RC_SWIZZLE_W: return 'w';
  177     case RC_SWIZZLE_ZERO: return '0';
  178     case RC_SWIZZLE_ONE: return '1';
  179     case RC_SWIZZLE_HALF: return 'H';
  180     case RC_SWIZZLE_UNUSED: return '_';
  181     }
  182     fprintf(stderr, "bad swz: %u\n", swz);
  183     return '?';
  184 }
  185 
  186 static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)
  187 {
  188     unsigned int comp;
  189     for(comp = 0; comp < 4; ++comp) {
  190         rc_swizzle swz = GET_SWZ(swizzle, comp);
  191         if (GET_BIT(negate, comp))
  192             fprintf(f, "-");
  193         fprintf(f, "%c", rc_swizzle_char(swz));
  194     }
  195 }
  196 
  197 static void rc_print_presub_instruction(FILE * f,
  198                     struct rc_presub_instruction inst)
  199 {
  200     fprintf(f,"(");
  201     switch(inst.Opcode){
  202     case RC_PRESUB_BIAS:
  203         fprintf(f, "1 - 2 * ");
  204         rc_print_register(f, inst.SrcReg[0].File,
  205                 inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);
  206         break;
  207     case RC_PRESUB_SUB:
  208         rc_print_register(f, inst.SrcReg[1].File,
  209                 inst.SrcReg[1].Index,inst.SrcReg[1].RelAddr);
  210         fprintf(f, " - ");
  211         rc_print_register(f, inst.SrcReg[0].File,
  212                 inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);
  213         break;
  214     case RC_PRESUB_ADD:
  215         rc_print_register(f, inst.SrcReg[1].File,
  216                 inst.SrcReg[1].Index,inst.SrcReg[1].RelAddr);
  217         fprintf(f, " + ");
  218         rc_print_register(f, inst.SrcReg[0].File,
  219                 inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);
  220         break;
  221     case RC_PRESUB_INV:
  222         fprintf(f, "1 - ");
  223         rc_print_register(f, inst.SrcReg[0].File,
  224                 inst.SrcReg[0].Index,inst.SrcReg[0].RelAddr);
  225         break;
  226     default:
  227         break;
  228     }
  229     fprintf(f, ")");
  230 }
  231 
  232 static void rc_print_src_register(FILE * f, struct rc_instruction * inst,
  233                         struct rc_src_register src)
  234 {
  235     int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);
  236 
  237     if (src.Negate == RC_MASK_XYZW)
  238         fprintf(f, "-");
  239     if (src.Abs)
  240         fprintf(f, "|");
  241 
  242     if(src.File == RC_FILE_PRESUB)
  243         rc_print_presub_instruction(f, inst->U.I.PreSub);
  244     else
  245         rc_print_register(f, src.File, src.Index, src.RelAddr);
  246 
  247     if (src.Abs && !trivial_negate)
  248         fprintf(f, "|");
  249 
  250     if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {
  251         fprintf(f, ".");
  252         rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);
  253     }
  254 
  255     if (src.Abs && trivial_negate)
  256         fprintf(f, "|");
  257 }
  258 
  259 static unsigned update_branch_depth(rc_opcode opcode, unsigned *branch_depth)
  260 {
  261     switch (opcode) {
  262     case RC_OPCODE_IF:
  263     case RC_OPCODE_BGNLOOP:
  264         return (*branch_depth)++ * 2;
  265 
  266     case RC_OPCODE_ENDIF:
  267     case RC_OPCODE_ENDLOOP:
  268         assert(*branch_depth > 0);
  269         return --(*branch_depth) * 2;
  270 
  271     case RC_OPCODE_ELSE:
  272         assert(*branch_depth > 0);
  273         return (*branch_depth - 1) * 2;
  274 
  275     default:
  276         return *branch_depth * 2;
  277     }
  278 }
  279 
  280 static void rc_print_normal_instruction(FILE * f, struct rc_instruction * inst, unsigned *branch_depth)
  281 {
  282     const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
  283     unsigned int reg;
  284     unsigned spaces = update_branch_depth(inst->U.I.Opcode, branch_depth);
  285 
  286     for (unsigned i = 0; i < spaces; i++)
  287         fprintf(f, " ");
  288 
  289     fprintf(f, "%s", opcode->Name);
  290 
  291     switch(inst->U.I.SaturateMode) {
  292     case RC_SATURATE_NONE: break;
  293     case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;
  294     case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;
  295     default: fprintf(f, "_BAD_SAT"); break;
  296     }
  297 
  298     if (opcode->HasDstReg) {
  299         fprintf(f, " ");
  300         rc_print_dst_register(f, inst->U.I.DstReg);
  301         print_omod_op(f, inst->U.I.Omod);
  302         if (opcode->NumSrcRegs)
  303             fprintf(f, ",");
  304     }
  305 
  306     for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
  307         if (reg > 0)
  308             fprintf(f, ",");
  309         fprintf(f, " ");
  310         rc_print_src_register(f, inst, inst->U.I.SrcReg[reg]);
  311     }
  312 
  313     if (opcode->HasTexture) {
  314         fprintf(f, ", %s%s[%u]%s%s",
  315             textarget_to_string(inst->U.I.TexSrcTarget),
  316             inst->U.I.TexShadow ? "SHADOW" : "",
  317             inst->U.I.TexSrcUnit,
  318             inst->U.I.TexSemWait ? " SEM_WAIT" : "",
  319             inst->U.I.TexSemAcquire ? " SEM_ACQUIRE" : "");
  320     }
  321 
  322     fprintf(f, ";");
  323 
  324     if (inst->U.I.WriteALUResult) {
  325         fprintf(f, " [aluresult = (");
  326         rc_print_comparefunc(f,
  327             (inst->U.I.WriteALUResult == RC_ALURESULT_X) ? "x" : "w",
  328             inst->U.I.ALUResultCompare, "0");
  329         fprintf(f, ")]");
  330     }
  331 
  332     if (inst->U.I.DstReg.Pred == RC_PRED_SET) {
  333         fprintf(f, " PRED_SET");
  334     } else if (inst->U.I.DstReg.Pred == RC_PRED_INV) {
  335         fprintf(f, " PRED_INV");
  336     }
  337 
  338     fprintf(f, "\n");
  339 }
  340 
  341 static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst, unsigned *branch_depth)
  342 {
  343     struct rc_pair_instruction * inst = &fullinst->U.P;
  344     int printedsrc = 0;
  345     unsigned spaces = update_branch_depth(inst->RGB.Opcode != RC_OPCODE_NOP ?
  346                           inst->RGB.Opcode : inst->Alpha.Opcode, branch_depth);
  347 
  348     for (unsigned i = 0; i < spaces; i++)
  349         fprintf(f, " ");
  350 
  351     for(unsigned int src = 0; src < 3; ++src) {
  352         if (inst->RGB.Src[src].Used) {
  353             if (printedsrc)
  354                 fprintf(f, ", ");
  355             fprintf(f, "src%i.xyz = ", src);
  356             rc_print_register(f, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, 0);
  357             printedsrc = 1;
  358         }
  359         if (inst->Alpha.Src[src].Used) {
  360             if (printedsrc)
  361                 fprintf(f, ", ");
  362             fprintf(f, "src%i.w = ", src);
  363             rc_print_register(f, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, 0);
  364             printedsrc = 1;
  365         }
  366     }
  367     if(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Used) {
  368         fprintf(f, ", srcp.xyz = %s",
  369             presubtract_op_to_string(
  370                     inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index));
  371     }
  372     if(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) {
  373         fprintf(f, ", srcp.w = %s",
  374             presubtract_op_to_string(
  375                     inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index));
  376     }
  377     if (inst->SemWait) {
  378         fprintf(f, " SEM_WAIT");
  379     }
  380     fprintf(f, "\n");
  381 
  382     if (inst->RGB.Opcode != RC_OPCODE_NOP) {
  383         const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->RGB.Opcode);
  384 
  385         for (unsigned i = 0; i < spaces; i++)
  386             fprintf(f, " ");
  387 
  388         fprintf(f, "     %s%s", opcode->Name, inst->RGB.Saturate ? "_SAT" : "");
  389         if (inst->RGB.WriteMask)
  390             fprintf(f, " temp[%i].%s%s%s", inst->RGB.DestIndex,
  391                 (inst->RGB.WriteMask & 1) ? "x" : "",
  392                 (inst->RGB.WriteMask & 2) ? "y" : "",
  393                 (inst->RGB.WriteMask & 4) ? "z" : "");
  394         if (inst->RGB.OutputWriteMask)
  395             fprintf(f, " color[%i].%s%s%s", inst->RGB.Target,
  396                 (inst->RGB.OutputWriteMask & 1) ? "x" : "",
  397                 (inst->RGB.OutputWriteMask & 2) ? "y" : "",
  398                 (inst->RGB.OutputWriteMask & 4) ? "z" : "");
  399         if (inst->WriteALUResult == RC_ALURESULT_X)
  400             fprintf(f, " aluresult");
  401 
  402         print_omod_op(f, inst->RGB.Omod);
  403 
  404         for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) {
  405             const char* abs = inst->RGB.Arg[arg].Abs ? "|" : "";
  406             const char* neg = inst->RGB.Arg[arg].Negate ? "-" : "";
  407             fprintf(f, ", %s%ssrc", neg, abs);
  408             if(inst->RGB.Arg[arg].Source == RC_PAIR_PRESUB_SRC)
  409                 fprintf(f,"p");
  410             else
  411                 fprintf(f,"%d", inst->RGB.Arg[arg].Source);
  412             fprintf(f,".%c%c%c%s",
  413                 rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 0)),
  414                 rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 1)),
  415                 rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 2)),
  416                 abs);
  417         }
  418         fprintf(f, "\n");
  419     }
  420 
  421     if (inst->Alpha.Opcode != RC_OPCODE_NOP) {
  422         const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Alpha.Opcode);
  423 
  424         for (unsigned i = 0; i < spaces; i++)
  425             fprintf(f, " ");
  426 
  427         fprintf(f, "     %s%s", opcode->Name, inst->Alpha.Saturate ? "_SAT" : "");
  428         if (inst->Alpha.WriteMask)
  429             fprintf(f, " temp[%i].w", inst->Alpha.DestIndex);
  430         if (inst->Alpha.OutputWriteMask)
  431             fprintf(f, " color[%i].w", inst->Alpha.Target);
  432         if (inst->Alpha.DepthWriteMask)
  433             fprintf(f, " depth.w");
  434         if (inst->WriteALUResult == RC_ALURESULT_W)
  435             fprintf(f, " aluresult");
  436 
  437         print_omod_op(f, inst->Alpha.Omod);
  438 
  439         for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) {
  440             const char* abs = inst->Alpha.Arg[arg].Abs ? "|" : "";
  441             const char* neg = inst->Alpha.Arg[arg].Negate ? "-" : "";
  442             fprintf(f, ", %s%ssrc", neg, abs);
  443             if(inst->Alpha.Arg[arg].Source == RC_PAIR_PRESUB_SRC)
  444                 fprintf(f,"p");
  445             else
  446                 fprintf(f,"%d", inst->Alpha.Arg[arg].Source);
  447             fprintf(f,".%c%s",
  448                 rc_swizzle_char(GET_SWZ(inst->Alpha.Arg[arg].Swizzle, 0)), abs);
  449         }
  450         fprintf(f, "\n");
  451     }
  452 
  453     if (inst->WriteALUResult) {
  454         for (unsigned i = 0; i < spaces; i++)
  455             fprintf(f, " ");
  456 
  457         fprintf(f, "      [aluresult = (");
  458         rc_print_comparefunc(f, "result", inst->ALUResultCompare, "0");
  459         fprintf(f, ")]\n");
  460     }
  461 }
  462 
  463 /**
  464  * Print program to stderr, default options.
  465  */
  466 void rc_print_program(const struct rc_program *prog)
  467 {
  468     unsigned int linenum = 0;
  469     unsigned branch_depth = 0;
  470     struct rc_instruction *inst;
  471 
  472     fprintf(stderr, "# Radeon Compiler Program\n");
  473 
  474     for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
  475         fprintf(stderr, "%3d: ", linenum);
  476 
  477         if (inst->Type == RC_INSTRUCTION_PAIR)
  478             rc_print_pair_instruction(stderr, inst, &branch_depth);
  479         else
  480             rc_print_normal_instruction(stderr, inst, &branch_depth);
  481 
  482         linenum++;
  483     }
  484 }