Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 1 | /* |
2 | * Copyright 2009 Nicolai Hähnle |
||
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 |
||
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 | }>>>>>>>>>>><>><>=";>";> |