summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2014-06-13 18:35:09 -0700
committerMatt Turner <mattst88@gmail.com>2014-06-14 23:49:26 -0700
commit264ed069100111329bf06338784443791d82cfae (patch)
tree354dd3b5812004f68dab97edb2fcfc1caa2b5db8
parent4f58bbaadd88bba2f9f2e9ce47e5b2229e9ba534 (diff)
use bitfield structs to optimize masking
-rw-r--r--src/mesa/drivers/dri/i965/brw_inst.h107
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)