• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include "radeon_compiler.h"
3 #include "radeon_compiler_util.h"
4 #include "radeon_dataflow.h"
5 #include "radeon_program.h"
6 #include "radeon_program_constants.h"
7 #include <stdio.h>
8 
9 #define VERBOSE 0
10 
11 #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
12 
13 /* IEEE-754:
14  * 22:0 mantissa
15  * 30:23 exponent
16  * 31 sign
17  *
18  * R300:
19  * 0:2 mantissa
20  * 3:6 exponent (bias 7)
21  */
ieee_754_to_r300_float(float f,unsigned char * r300_float_out)22 static int ieee_754_to_r300_float(float f, unsigned char *r300_float_out)
23 {
24 	unsigned float_bits = *((unsigned *)&f);
25 	/* XXX: Handle big-endian */
26 	unsigned mantissa = float_bits &         0x007fffff;
27 	unsigned biased_exponent = (float_bits & 0x7f800000) >> 23;
28 	unsigned negate = !!(float_bits &         0x80000000);
29 	int exponent = biased_exponent - 127;
30 	unsigned mantissa_mask = 0xff8fffff;
31 	unsigned r300_exponent, r300_mantissa;
32 
33 	DBG("Converting %f (0x%x) to 7-bit:\n", f, float_bits);
34 	DBG("Raw exponent = %d\n", exponent);
35 
36 	if (exponent < -7 || exponent > 8) {
37 		DBG("Failed exponent out of range\n\n");
38 		return 0;
39 	}
40 
41 	if (mantissa & mantissa_mask) {
42 		DBG("Failed mantisa has too many bits:\n"
43 			"manitssa=0x%x mantissa_mask=0x%x, and=0x%x\n\n",
44 			mantissa, mantissa_mask,
45 			mantissa & mantissa_mask);
46 		return 0;
47 	}
48 
49 	r300_exponent = exponent + 7;
50 	r300_mantissa = (mantissa & ~mantissa_mask) >> 20;
51 	*r300_float_out = r300_mantissa | (r300_exponent << 3);
52 
53 	DBG("Success! r300_float = 0x%x\n\n", *r300_float_out);
54 
55 	if (negate)
56 		return -1;
57 	else
58 		return 1;
59 }
60 
rc_inline_literals(struct radeon_compiler * c,void * user)61 void rc_inline_literals(struct radeon_compiler *c, void *user)
62 {
63 	struct rc_instruction * inst;
64 
65 	for(inst = c->Program.Instructions.Next;
66 					inst != &c->Program.Instructions;
67 					inst = inst->Next) {
68 		const struct rc_opcode_info * info =
69 					rc_get_opcode_info(inst->U.I.Opcode);
70 
71 		unsigned src_idx;
72 		struct rc_constant * constant;
73 		float float_value;
74 		unsigned char r300_float = 0;
75 		int ret;
76 
77 		/* XXX: Handle presub */
78 
79 		/* We aren't using rc_for_all_reads_src here, because presub
80 		 * sources need to be handled differently. */
81 		for (src_idx = 0; src_idx < info->NumSrcRegs; src_idx++) {
82 			unsigned new_swizzle;
83 			unsigned use_literal = 0;
84 			unsigned negate_mask = 0;
85 			unsigned swz, chan;
86 			struct rc_src_register * src_reg =
87 						&inst->U.I.SrcReg[src_idx];
88 			swz = RC_SWIZZLE_UNUSED;
89 			if (src_reg->File != RC_FILE_CONSTANT) {
90 				continue;
91 			}
92 			constant =
93 				&c->Program.Constants.Constants[src_reg->Index];
94 			if (constant->Type != RC_CONSTANT_IMMEDIATE) {
95 				continue;
96 			}
97 			new_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0);
98 			for (chan = 0; chan < 4; chan++) {
99 				unsigned char r300_float_tmp;
100 				swz = GET_SWZ(src_reg->Swizzle, chan);
101 				if (swz == RC_SWIZZLE_UNUSED) {
102 					continue;
103 				}
104 				float_value = constant->u.Immediate[swz];
105 				ret = ieee_754_to_r300_float(float_value,
106 								&r300_float_tmp);
107 				if (!ret || (use_literal &&
108 						r300_float != r300_float_tmp)) {
109 					use_literal = 0;
110 					break;
111 				}
112 
113 				if (ret == -1 && src_reg->Abs) {
114 					use_literal = 0;
115 					break;
116 				}
117 
118 				if (!use_literal) {
119 					r300_float = r300_float_tmp;
120 					use_literal = 1;
121 				}
122 
123 				/* Use RC_SWIZZLE_W for the inline constant, so
124 				 * it will become one of the alpha sources. */
125 				SET_SWZ(new_swizzle, chan, RC_SWIZZLE_W);
126 				if (ret == -1) {
127 					negate_mask |= (1 << chan);
128 				}
129 			}
130 
131 			if (!use_literal) {
132 				continue;
133 			}
134 			src_reg->File = RC_FILE_INLINE;
135 			src_reg->Index = r300_float;
136 			src_reg->Swizzle = new_swizzle;
137 			src_reg->Negate = src_reg->Negate ^ negate_mask;
138 		}
139 	}
140 }
141