Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2009 Nicolai Haehnle.
      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 #ifndef RADEON_OPCODES_H
     29 #define RADEON_OPCODES_H
     30 
     31 #include <assert.h>
     32 
     33 /**
     34  * Opcodes understood by the Radeon compiler.
     35  */
     36 typedef enum {
     37 	RC_OPCODE_NOP = 0,
     38 	RC_OPCODE_ILLEGAL_OPCODE,
     39 
     40 	/** vec4 instruction: dst.c = abs(src0.c); */
     41 	RC_OPCODE_ABS,
     42 
     43 	/** vec4 instruction: dst.c = src0.c + src1.c; */
     44 	RC_OPCODE_ADD,
     45 
     46 	/** special instruction: load address register
     47 	 * dst.x = floor(src.x), where dst must be an address register */
     48 	RC_OPCODE_ARL,
     49 
     50 	/** special instruction: load address register with round
     51 	 * dst.x = round(src.x), where dst must be an address register */
     52 	RC_OPCODE_ARR,
     53 
     54 	/** vec4 instruction: dst.c = ceil(src0.c) */
     55 	RC_OPCODE_CEIL,
     56 
     57 	/** vec4 instruction: dst.c = clamp(src0.c, src1.c, src2.c) */
     58 	RC_OPCODE_CLAMP,
     59 
     60 	/** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */
     61 	RC_OPCODE_CMP,
     62 
     63 	/** vec4 instruction: dst.c = src2.c > 0.5 ? src0.c : src1.c */
     64 	RC_OPCODE_CND,
     65 
     66 	/** scalar instruction: dst = cos(src0.x) */
     67 	RC_OPCODE_COS,
     68 
     69 	/** special instruction: take vec4 partial derivative in X direction
     70 	 * dst.c = d src0.c / dx */
     71 	RC_OPCODE_DDX,
     72 
     73 	/** special instruction: take vec4 partial derivative in Y direction
     74 	 * dst.c = d src0.c / dy */
     75 	RC_OPCODE_DDY,
     76 
     77 	/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y */
     78 	RC_OPCODE_DP2,
     79 
     80 	/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z */
     81 	RC_OPCODE_DP3,
     82 
     83 	/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z + src0.w*src1.w */
     84 	RC_OPCODE_DP4,
     85 
     86 	/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z + src1.w */
     87 	RC_OPCODE_DPH,
     88 
     89 	/** special instruction, see ARB_fragment_program */
     90 	RC_OPCODE_DST,
     91 
     92 	/** scalar instruction: dst = 2**src0.x */
     93 	RC_OPCODE_EX2,
     94 
     95 	/** special instruction, see ARB_vertex_program */
     96 	RC_OPCODE_EXP,
     97 
     98 	/** vec4 instruction: dst.c = floor(src0.c) */
     99 	RC_OPCODE_FLR,
    100 
    101 	/** vec4 instruction: dst.c = src0.c - floor(src0.c) */
    102 	RC_OPCODE_FRC,
    103 
    104 	/** special instruction: stop execution if any component of src0 is negative */
    105 	RC_OPCODE_KIL,
    106 
    107 	/** scalar instruction: dst = log_2(src0.x) */
    108 	RC_OPCODE_LG2,
    109 
    110 	/** special instruction, see ARB_vertex_program */
    111 	RC_OPCODE_LIT,
    112 
    113 	/** special instruction, see ARB_vertex_program */
    114 	RC_OPCODE_LOG,
    115 
    116 	/** vec4 instruction: dst.c = src0.c*src1.c + (1 - src0.c)*src2.c */
    117 	RC_OPCODE_LRP,
    118 
    119 	/** vec4 instruction: dst.c = src0.c*src1.c + src2.c */
    120 	RC_OPCODE_MAD,
    121 
    122 	/** vec4 instruction: dst.c = max(src0.c, src1.c) */
    123 	RC_OPCODE_MAX,
    124 
    125 	/** vec4 instruction: dst.c = min(src0.c, src1.c) */
    126 	RC_OPCODE_MIN,
    127 
    128 	/** vec4 instruction: dst.c = src0.c */
    129 	RC_OPCODE_MOV,
    130 
    131 	/** vec4 instruction: dst.c = src0.c*src1.c */
    132 	RC_OPCODE_MUL,
    133 
    134 	/** scalar instruction: dst = src0.x ** src1.x */
    135 	RC_OPCODE_POW,
    136 
    137 	/** scalar instruction: dst = 1 / src0.x */
    138 	RC_OPCODE_RCP,
    139 
    140 	/** vec4 instruction: dst.c = floor(src0.c + 0.5) */
    141 	RC_OPCODE_ROUND,
    142 
    143 	/** scalar instruction: dst = 1 / sqrt(src0.x) */
    144 	RC_OPCODE_RSQ,
    145 
    146 	/** special instruction, see ARB_fragment_program */
    147 	RC_OPCODE_SCS,
    148 
    149 	/** vec4 instruction: dst.c = (src0.c == src1.c) ? 1.0 : 0.0 */
    150 	RC_OPCODE_SEQ,
    151 
    152 	/** vec4 instruction: dst.c = 0.0 */
    153 	RC_OPCODE_SFL,
    154 
    155 	/** vec4 instruction: dst.c = (src0.c >= src1.c) ? 1.0 : 0.0 */
    156 	RC_OPCODE_SGE,
    157 
    158 	/** vec4 instruction: dst.c = (src0.c > src1.c) ? 1.0 : 0.0 */
    159 	RC_OPCODE_SGT,
    160 
    161 	/** scalar instruction: dst = sin(src0.x) */
    162 	RC_OPCODE_SIN,
    163 
    164 	/** vec4 instruction: dst.c = (src0.c <= src1.c) ? 1.0 : 0.0 */
    165 	RC_OPCODE_SLE,
    166 
    167 	/** vec4 instruction: dst.c = (src0.c < src1.c) ? 1.0 : 0.0 */
    168 	RC_OPCODE_SLT,
    169 
    170 	/** vec4 instruction: dst.c = (src0.c != src1.c) ? 1.0 : 0.0 */
    171 	RC_OPCODE_SNE,
    172 
    173 	/** vec4 instruction: dst.c = (src0.c < 0 ?) -1 : ((src0.c > 0) : 1 : 0) */
    174 	RC_OPCODE_SSG,
    175 
    176 	/** vec4 instruction: dst.c = src0.c - src1.c */
    177 	RC_OPCODE_SUB,
    178 
    179 	/** vec4 instruction: dst.c = src0.c */
    180 	RC_OPCODE_SWZ,
    181 
    182 	/** vec4 instruction: dst.c = (abs(src0.c) - fract(abs(src0.c))) * sgn(src0.c) */
    183 	RC_OPCODE_TRUNC,
    184 
    185 	/** special instruction, see ARB_fragment_program */
    186 	RC_OPCODE_XPD,
    187 
    188 	RC_OPCODE_TEX,
    189 	RC_OPCODE_TXB,
    190 	RC_OPCODE_TXD,
    191 	RC_OPCODE_TXL,
    192 	RC_OPCODE_TXP,
    193 
    194 	/** branch instruction:
    195 	 * If src0.x != 0.0, continue with the next instruction;
    196 	 * otherwise, jump to matching RC_OPCODE_ELSE or RC_OPCODE_ENDIF.
    197 	 */
    198 	RC_OPCODE_IF,
    199 
    200 	/** branch instruction: jump to matching RC_OPCODE_ENDIF */
    201 	RC_OPCODE_ELSE,
    202 
    203 	/** branch instruction: has no effect */
    204 	RC_OPCODE_ENDIF,
    205 
    206 	RC_OPCODE_BGNLOOP,
    207 
    208 	RC_OPCODE_BRK,
    209 
    210 	RC_OPCODE_ENDLOOP,
    211 
    212 	RC_OPCODE_CONT,
    213 
    214 	/** special instruction, used in R300-R500 fragment program pair instructions
    215 	 * indicates that the result of the alpha operation shall be replicated
    216 	 * across all other channels */
    217 	RC_OPCODE_REPL_ALPHA,
    218 
    219 	/** special instruction, used in R300-R500 fragment programs
    220 	 * to indicate the start of a block of texture instructions that
    221 	 * can run simultaneously. */
    222 	RC_OPCODE_BEGIN_TEX,
    223 
    224 	/** Stop execution of the shader (GLSL discard) */
    225 	RC_OPCODE_KILP,
    226 
    227 	/* Vertex shader CF Instructions */
    228 	RC_ME_PRED_SEQ,
    229 	RC_ME_PRED_SGT,
    230 	RC_ME_PRED_SGE,
    231 	RC_ME_PRED_SNEQ,
    232 	RC_ME_PRED_SET_CLR,
    233 	RC_ME_PRED_SET_INV,
    234 	RC_ME_PRED_SET_POP,
    235 	RC_ME_PRED_SET_RESTORE,
    236 
    237 	RC_VE_PRED_SEQ_PUSH,
    238 	RC_VE_PRED_SGT_PUSH,
    239 	RC_VE_PRED_SGE_PUSH,
    240 	RC_VE_PRED_SNEQ_PUSH,
    241 
    242 	MAX_RC_OPCODE
    243 } rc_opcode;
    244 
    245 
    246 struct rc_opcode_info {
    247 	rc_opcode Opcode;
    248 	const char * Name;
    249 
    250 	/** true if the instruction reads from a texture.
    251 	 *
    252 	 * \note This is false for the KIL instruction, even though KIL is
    253 	 * a texture instruction from a hardware point of view. */
    254 	unsigned int HasTexture:1;
    255 
    256 	unsigned int NumSrcRegs:2;
    257 	unsigned int HasDstReg:1;
    258 
    259 	/** true if this instruction affects control flow */
    260 	unsigned int IsFlowControl:1;
    261 
    262 	/** true if this is a vector instruction that operates on components in parallel
    263 	 * without any cross-component interaction */
    264 	unsigned int IsComponentwise:1;
    265 
    266 	/** true if this instruction sources only its operands X components
    267 	 * to compute one result which is smeared across all output channels */
    268 	unsigned int IsStandardScalar:1;
    269 };
    270 
    271 extern struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE];
    272 
    273 static inline const struct rc_opcode_info * rc_get_opcode_info(rc_opcode opcode)
    274 {
    275 	assert((unsigned int)opcode < MAX_RC_OPCODE);
    276 	assert(rc_opcodes[opcode].Opcode == opcode);
    277 
    278 	return &rc_opcodes[opcode];
    279 }
    280 
    281 struct rc_instruction;
    282 
    283 void rc_compute_sources_for_writemask(
    284 		const struct rc_instruction *inst,
    285 		unsigned int writemask,
    286 		unsigned int *srcmasks);
    287 
    288 #endif /* RADEON_OPCODES_H */
    289