101e04c3fSmrg/* -*- c++ -*- */ 201e04c3fSmrg/* 301e04c3fSmrg * Copyright © 2011-2015 Intel Corporation 401e04c3fSmrg * 501e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 601e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 701e04c3fSmrg * to deal in the Software without restriction, including without limitation 801e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 901e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1001e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1101e04c3fSmrg * 1201e04c3fSmrg * The above copyright notice and this permission notice (including the next 1301e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1401e04c3fSmrg * Software. 1501e04c3fSmrg * 1601e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1701e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1801e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1901e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2001e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2101e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2201e04c3fSmrg * IN THE SOFTWARE. 2301e04c3fSmrg */ 2401e04c3fSmrg 2501e04c3fSmrg#ifndef BRW_IR_VEC4_H 2601e04c3fSmrg#define BRW_IR_VEC4_H 2701e04c3fSmrg 2801e04c3fSmrg#include "brw_shader.h" 2901e04c3fSmrg 3001e04c3fSmrgnamespace brw { 3101e04c3fSmrg 3201e04c3fSmrgclass dst_reg; 3301e04c3fSmrg 3401e04c3fSmrgclass src_reg : public backend_reg 3501e04c3fSmrg{ 3601e04c3fSmrgpublic: 3701e04c3fSmrg DECLARE_RALLOC_CXX_OPERATORS(src_reg) 3801e04c3fSmrg 3901e04c3fSmrg void init(); 4001e04c3fSmrg 4101e04c3fSmrg src_reg(enum brw_reg_file file, int nr, const glsl_type *type); 4201e04c3fSmrg src_reg(); 4301e04c3fSmrg src_reg(struct ::brw_reg reg); 4401e04c3fSmrg 4501e04c3fSmrg bool equals(const src_reg &r) const; 4601e04c3fSmrg bool negative_equals(const src_reg &r) const; 4701e04c3fSmrg 4801e04c3fSmrg src_reg(class vec4_visitor *v, const struct glsl_type *type); 4901e04c3fSmrg src_reg(class vec4_visitor *v, const struct glsl_type *type, int size); 5001e04c3fSmrg 5101e04c3fSmrg explicit src_reg(const dst_reg ®); 5201e04c3fSmrg 5301e04c3fSmrg src_reg *reladdr; 5401e04c3fSmrg}; 5501e04c3fSmrg 5601e04c3fSmrgstatic inline src_reg 5701e04c3fSmrgretype(src_reg reg, enum brw_reg_type type) 5801e04c3fSmrg{ 5901e04c3fSmrg reg.type = type; 6001e04c3fSmrg return reg; 6101e04c3fSmrg} 6201e04c3fSmrg 6301e04c3fSmrgnamespace detail { 6401e04c3fSmrg 6501e04c3fSmrgstatic inline void 6601e04c3fSmrgadd_byte_offset(backend_reg *reg, unsigned bytes) 6701e04c3fSmrg{ 6801e04c3fSmrg switch (reg->file) { 6901e04c3fSmrg case BAD_FILE: 7001e04c3fSmrg break; 7101e04c3fSmrg case VGRF: 7201e04c3fSmrg case ATTR: 7301e04c3fSmrg case UNIFORM: 7401e04c3fSmrg reg->offset += bytes; 7501e04c3fSmrg assert(reg->offset % 16 == 0); 7601e04c3fSmrg break; 7701e04c3fSmrg case MRF: { 7801e04c3fSmrg const unsigned suboffset = reg->offset + bytes; 7901e04c3fSmrg reg->nr += suboffset / REG_SIZE; 8001e04c3fSmrg reg->offset = suboffset % REG_SIZE; 8101e04c3fSmrg assert(reg->offset % 16 == 0); 8201e04c3fSmrg break; 8301e04c3fSmrg } 8401e04c3fSmrg case ARF: 8501e04c3fSmrg case FIXED_GRF: { 8601e04c3fSmrg const unsigned suboffset = reg->subnr + bytes; 8701e04c3fSmrg reg->nr += suboffset / REG_SIZE; 8801e04c3fSmrg reg->subnr = suboffset % REG_SIZE; 8901e04c3fSmrg assert(reg->subnr % 16 == 0); 9001e04c3fSmrg break; 9101e04c3fSmrg } 9201e04c3fSmrg default: 9301e04c3fSmrg assert(bytes == 0); 9401e04c3fSmrg } 9501e04c3fSmrg} 9601e04c3fSmrg 9701e04c3fSmrg} /* namepace detail */ 9801e04c3fSmrg 9901e04c3fSmrgstatic inline src_reg 10001e04c3fSmrgbyte_offset(src_reg reg, unsigned bytes) 10101e04c3fSmrg{ 10201e04c3fSmrg detail::add_byte_offset(®, bytes); 10301e04c3fSmrg return reg; 10401e04c3fSmrg} 10501e04c3fSmrg 10601e04c3fSmrgstatic inline src_reg 10701e04c3fSmrgoffset(src_reg reg, unsigned width, unsigned delta) 10801e04c3fSmrg{ 10901e04c3fSmrg const unsigned stride = (reg.file == UNIFORM ? 0 : 4); 11001e04c3fSmrg const unsigned num_components = MAX2(width / 4 * stride, 4); 11101e04c3fSmrg return byte_offset(reg, num_components * type_sz(reg.type) * delta); 11201e04c3fSmrg} 11301e04c3fSmrg 11401e04c3fSmrgstatic inline src_reg 11501e04c3fSmrghoriz_offset(src_reg reg, unsigned delta) 11601e04c3fSmrg{ 11701e04c3fSmrg return byte_offset(reg, delta * type_sz(reg.type)); 11801e04c3fSmrg} 11901e04c3fSmrg 12001e04c3fSmrg/** 12101e04c3fSmrg * Reswizzle a given source register. 12201e04c3fSmrg * \sa brw_swizzle(). 12301e04c3fSmrg */ 12401e04c3fSmrgstatic inline src_reg 12501e04c3fSmrgswizzle(src_reg reg, unsigned swizzle) 12601e04c3fSmrg{ 12701e04c3fSmrg if (reg.file == IMM) 12801e04c3fSmrg reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swizzle); 12901e04c3fSmrg else 13001e04c3fSmrg reg.swizzle = brw_compose_swizzle(swizzle, reg.swizzle); 13101e04c3fSmrg 13201e04c3fSmrg return reg; 13301e04c3fSmrg} 13401e04c3fSmrg 13501e04c3fSmrgstatic inline src_reg 13601e04c3fSmrgnegate(src_reg reg) 13701e04c3fSmrg{ 13801e04c3fSmrg assert(reg.file != IMM); 13901e04c3fSmrg reg.negate = !reg.negate; 14001e04c3fSmrg return reg; 14101e04c3fSmrg} 14201e04c3fSmrg 14301e04c3fSmrgstatic inline bool 14401e04c3fSmrgis_uniform(const src_reg ®) 14501e04c3fSmrg{ 14601e04c3fSmrg return (reg.file == IMM || reg.file == UNIFORM || reg.is_null()) && 14701e04c3fSmrg (!reg.reladdr || is_uniform(*reg.reladdr)); 14801e04c3fSmrg} 14901e04c3fSmrg 15001e04c3fSmrgclass dst_reg : public backend_reg 15101e04c3fSmrg{ 15201e04c3fSmrgpublic: 15301e04c3fSmrg DECLARE_RALLOC_CXX_OPERATORS(dst_reg) 15401e04c3fSmrg 15501e04c3fSmrg void init(); 15601e04c3fSmrg 15701e04c3fSmrg dst_reg(); 15801e04c3fSmrg dst_reg(enum brw_reg_file file, int nr); 15901e04c3fSmrg dst_reg(enum brw_reg_file file, int nr, const glsl_type *type, 16001e04c3fSmrg unsigned writemask); 16101e04c3fSmrg dst_reg(enum brw_reg_file file, int nr, brw_reg_type type, 16201e04c3fSmrg unsigned writemask); 16301e04c3fSmrg dst_reg(struct ::brw_reg reg); 16401e04c3fSmrg dst_reg(class vec4_visitor *v, const struct glsl_type *type); 16501e04c3fSmrg 16601e04c3fSmrg explicit dst_reg(const src_reg ®); 16701e04c3fSmrg 16801e04c3fSmrg bool equals(const dst_reg &r) const; 16901e04c3fSmrg 17001e04c3fSmrg src_reg *reladdr; 17101e04c3fSmrg}; 17201e04c3fSmrg 17301e04c3fSmrgstatic inline dst_reg 17401e04c3fSmrgretype(dst_reg reg, enum brw_reg_type type) 17501e04c3fSmrg{ 17601e04c3fSmrg reg.type = type; 17701e04c3fSmrg return reg; 17801e04c3fSmrg} 17901e04c3fSmrg 18001e04c3fSmrgstatic inline dst_reg 18101e04c3fSmrgbyte_offset(dst_reg reg, unsigned bytes) 18201e04c3fSmrg{ 18301e04c3fSmrg detail::add_byte_offset(®, bytes); 18401e04c3fSmrg return reg; 18501e04c3fSmrg} 18601e04c3fSmrg 18701e04c3fSmrgstatic inline dst_reg 18801e04c3fSmrgoffset(dst_reg reg, unsigned width, unsigned delta) 18901e04c3fSmrg{ 19001e04c3fSmrg const unsigned stride = (reg.file == UNIFORM ? 0 : 4); 19101e04c3fSmrg const unsigned num_components = MAX2(width / 4 * stride, 4); 19201e04c3fSmrg return byte_offset(reg, num_components * type_sz(reg.type) * delta); 19301e04c3fSmrg} 19401e04c3fSmrg 19501e04c3fSmrgstatic inline dst_reg 19601e04c3fSmrghoriz_offset(const dst_reg ®, unsigned delta) 19701e04c3fSmrg{ 19801e04c3fSmrg if (is_uniform(src_reg(reg))) 19901e04c3fSmrg return reg; 20001e04c3fSmrg else 20101e04c3fSmrg return byte_offset(reg, delta * type_sz(reg.type)); 20201e04c3fSmrg} 20301e04c3fSmrg 20401e04c3fSmrgstatic inline dst_reg 20501e04c3fSmrgwritemask(dst_reg reg, unsigned mask) 20601e04c3fSmrg{ 20701e04c3fSmrg assert(reg.file != IMM); 20801e04c3fSmrg assert((reg.writemask & mask) != 0); 20901e04c3fSmrg reg.writemask &= mask; 21001e04c3fSmrg return reg; 21101e04c3fSmrg} 21201e04c3fSmrg 21301e04c3fSmrg/** 21401e04c3fSmrg * Return an integer identifying the discrete address space a register is 21501e04c3fSmrg * contained in. A register is by definition fully contained in the single 21601e04c3fSmrg * reg_space it belongs to, so two registers with different reg_space ids are 21701e04c3fSmrg * guaranteed not to overlap. Most register files are a single reg_space of 21801e04c3fSmrg * its own, only the VGRF file is composed of multiple discrete address 21901e04c3fSmrg * spaces, one for each VGRF allocation. 22001e04c3fSmrg */ 22101e04c3fSmrgstatic inline uint32_t 22201e04c3fSmrgreg_space(const backend_reg &r) 22301e04c3fSmrg{ 22401e04c3fSmrg return r.file << 16 | (r.file == VGRF ? r.nr : 0); 22501e04c3fSmrg} 22601e04c3fSmrg 22701e04c3fSmrg/** 22801e04c3fSmrg * Return the base offset in bytes of a register relative to the start of its 22901e04c3fSmrg * reg_space(). 23001e04c3fSmrg */ 23101e04c3fSmrgstatic inline unsigned 23201e04c3fSmrgreg_offset(const backend_reg &r) 23301e04c3fSmrg{ 23401e04c3fSmrg return (r.file == VGRF || r.file == IMM ? 0 : r.nr) * 23501e04c3fSmrg (r.file == UNIFORM ? 16 : REG_SIZE) + r.offset + 23601e04c3fSmrg (r.file == ARF || r.file == FIXED_GRF ? r.subnr : 0); 23701e04c3fSmrg} 23801e04c3fSmrg 23901e04c3fSmrg/** 24001e04c3fSmrg * Return whether the register region starting at \p r and spanning \p dr 24101e04c3fSmrg * bytes could potentially overlap the register region starting at \p s and 24201e04c3fSmrg * spanning \p ds bytes. 24301e04c3fSmrg */ 24401e04c3fSmrgstatic inline bool 24501e04c3fSmrgregions_overlap(const backend_reg &r, unsigned dr, 24601e04c3fSmrg const backend_reg &s, unsigned ds) 24701e04c3fSmrg{ 24801e04c3fSmrg if (r.file == MRF && (r.nr & BRW_MRF_COMPR4)) { 24901e04c3fSmrg /* COMPR4 regions are translated by the hardware during decompression 25001e04c3fSmrg * into two separate half-regions 4 MRFs apart from each other. 25101e04c3fSmrg */ 25201e04c3fSmrg backend_reg t0 = r; 25301e04c3fSmrg t0.nr &= ~BRW_MRF_COMPR4; 25401e04c3fSmrg backend_reg t1 = t0; 25501e04c3fSmrg t1.offset += 4 * REG_SIZE; 25601e04c3fSmrg return regions_overlap(t0, dr / 2, s, ds) || 25701e04c3fSmrg regions_overlap(t1, dr / 2, s, ds); 25801e04c3fSmrg 25901e04c3fSmrg } else if (s.file == MRF && (s.nr & BRW_MRF_COMPR4)) { 26001e04c3fSmrg return regions_overlap(s, ds, r, dr); 26101e04c3fSmrg 26201e04c3fSmrg } else { 26301e04c3fSmrg return reg_space(r) == reg_space(s) && 26401e04c3fSmrg !(reg_offset(r) + dr <= reg_offset(s) || 26501e04c3fSmrg reg_offset(s) + ds <= reg_offset(r)); 26601e04c3fSmrg } 26701e04c3fSmrg} 26801e04c3fSmrg 26901e04c3fSmrgclass vec4_instruction : public backend_instruction { 27001e04c3fSmrgpublic: 27101e04c3fSmrg DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction) 27201e04c3fSmrg 27301e04c3fSmrg vec4_instruction(enum opcode opcode, 27401e04c3fSmrg const dst_reg &dst = dst_reg(), 27501e04c3fSmrg const src_reg &src0 = src_reg(), 27601e04c3fSmrg const src_reg &src1 = src_reg(), 27701e04c3fSmrg const src_reg &src2 = src_reg()); 27801e04c3fSmrg 27901e04c3fSmrg dst_reg dst; 28001e04c3fSmrg src_reg src[3]; 28101e04c3fSmrg 28201e04c3fSmrg enum brw_urb_write_flags urb_write_flags; 28301e04c3fSmrg 2847ec681f3Smrg unsigned sol_binding; /**< gfx6: SOL binding table index */ 2857ec681f3Smrg bool sol_final_write; /**< gfx6: send commit message */ 2867ec681f3Smrg unsigned sol_vertex; /**< gfx6: used for setting dst index in SVB header */ 28701e04c3fSmrg 2887ec681f3Smrg bool is_send_from_grf() const; 28901e04c3fSmrg unsigned size_read(unsigned arg) const; 2907ec681f3Smrg bool can_reswizzle(const struct intel_device_info *devinfo, 2917ec681f3Smrg int dst_writemask, 29201e04c3fSmrg int swizzle, int swizzle_mask); 29301e04c3fSmrg void reswizzle(int dst_writemask, int swizzle); 2947ec681f3Smrg bool can_do_source_mods(const struct intel_device_info *devinfo); 29501e04c3fSmrg bool can_do_cmod(); 2967ec681f3Smrg bool can_do_writemask(const struct intel_device_info *devinfo); 29701e04c3fSmrg bool can_change_types() const; 29801e04c3fSmrg bool has_source_and_destination_hazard() const; 2997ec681f3Smrg unsigned implied_mrf_writes() const; 30001e04c3fSmrg 30101e04c3fSmrg bool is_align1_partial_write() 30201e04c3fSmrg { 30301e04c3fSmrg return opcode == VEC4_OPCODE_SET_LOW_32BIT || 30401e04c3fSmrg opcode == VEC4_OPCODE_SET_HIGH_32BIT; 30501e04c3fSmrg } 30601e04c3fSmrg 3077ec681f3Smrg bool reads_flag() const 30801e04c3fSmrg { 30901e04c3fSmrg return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2; 31001e04c3fSmrg } 31101e04c3fSmrg 31201e04c3fSmrg bool reads_flag(unsigned c) 31301e04c3fSmrg { 31401e04c3fSmrg if (opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2) 31501e04c3fSmrg return true; 31601e04c3fSmrg 31701e04c3fSmrg switch (predicate) { 31801e04c3fSmrg case BRW_PREDICATE_NONE: 31901e04c3fSmrg return false; 32001e04c3fSmrg case BRW_PREDICATE_ALIGN16_REPLICATE_X: 32101e04c3fSmrg return c == 0; 32201e04c3fSmrg case BRW_PREDICATE_ALIGN16_REPLICATE_Y: 32301e04c3fSmrg return c == 1; 32401e04c3fSmrg case BRW_PREDICATE_ALIGN16_REPLICATE_Z: 32501e04c3fSmrg return c == 2; 32601e04c3fSmrg case BRW_PREDICATE_ALIGN16_REPLICATE_W: 32701e04c3fSmrg return c == 3; 32801e04c3fSmrg default: 32901e04c3fSmrg return true; 33001e04c3fSmrg } 33101e04c3fSmrg } 33201e04c3fSmrg 3337ec681f3Smrg bool writes_flag(const intel_device_info *devinfo) const 33401e04c3fSmrg { 3357ec681f3Smrg return (conditional_mod && ((opcode != BRW_OPCODE_SEL || devinfo->ver <= 5) && 33601e04c3fSmrg opcode != BRW_OPCODE_CSEL && 33701e04c3fSmrg opcode != BRW_OPCODE_IF && 33801e04c3fSmrg opcode != BRW_OPCODE_WHILE)); 33901e04c3fSmrg } 34001e04c3fSmrg 34101e04c3fSmrg bool reads_g0_implicitly() const 34201e04c3fSmrg { 34301e04c3fSmrg switch (opcode) { 34401e04c3fSmrg case SHADER_OPCODE_TEX: 34501e04c3fSmrg case SHADER_OPCODE_TXL: 34601e04c3fSmrg case SHADER_OPCODE_TXD: 34701e04c3fSmrg case SHADER_OPCODE_TXF: 34801e04c3fSmrg case SHADER_OPCODE_TXF_CMS_W: 34901e04c3fSmrg case SHADER_OPCODE_TXF_CMS: 35001e04c3fSmrg case SHADER_OPCODE_TXF_MCS: 35101e04c3fSmrg case SHADER_OPCODE_TXS: 35201e04c3fSmrg case SHADER_OPCODE_TG4: 35301e04c3fSmrg case SHADER_OPCODE_TG4_OFFSET: 35401e04c3fSmrg case SHADER_OPCODE_SAMPLEINFO: 35501e04c3fSmrg case VS_OPCODE_PULL_CONSTANT_LOAD: 35601e04c3fSmrg case GS_OPCODE_SET_PRIMITIVE_ID: 35701e04c3fSmrg case GS_OPCODE_GET_INSTANCE_ID: 3587ec681f3Smrg case SHADER_OPCODE_GFX4_SCRATCH_READ: 3597ec681f3Smrg case SHADER_OPCODE_GFX4_SCRATCH_WRITE: 36001e04c3fSmrg return true; 36101e04c3fSmrg default: 36201e04c3fSmrg return false; 36301e04c3fSmrg } 36401e04c3fSmrg } 36501e04c3fSmrg}; 36601e04c3fSmrg 36701e04c3fSmrg/** 36801e04c3fSmrg * Make the execution of \p inst dependent on the evaluation of a possibly 36901e04c3fSmrg * inverted predicate. 37001e04c3fSmrg */ 37101e04c3fSmrginline vec4_instruction * 37201e04c3fSmrgset_predicate_inv(enum brw_predicate pred, bool inverse, 37301e04c3fSmrg vec4_instruction *inst) 37401e04c3fSmrg{ 37501e04c3fSmrg inst->predicate = pred; 37601e04c3fSmrg inst->predicate_inverse = inverse; 37701e04c3fSmrg return inst; 37801e04c3fSmrg} 37901e04c3fSmrg 38001e04c3fSmrg/** 38101e04c3fSmrg * Make the execution of \p inst dependent on the evaluation of a predicate. 38201e04c3fSmrg */ 38301e04c3fSmrginline vec4_instruction * 38401e04c3fSmrgset_predicate(enum brw_predicate pred, vec4_instruction *inst) 38501e04c3fSmrg{ 38601e04c3fSmrg return set_predicate_inv(pred, false, inst); 38701e04c3fSmrg} 38801e04c3fSmrg 38901e04c3fSmrg/** 39001e04c3fSmrg * Write the result of evaluating the condition given by \p mod to a flag 39101e04c3fSmrg * register. 39201e04c3fSmrg */ 39301e04c3fSmrginline vec4_instruction * 39401e04c3fSmrgset_condmod(enum brw_conditional_mod mod, vec4_instruction *inst) 39501e04c3fSmrg{ 39601e04c3fSmrg inst->conditional_mod = mod; 39701e04c3fSmrg return inst; 39801e04c3fSmrg} 39901e04c3fSmrg 40001e04c3fSmrg/** 40101e04c3fSmrg * Clamp the result of \p inst to the saturation range of its destination 40201e04c3fSmrg * datatype. 40301e04c3fSmrg */ 40401e04c3fSmrginline vec4_instruction * 40501e04c3fSmrgset_saturate(bool saturate, vec4_instruction *inst) 40601e04c3fSmrg{ 40701e04c3fSmrg inst->saturate = saturate; 40801e04c3fSmrg return inst; 40901e04c3fSmrg} 41001e04c3fSmrg 41101e04c3fSmrg/** 41201e04c3fSmrg * Return the number of dataflow registers written by the instruction (either 41301e04c3fSmrg * fully or partially) counted from 'floor(reg_offset(inst->dst) / 41401e04c3fSmrg * register_size)'. The somewhat arbitrary register size unit is 16B for the 41501e04c3fSmrg * UNIFORM and IMM files and 32B for all other files. 41601e04c3fSmrg */ 41701e04c3fSmrginline unsigned 41801e04c3fSmrgregs_written(const vec4_instruction *inst) 41901e04c3fSmrg{ 42001e04c3fSmrg assert(inst->dst.file != UNIFORM && inst->dst.file != IMM); 42101e04c3fSmrg return DIV_ROUND_UP(reg_offset(inst->dst) % REG_SIZE + inst->size_written, 42201e04c3fSmrg REG_SIZE); 42301e04c3fSmrg} 42401e04c3fSmrg 42501e04c3fSmrg/** 42601e04c3fSmrg * Return the number of dataflow registers read by the instruction (either 42701e04c3fSmrg * fully or partially) counted from 'floor(reg_offset(inst->src[i]) / 42801e04c3fSmrg * register_size)'. The somewhat arbitrary register size unit is 16B for the 42901e04c3fSmrg * UNIFORM and IMM files and 32B for all other files. 43001e04c3fSmrg */ 43101e04c3fSmrginline unsigned 43201e04c3fSmrgregs_read(const vec4_instruction *inst, unsigned i) 43301e04c3fSmrg{ 43401e04c3fSmrg const unsigned reg_size = 43501e04c3fSmrg inst->src[i].file == UNIFORM || inst->src[i].file == IMM ? 16 : REG_SIZE; 43601e04c3fSmrg return DIV_ROUND_UP(reg_offset(inst->src[i]) % reg_size + inst->size_read(i), 43701e04c3fSmrg reg_size); 43801e04c3fSmrg} 43901e04c3fSmrg 44001e04c3fSmrgstatic inline enum brw_reg_type 44101e04c3fSmrgget_exec_type(const vec4_instruction *inst) 44201e04c3fSmrg{ 44301e04c3fSmrg enum brw_reg_type exec_type = BRW_REGISTER_TYPE_B; 44401e04c3fSmrg 44501e04c3fSmrg for (int i = 0; i < 3; i++) { 44601e04c3fSmrg if (inst->src[i].file != BAD_FILE) { 44701e04c3fSmrg const brw_reg_type t = get_exec_type(brw_reg_type(inst->src[i].type)); 44801e04c3fSmrg if (type_sz(t) > type_sz(exec_type)) 44901e04c3fSmrg exec_type = t; 45001e04c3fSmrg else if (type_sz(t) == type_sz(exec_type) && 45101e04c3fSmrg brw_reg_type_is_floating_point(t)) 45201e04c3fSmrg exec_type = t; 45301e04c3fSmrg } 45401e04c3fSmrg } 45501e04c3fSmrg 45601e04c3fSmrg if (exec_type == BRW_REGISTER_TYPE_B) 45701e04c3fSmrg exec_type = inst->dst.type; 45801e04c3fSmrg 45901e04c3fSmrg /* TODO: We need to handle half-float conversions. */ 46001e04c3fSmrg assert(exec_type != BRW_REGISTER_TYPE_HF || 46101e04c3fSmrg inst->dst.type == BRW_REGISTER_TYPE_HF); 46201e04c3fSmrg assert(exec_type != BRW_REGISTER_TYPE_B); 46301e04c3fSmrg 46401e04c3fSmrg return exec_type; 46501e04c3fSmrg} 46601e04c3fSmrg 46701e04c3fSmrgstatic inline unsigned 46801e04c3fSmrgget_exec_type_size(const vec4_instruction *inst) 46901e04c3fSmrg{ 47001e04c3fSmrg return type_sz(get_exec_type(inst)); 47101e04c3fSmrg} 47201e04c3fSmrg 47301e04c3fSmrg} /* namespace brw */ 47401e04c3fSmrg 47501e04c3fSmrg#endif 476