1 /* 2 * Copyright 2008 Nicolai Haehnle. 3 * SPDX-License-Identifier: MIT 4 */ 5 6 #ifndef __RADEON_PROGRAM_H_ 7 #define __RADEON_PROGRAM_H_ 8 9 #include <stdint.h> 10 #include <string.h> 11 12 #include "radeon_code.h" 13 #include "radeon_opcodes.h" 14 #include "radeon_program_constants.h" 15 #include "radeon_program_pair.h" 16 17 struct radeon_compiler; 18 19 struct rc_src_register { 20 unsigned int File : 4; 21 22 /** Negative values may be used for relative addressing. */ 23 unsigned int Index : RC_REGISTER_INDEX_BITS; 24 unsigned int RelAddr : 1; 25 26 unsigned int Swizzle : 12; 27 28 /** Take the component-wise absolute value */ 29 unsigned int Abs : 1; 30 31 /** Post-Abs negation. */ 32 unsigned int Negate : 4; 33 }; 34 35 struct rc_dst_register { 36 unsigned int File : 3; 37 unsigned int Index : RC_REGISTER_INDEX_BITS; 38 unsigned int WriteMask : 4; 39 unsigned int Pred : 2; 40 }; 41 42 struct rc_presub_instruction { 43 rc_presubtract_op Opcode; 44 struct rc_src_register SrcReg[2]; 45 }; 46 47 /** 48 * Instructions are maintained by the compiler in a doubly linked list 49 * of these structures. 50 * 51 * This instruction format is intended to be expanded for hardware-specific 52 * trickery. At different stages of compilation, a different set of 53 * instruction types may be valid. 54 */ 55 struct rc_sub_instruction { 56 struct rc_src_register SrcReg[3]; 57 struct rc_dst_register DstReg; 58 59 /** 60 * Opcode of this instruction, according to \ref rc_opcode enums. 61 */ 62 unsigned int Opcode : 8; 63 64 /** 65 * Saturate each value of the result to the range [0,1] or [-1,1], 66 * according to \ref rc_saturate_mode enums. 67 */ 68 unsigned int SaturateMode : 2; 69 70 /** 71 * Writing to the special register RC_SPECIAL_ALU_RESULT 72 */ 73 /*@{*/ 74 unsigned int WriteALUResult : 2; 75 unsigned int ALUResultCompare : 3; 76 /*@}*/ 77 78 /** 79 * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions. 80 */ 81 /*@{*/ 82 /** Source texture unit. */ 83 unsigned int TexSrcUnit : 5; 84 85 /** Source texture target, one of the \ref rc_texture_target enums */ 86 unsigned int TexSrcTarget : 3; 87 88 /** True if tex instruction should do shadow comparison */ 89 unsigned int TexShadow : 1; 90 91 /**/ 92 unsigned int TexSemWait : 1; 93 unsigned int TexSemAcquire : 1; 94 95 /**R500 Only. How to swizzle the result of a TEX lookup*/ 96 unsigned int TexSwizzle : 12; 97 /*@}*/ 98 99 /** This holds information about the presubtract operation used by 100 * this instruction. */ 101 struct rc_presub_instruction PreSub; 102 103 rc_omod_op Omod; 104 }; 105 106 typedef enum { RC_INSTRUCTION_NORMAL = 0, RC_INSTRUCTION_PAIR } rc_instruction_type; 107 108 struct rc_instruction { 109 struct rc_instruction *Prev; 110 struct rc_instruction *Next; 111 112 rc_instruction_type Type; 113 union { 114 struct rc_sub_instruction I; 115 struct rc_pair_instruction P; 116 } U; 117 118 /** 119 * Warning: IPs are not stable. If you want to use them, 120 * you need to recompute them at the beginning of each pass 121 * using \ref rc_recompute_ips 122 */ 123 unsigned int IP; 124 }; 125 126 struct rc_program { 127 /** 128 * Instructions.Next points to the first instruction, 129 * Instructions.Prev points to the last instruction. 130 */ 131 struct rc_instruction Instructions; 132 133 /* Long term, we should probably remove InputsRead & OutputsWritten, 134 * since updating dependent state can be fragile, and they aren't 135 * actually used very often. */ 136 uint32_t InputsRead; 137 uint32_t OutputsWritten; 138 139 struct rc_constant_list Constants; 140 }; 141 142 /** 143 * A transformation that can be passed to \ref rc_local_transform. 144 * 145 * The function will be called once for each instruction. 146 * It has to either emit the appropriate transformed code for the instruction 147 * and return true, or return false if it doesn't understand the 148 * instruction. 149 * 150 * The function gets passed the userData as last parameter. 151 */ 152 struct radeon_program_transformation { 153 int (*function)(struct radeon_compiler *, struct rc_instruction *, void *); 154 void *userData; 155 }; 156 157 void rc_local_transform(struct radeon_compiler *c, void *user); 158 159 void rc_get_used_temporaries(struct radeon_compiler *c, unsigned char *used, 160 unsigned int used_length); 161 162 int rc_find_free_temporary_list(struct radeon_compiler *c, unsigned char *used, 163 unsigned int used_length, unsigned int mask); 164 165 unsigned int rc_find_free_temporary(struct radeon_compiler *c); 166 167 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler *c); 168 struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler *c, 169 struct rc_instruction *after); 170 void rc_insert_instruction(struct rc_instruction *after, struct rc_instruction *inst); 171 void rc_remove_instruction(struct rc_instruction *inst); 172 173 unsigned int rc_recompute_ips(struct radeon_compiler *c); 174 175 void rc_print_program(const struct rc_program *prog); 176 177 rc_swizzle rc_mask_to_swizzle(unsigned int mask); 178 #endif 179