intel/fs: Remove unused emission of load_simd_with_intel
[mesa.git] / src / intel / compiler / brw_reg.h
index 17a51fbd6556bb4bde17bc0fdb1c1962a9e09a5d..865cd9e0f362251a9bc2e8af6f45c22dd703a0da 100644 (file)
 #define BRW_REG_H
 
 #include <stdbool.h>
-#include "main/compiler.h"
+#include "util/compiler.h"
 #include "main/macros.h"
 #include "program/prog_instruction.h"
 #include "brw_eu_defines.h"
+#include "brw_reg_type.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -202,43 +203,6 @@ brw_mask_for_swizzle(unsigned swz)
    return brw_apply_inv_swizzle_to_mask(swz, ~0);
 }
 
-enum PACKED brw_reg_type {
-   BRW_REGISTER_TYPE_UD = 0,
-   BRW_REGISTER_TYPE_D,
-   BRW_REGISTER_TYPE_UW,
-   BRW_REGISTER_TYPE_W,
-   BRW_REGISTER_TYPE_F,
-
-   /** Non-immediates only: @{ */
-   BRW_REGISTER_TYPE_UB,
-   BRW_REGISTER_TYPE_B,
-   /** @} */
-
-   /** Immediates only: @{ */
-   BRW_REGISTER_TYPE_UV, /* Gen6+ */
-   BRW_REGISTER_TYPE_V,
-   BRW_REGISTER_TYPE_VF,
-   /** @} */
-
-   BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
-
-   /* Gen8+ */
-   BRW_REGISTER_TYPE_HF,
-   BRW_REGISTER_TYPE_UQ,
-   BRW_REGISTER_TYPE_Q,
-};
-
-unsigned brw_reg_type_to_hw_type(const struct gen_device_info *devinfo,
-                                 enum brw_reg_type type, enum brw_reg_file file);
-
-#define brw_element_size(devinfo, inst, operand)                             \
-   brw_hw_reg_type_to_size(devinfo,                                          \
-                           brw_inst_ ## operand ## _reg_type(devinfo, inst), \
-                           brw_inst_ ## operand ## _reg_file(devinfo, inst))
-unsigned brw_hw_reg_type_to_size(const struct gen_device_info *devinfo,
-                                 unsigned type, enum brw_reg_file file);
-
-const char *brw_reg_type_letters(unsigned brw_reg_type);
 uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
 
 #define REG_SIZE (8*4)
@@ -257,15 +221,15 @@ struct brw_reg {
          unsigned negate:1;             /* source only */
          unsigned abs:1;                /* source only */
          unsigned address_mode:1;       /* relative addressing, hopefully! */
-         unsigned pad0:1;
+         unsigned pad0:17;
          unsigned subnr:5;              /* :1 in align16 */
-         unsigned nr:16;
       };
       uint32_t bits;
    };
 
    union {
       struct {
+         unsigned nr;
          unsigned swizzle:8;      /* src only, align16 only */
          unsigned writemask:4;    /* dest only, align16 only */
          int  indirect_offset:10; /* relative addressing offset */
@@ -287,8 +251,57 @@ struct brw_reg {
 static inline bool
 brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
 {
-   const bool df = a->type == BRW_REGISTER_TYPE_DF && a->file == IMM;
-   return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
+   return a->bits == b->bits && a->u64 == b->u64;
+}
+
+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 ((enum brw_reg_type) 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:
+      default:
+         unreachable("not reached");
+      }
+   } else {
+      struct brw_reg tmp = *a;
+
+      tmp.negate = !tmp.negate;
+
+      return brw_regs_equal(&tmp, b);
+   }
 }
 
 struct brw_indirect {
@@ -305,6 +318,7 @@ type_sz(unsigned type)
    case BRW_REGISTER_TYPE_UQ:
    case BRW_REGISTER_TYPE_Q:
    case BRW_REGISTER_TYPE_DF:
+   case BRW_REGISTER_TYPE_NF:
       return 8;
    case BRW_REGISTER_TYPE_UD:
    case BRW_REGISTER_TYPE_D:
@@ -325,19 +339,6 @@ type_sz(unsigned type)
    }
 }
 
-static inline bool
-brw_reg_type_is_floating_point(enum brw_reg_type type)
-{
-   switch (type) {
-   case BRW_REGISTER_TYPE_F:
-   case BRW_REGISTER_TYPE_HF:
-   case BRW_REGISTER_TYPE_DF:
-      return true;
-   default:
-      return false;
-   }
-}
-
 static inline enum brw_reg_type
 get_exec_type(const enum brw_reg_type type)
 {
@@ -375,6 +376,15 @@ brw_int_type(unsigned sz, bool is_signed)
    }
 }
 
+static inline bool
+type_is_unsigned_int(enum brw_reg_type tp)
+{
+   return tp == BRW_REGISTER_TYPE_UB ||
+          tp == BRW_REGISTER_TYPE_UW ||
+          tp == BRW_REGISTER_TYPE_UD ||
+          tp == BRW_REGISTER_TYPE_UQ;
+}
+
 /**
  * Construct a brw_reg.
  * \param file      one of the BRW_x_REGISTER_FILE values
@@ -638,6 +648,14 @@ brw_imm_df(double df)
    return imm;
 }
 
+static inline struct brw_reg
+brw_imm_u64(uint64_t u64)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
+   imm.u64 = u64;
+   return imm;
+}
+
 static inline struct brw_reg
 brw_imm_f(float f)
 {
@@ -646,6 +664,24 @@ brw_imm_f(float f)
    return imm;
 }
 
+/** Construct int64_t immediate register */
+static inline struct brw_reg
+brw_imm_q(int64_t q)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
+   imm.d64 = q;
+   return imm;
+}
+
+/** Construct int64_t immediate register */
+static inline struct brw_reg
+brw_imm_uq(uint64_t uq)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
+   imm.u64 = uq;
+   return imm;
+}
+
 /** Construct integer immediate register */
 static inline struct brw_reg
 brw_imm_d(int d)
@@ -678,7 +714,7 @@ static inline struct brw_reg
 brw_imm_w(int16_t w)
 {
    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
-   imm.d = w | (w << 16);
+   imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
    return imm;
 }
 
@@ -805,6 +841,12 @@ brw_address_reg(unsigned subnr)
    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
 }
 
+static inline struct brw_reg
+brw_tdr_reg(void)
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
+}
+
 /* If/else instructions break in align16 mode if writemask & swizzle
  * aren't xyzw.  This goes against the convention for other scalar
  * regs:
@@ -841,6 +883,12 @@ brw_notification_reg(void)
                   WRITEMASK_X);
 }
 
+static inline struct brw_reg
+brw_cr0_reg(unsigned subnr)
+{
+   return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
+}
+
 static inline struct brw_reg
 brw_sr0_reg(unsigned subnr)
 {
@@ -861,6 +909,13 @@ brw_flag_reg(int reg, int subreg)
                       BRW_ARF_FLAG + reg, subreg);
 }
 
+static inline struct brw_reg
+brw_flag_subreg(unsigned subreg)
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                      BRW_ARF_FLAG + subreg / 2, subreg % 2);
+}
+
 /**
  * Return the mask register present in Gen4-5, or the related register present
  * in Gen7.5 and later hardware referred to as "channel enable" register in
@@ -931,7 +986,7 @@ static inline struct brw_reg
 spread(struct brw_reg reg, unsigned s)
 {
    if (s) {
-      assert(_mesa_is_pow_two(s));
+      assert(util_is_power_of_two_nonzero(s));
 
       if (reg.hstride)
          reg.hstride += cvt(s) - 1;
@@ -945,6 +1000,22 @@ spread(struct brw_reg reg, unsigned s)
    }
 }
 
+/**
+ * Reinterpret each channel of register \p reg as a vector of values of the
+ * given smaller type and take the i-th subcomponent from each.
+ */
+static inline struct brw_reg
+subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
+{
+   if (reg.file == IMM)
+      return reg;
+
+   unsigned scale = type_sz(reg.type) / type_sz(type);
+   assert(scale >= 1 && i < scale);
+
+   return suboffset(retype(spread(reg, scale), type), i);
+}
+
 static inline struct brw_reg
 vec16(struct brw_reg reg)
 {