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