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