1 /************************************************************************** 2 * 3 * Copyright 2010 Luca Barbieri 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 #include "sm4.h" 28 29 // TODO: we should fix this to output the same syntax as fxc, if sm4_dump_short_syntax is set 30 31 bool sm4_dump_short_syntax = true; 32 33 std::ostream& operator <<(std::ostream& out, const sm4_op& op) 34 { 35 if(op.neg) 36 out << '-'; 37 if(op.abs) 38 out << '|'; 39 if(op.file == SM4_FILE_IMMEDIATE32) 40 { 41 out << "l("; 42 for(unsigned i = 0; i < op.comps; ++i) 43 { 44 if(i) 45 out << ", "; 46 out << op.imm_values[i].f32; 47 } 48 out << ")"; 49 } 50 else if(op.file == SM4_FILE_IMMEDIATE64) 51 { 52 out << "d("; 53 for(unsigned i = 0; i < op.comps; ++i) 54 { 55 if(i) 56 out << ", "; 57 out << op.imm_values[i].f64; 58 } 59 out << ")"; 60 return out; 61 } 62 else 63 { 64 bool naked = false; 65 if(sm4_dump_short_syntax) 66 { 67 switch(op.file) 68 { 69 case SM4_FILE_TEMP: 70 case SM4_FILE_INPUT: 71 case SM4_FILE_OUTPUT: 72 case SM4_FILE_CONSTANT_BUFFER: 73 case SM4_FILE_INDEXABLE_TEMP: 74 case SM4_FILE_UNORDERED_ACCESS_VIEW: 75 case SM4_FILE_THREAD_GROUP_SHARED_MEMORY: 76 naked = true; 77 break; 78 default: 79 naked = false; 80 break; 81 } 82 } 83 84 out << (sm4_dump_short_syntax ? sm4_shortfile_names : sm4_file_names)[op.file]; 85 86 if(op.indices[0].reg.get()) 87 naked = false; 88 89 for(unsigned i = 0; i < op.num_indices; ++i) 90 { 91 if(!naked || i) 92 out << '['; 93 if(op.indices[i].reg.get()) 94 { 95 out << *op.indices[i].reg; 96 if(op.indices[i].disp) 97 out << '+' << op.indices[i].disp; 98 } 99 else 100 out << op.indices[i].disp; 101 if(!naked || i) 102 out << ']'; 103 } 104 if(op.comps) 105 { 106 switch(op.mode) 107 { 108 case SM4_OPERAND_MODE_MASK: 109 out << (sm4_dump_short_syntax ? '.' : '!'); 110 for(unsigned i = 0; i < op.comps; ++i) 111 { 112 if(op.mask & (1 << i)) 113 out << "xyzw"[i]; 114 } 115 break; 116 case SM4_OPERAND_MODE_SWIZZLE: 117 out << '.'; 118 for(unsigned i = 0; i < op.comps; ++i) 119 out << "xyzw"[op.swizzle[i]]; 120 break; 121 case SM4_OPERAND_MODE_SCALAR: 122 out << (sm4_dump_short_syntax ? '.' : ':'); 123 out << "xyzw"[op.swizzle[0]]; 124 break; 125 } 126 } 127 } 128 if(op.abs) 129 out << '|'; 130 return out; 131 } 132 133 std::ostream& operator <<(std::ostream& out, const sm4_dcl& dcl) 134 { 135 out << sm4_opcode_names[dcl.opcode]; 136 switch(dcl.opcode) 137 { 138 case SM4_OPCODE_DCL_GLOBAL_FLAGS: 139 if(dcl.dcl_global_flags.allow_refactoring) 140 out << " refactoringAllowed"; 141 if(dcl.dcl_global_flags.early_depth_stencil) 142 out << " forceEarlyDepthStencil"; 143 if(dcl.dcl_global_flags.fp64) 144 out << " enableDoublePrecisionFloatOps"; 145 if(dcl.dcl_global_flags.enable_raw_and_structured_in_non_cs) 146 out << " enableRawAndStructuredBuffers"; 147 break; 148 case SM4_OPCODE_DCL_INPUT_PS: 149 case SM4_OPCODE_DCL_INPUT_PS_SIV: 150 case SM4_OPCODE_DCL_INPUT_PS_SGV: 151 out << ' ' << sm4_interpolation_names[dcl.dcl_input_ps.interpolation]; 152 break; 153 case SM4_OPCODE_DCL_TEMPS: 154 out << ' ' << dcl.num; 155 break; 156 default: 157 break; 158 } 159 if(dcl.op.get()) 160 out << ' ' << *dcl.op; 161 switch(dcl.opcode) 162 { 163 case SM4_OPCODE_DCL_CONSTANT_BUFFER: 164 out << ", " << (dcl.dcl_constant_buffer.dynamic ? "dynamicIndexed" : "immediateIndexed"); 165 break; 166 case SM4_OPCODE_DCL_INPUT_SIV: 167 case SM4_OPCODE_DCL_INPUT_SGV: 168 case SM4_OPCODE_DCL_OUTPUT_SIV: 169 case SM4_OPCODE_DCL_OUTPUT_SGV: 170 case SM4_OPCODE_DCL_INPUT_PS_SIV: 171 case SM4_OPCODE_DCL_INPUT_PS_SGV: 172 out << ", " << sm4_sv_names[dcl.num]; 173 break; 174 } 175 176 return out; 177 } 178 179 std::ostream& operator <<(std::ostream& out, const sm4_insn& insn) 180 { 181 out << sm4_opcode_names[insn.opcode]; 182 if(insn.insn.sat) 183 out << "_sat"; 184 for(unsigned i = 0; i < insn.num_ops; ++i) 185 { 186 if(i) 187 out << ','; 188 out << ' ' << *insn.ops[i]; 189 } 190 return out; 191 } 192 193 std::ostream& operator <<(std::ostream& out, const sm4_program& program) 194 { 195 out << "pvghdc"[program.version.type] << "s_" << program.version.major << "_" << program.version.minor << "\n"; 196 for(unsigned i = 0; i < program.dcls.size(); ++i) 197 out << *program.dcls[i] << "\n"; 198 199 for(unsigned i = 0; i < program.insns.size(); ++i) 200 out << *program.insns[i] << "\n"; 201 return out; 202 } 203 204 void sm4_op::dump() 205 { 206 std::cout << *this; 207 } 208 209 void sm4_insn::dump() 210 { 211 std::cout << *this; 212 } 213 214 void sm4_dcl::dump() 215 { 216 std::cout << *this; 217 } 218 219 void sm4_program::dump() 220 { 221 std::cout << *this; 222 } 223