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"
11 #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
20 * 3:6 exponent (bias 7)
22 static int ieee_754_to_r300_float(float f
, unsigned char *r300_float_out
)
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
;
33 DBG("Converting %f (0x%x) to 7-bit:\n", f
, float_bits
);
34 DBG("Raw exponent = %d\n", exponent
);
36 if (exponent
< -7 || exponent
> 8) {
37 DBG("Failed exponent out of range\n\n");
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
);
49 r300_exponent
= exponent
+ 7;
50 r300_mantissa
= (mantissa
& ~mantissa_mask
) >> 20;
51 *r300_float_out
= r300_mantissa
| (r300_exponent
<< 3);
53 DBG("Success! r300_float = 0x%x\n\n", *r300_float_out
);
61 void rc_inline_literals(struct radeon_compiler
*c
, void *user
)
63 struct rc_instruction
* inst
;
65 for(inst
= c
->Program
.Instructions
.Next
;
66 inst
!= &c
->Program
.Instructions
;
68 const struct rc_opcode_info
* info
=
69 rc_get_opcode_info(inst
->U
.I
.Opcode
);
72 struct rc_constant
* constant
;
74 unsigned char r300_float
;
77 /* XXX: Handle presub */
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
++) {
83 unsigned use_literal
= 0;
84 unsigned negate_mask
= 0;
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
) {
93 &c
->Program
.Constants
.Constants
[src_reg
->Index
];
94 if (constant
->Type
!= RC_CONSTANT_IMMEDIATE
) {
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
) {
104 float_value
= constant
->u
.Immediate
[swz
];
105 ret
= ieee_754_to_r300_float(float_value
,
107 if (!ret
|| (use_literal
&&
108 r300_float
!= r300_float_tmp
)) {
113 if (ret
== -1 && src_reg
->Abs
) {
119 r300_float
= r300_float_tmp
;
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
);
127 negate_mask
|= (1 << chan
);
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
;