diff options
| author | Matt Turner <mattst88@gmail.com> | 2014-06-13 18:35:09 -0700 |
|---|---|---|
| committer | Matt Turner <mattst88@gmail.com> | 2014-06-14 23:49:26 -0700 |
| commit | 264ed069100111329bf06338784443791d82cfae (patch) | |
| tree | 354dd3b5812004f68dab97edb2fcfc1caa2b5db8 | |
| parent | 4f58bbaadd88bba2f9f2e9ce47e5b2229e9ba534 (diff) | |
use bitfield structs to optimize masking
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_inst.h | 107 |
1 files changed, 86 insertions, 21 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_inst.h b/src/mesa/drivers/dri/i965/brw_inst.h index 5b048d30732..ad679c8ae12 100644 --- a/src/mesa/drivers/dri/i965/brw_inst.h +++ b/src/mesa/drivers/dri/i965/brw_inst.h @@ -665,30 +665,69 @@ typedef struct { * * Bits indices range from 0..63. */ -static inline unsigned -brw_compact_inst_bits(brw_compact_inst *inst, unsigned high, unsigned low) -{ - const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low); - - return (inst->data & mask) >> low; -} +#define brw_compact_inst_bits_high_edge(inst, high, low) \ + ({ \ + struct bits { \ + uint64_t val:64-low; \ + uint64_t lowpad:low; \ + } *b = (struct bits *)inst; \ + b->val; \ + }) + +#define brw_compact_inst_bits_low_edge(inst, high, low) \ + ({ \ + struct bits { \ + uint64_t highpad:63-high; \ + uint64_t val:high+1; \ + } *b = (struct bits *)inst; \ + b->val; \ + }) + +#define brw_compact_inst_bits(inst, high, low) \ + ({ \ + struct bits { \ + uint64_t highpad:63-high; \ + uint64_t val:high-low+1; \ + uint64_t lowpad:low; \ + } *b = (struct bits *)inst; \ + b->val; \ + }) /** * Set bits in the compacted instruction. * * Bits indices range from 0..63. */ -static inline void -brw_compact_inst_set_bits(brw_compact_inst *inst, unsigned high, unsigned low, - uint64_t value) -{ - const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low); - - /* Make sure the supplied value actually fits in the given bitfield. */ - assert((value & (mask >> low)) == value); - - inst->data = (inst->data & ~mask) | ((value << low) & mask); -} +#define brw_compact_inst_set_bits_high_edge(inst, high, low, v) \ + ({ \ + struct bits { \ + uint64_t val:64-low; \ + uint64_t lowpad:low; \ + } *b; \ + b = (struct bits *)inst; \ + b->val = v; \ + }) + +#define brw_compact_inst_set_bits_low_edge(inst, high, low, v) \ + ({ \ + struct bits { \ + uint64_t highpad:63-high; \ + uint64_t val:high+1; \ + } *b; \ + b = (struct bits *)inst; \ + b->val = v; \ + }) + +#define brw_compact_inst_set_bits(inst, high, low, v) \ + ({ \ + struct bits { \ + uint64_t highpad:63-high; \ + uint64_t val:high-low+1; \ + uint64_t lowpad:low; \ + } *b; \ + b = (struct bits *)inst; \ + b->val = v; \ + }) #define F(name, high, low) \ static inline void \ @@ -703,7 +742,33 @@ brw_compact_inst_##name(brw_compact_inst *inst) \ return brw_compact_inst_bits(inst, high, low); \ } -F(src1_reg_nr, 63, 56) +#define F_HIGH(name, high, low) \ +static inline void \ +brw_compact_inst_set_##name(brw_compact_inst *inst, unsigned v) \ +{ \ + brw_compact_inst_set_bits_high_edge(inst, high, low, v); \ +} \ + \ +static inline unsigned \ +brw_compact_inst_##name(brw_compact_inst *inst) \ +{ \ + return brw_compact_inst_bits_high_edge(inst, high, low); \ +} + +#define F_LOW(name, high, low) \ +static inline void \ +brw_compact_inst_set_##name(brw_compact_inst *inst, unsigned v) \ +{ \ + brw_compact_inst_set_bits_low_edge(inst, high, low, v); \ +} \ + \ +static inline unsigned \ +brw_compact_inst_##name(brw_compact_inst *inst) \ +{ \ + return brw_compact_inst_bits_low_edge(inst, high, low); \ +} + +F_HIGH(src1_reg_nr, 63, 56) F(src0_reg_nr, 55, 48) F(dst_reg_nr, 47, 40) F(src1_index, 39, 35) @@ -716,13 +781,13 @@ F(subreg_index, 22, 18) F(datatype_index, 17, 13) F(control_index, 12, 8) F(debug_control, 7, 7) -F(opcode, 6, 0) /* Same location as brw_inst */ +F_LOW(opcode, 6, 0) /* Same location as brw_inst */ /** * Three-source instructions: * @{ */ -F(3src_src2_reg_nr, 63, 57) +F_HIGH(3src_src2_reg_nr, 63, 57) F(3src_src1_reg_nr, 56, 50) F(3src_src0_reg_nr, 49, 43) F(3src_src2_subreg_nr, 42, 40) |
