i965: Add negative_equals methods
This method is similar to the existing ::equals methods. Instead of testing that two src_regs are equal to each other, it tests that one is the negation of the other. v2: Simplify various checks based on suggestions from Matt. Use src_reg::type instead of fixed_hw_reg.type in a check. Also suggested by Matt. v3: Rebase on 3 years. Fix some problems with negative_equals with VF constants. Add fs_reg::negative_equals. v4: Replace the existing default case with BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B, and BRW_REGISTER_TYPE_NF. Suggested by Matt. Expand the FINISHME comment to better explain why it isn't already finished. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> [v3] Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -453,6 +453,13 @@ fs_reg::equals(const fs_reg &r) const
|
|||||||
stride == r.stride);
|
stride == r.stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fs_reg::negative_equals(const fs_reg &r) const
|
||||||
|
{
|
||||||
|
return (this->backend_reg::negative_equals(r) &&
|
||||||
|
stride == r.stride);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fs_reg::is_contiguous() const
|
fs_reg::is_contiguous() const
|
||||||
{
|
{
|
||||||
|
@@ -41,6 +41,7 @@ public:
|
|||||||
fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
|
fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
|
||||||
|
|
||||||
bool equals(const fs_reg &r) const;
|
bool equals(const fs_reg &r) const;
|
||||||
|
bool negative_equals(const fs_reg &r) const;
|
||||||
bool is_contiguous() const;
|
bool is_contiguous() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -43,6 +43,7 @@ public:
|
|||||||
src_reg(struct ::brw_reg reg);
|
src_reg(struct ::brw_reg reg);
|
||||||
|
|
||||||
bool equals(const src_reg &r) const;
|
bool equals(const src_reg &r) const;
|
||||||
|
bool negative_equals(const src_reg &r) const;
|
||||||
|
|
||||||
src_reg(class vec4_visitor *v, const struct glsl_type *type);
|
src_reg(class vec4_visitor *v, const struct glsl_type *type);
|
||||||
src_reg(class vec4_visitor *v, const struct glsl_type *type, int size);
|
src_reg(class vec4_visitor *v, const struct glsl_type *type, int size);
|
||||||
|
@@ -255,6 +255,55 @@ brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
|
|||||||
return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
|
return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
brw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
|
||||||
|
{
|
||||||
|
if (a->file == IMM) {
|
||||||
|
if (a->bits != b->bits)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (a->type) {
|
||||||
|
case BRW_REGISTER_TYPE_UQ:
|
||||||
|
case BRW_REGISTER_TYPE_Q:
|
||||||
|
return a->d64 == -b->d64;
|
||||||
|
case BRW_REGISTER_TYPE_DF:
|
||||||
|
return a->df == -b->df;
|
||||||
|
case BRW_REGISTER_TYPE_UD:
|
||||||
|
case BRW_REGISTER_TYPE_D:
|
||||||
|
return a->d == -b->d;
|
||||||
|
case BRW_REGISTER_TYPE_F:
|
||||||
|
return a->f == -b->f;
|
||||||
|
case BRW_REGISTER_TYPE_VF:
|
||||||
|
/* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
|
||||||
|
* of -0). There are occasions where 0 or -0 is used and the exact
|
||||||
|
* bit pattern is desired. At the very least, changing this to allow
|
||||||
|
* 0 as a negation of 0 causes some fp64 tests to fail on IVB.
|
||||||
|
*/
|
||||||
|
return a->ud == (b->ud ^ 0x80808080);
|
||||||
|
case BRW_REGISTER_TYPE_UW:
|
||||||
|
case BRW_REGISTER_TYPE_W:
|
||||||
|
case BRW_REGISTER_TYPE_UV:
|
||||||
|
case BRW_REGISTER_TYPE_V:
|
||||||
|
case BRW_REGISTER_TYPE_HF:
|
||||||
|
/* FINISHME: Implement support for these types once there is
|
||||||
|
* something in the compiler that can generate them. Until then,
|
||||||
|
* they cannot be tested.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
case BRW_REGISTER_TYPE_UB:
|
||||||
|
case BRW_REGISTER_TYPE_B:
|
||||||
|
case BRW_REGISTER_TYPE_NF:
|
||||||
|
unreachable("not reached");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct brw_reg tmp = *a;
|
||||||
|
|
||||||
|
tmp.negate = !tmp.negate;
|
||||||
|
|
||||||
|
return brw_regs_equal(&tmp, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct brw_indirect {
|
struct brw_indirect {
|
||||||
unsigned addr_subnr:4;
|
unsigned addr_subnr:4;
|
||||||
int addr_offset:10;
|
int addr_offset:10;
|
||||||
|
@@ -684,6 +684,12 @@ backend_reg::equals(const backend_reg &r) const
|
|||||||
return brw_regs_equal(this, &r) && offset == r.offset;
|
return brw_regs_equal(this, &r) && offset == r.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
backend_reg::negative_equals(const backend_reg &r) const
|
||||||
|
{
|
||||||
|
return brw_regs_negative_equal(this, &r) && offset == r.offset;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
backend_reg::is_zero() const
|
backend_reg::is_zero() const
|
||||||
{
|
{
|
||||||
|
@@ -59,6 +59,7 @@ struct backend_reg : private brw_reg
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const backend_reg &r) const;
|
bool equals(const backend_reg &r) const;
|
||||||
|
bool negative_equals(const backend_reg &r) const;
|
||||||
|
|
||||||
bool is_zero() const;
|
bool is_zero() const;
|
||||||
bool is_one() const;
|
bool is_one() const;
|
||||||
|
@@ -375,6 +375,13 @@ src_reg::equals(const src_reg &r) const
|
|||||||
!reladdr && !r.reladdr);
|
!reladdr && !r.reladdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
src_reg::negative_equals(const src_reg &r) const
|
||||||
|
{
|
||||||
|
return this->backend_reg::negative_equals(r) &&
|
||||||
|
!reladdr && !r.reladdr;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
vec4_visitor::opt_vector_float()
|
vec4_visitor::opt_vector_float()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user