Merge remote branch 'origin/master' into lp-setup-llvm
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu_emit.c
index 419b40ba84b7c01765da7b5659405dbf9a3e428d..a1fead0a4fac06431fcb40dff7a4f7e70299a8b8 100644 (file)
@@ -654,6 +654,26 @@ struct brw_instruction *brw_##OP(struct brw_compile *p,    \
    return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1);      \
 }
 
+/* Rounding operations (other than RNDD) require two instructions - the first
+ * stores a rounded value (possibly the wrong way) in the dest register, but
+ * also sets a per-channel "increment bit" in the flag register.  A predicated
+ * add of 1.0 fixes dest to contain the desired result.
+ */
+#define ROUND(OP)                                                            \
+void brw_##OP(struct brw_compile *p,                                         \
+             struct brw_reg dest,                                            \
+             struct brw_reg src)                                             \
+{                                                                            \
+   struct brw_instruction *rnd, *add;                                        \
+   rnd = next_insn(p, BRW_OPCODE_##OP);                                              \
+   brw_set_dest(rnd, dest);                                                  \
+   brw_set_src0(rnd, src);                                                   \
+   rnd->header.destreg__conditionalmod = 0x7; /* turn on round-increments */  \
+                                                                             \
+   add = brw_ADD(p, dest, dest, brw_imm_f(1.0f));                            \
+   add->header.predicate_control = BRW_PREDICATE_NORMAL;                     \
+}
+
 
 ALU1(MOV)
 ALU2(SEL)
@@ -668,7 +688,6 @@ ALU2(RSL)
 ALU2(ASR)
 ALU1(FRC)
 ALU1(RNDD)
-ALU1(RNDZ)
 ALU2(MAC)
 ALU2(MACH)
 ALU1(LZD)
@@ -679,6 +698,11 @@ ALU2(DP2)
 ALU2(LINE)
 ALU2(PLN)
 
+
+ROUND(RNDZ)
+ROUND(RNDE)
+
+
 struct brw_instruction *brw_ADD(struct brw_compile *p,
                                struct brw_reg dest,
                                struct brw_reg src0,
@@ -1147,6 +1171,17 @@ void brw_math( struct brw_compile *p,
    if (intel->gen >= 6) {
       struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
 
+      assert(dest.file == BRW_GENERAL_REGISTER_FILE);
+      assert(src.file == BRW_GENERAL_REGISTER_FILE);
+
+      assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
+      assert(src.hstride == BRW_HORIZONTAL_STRIDE_1);
+
+      if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
+         function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
+        assert(src.type == BRW_REGISTER_TYPE_F);
+      }
+
       /* Math is the same ISA format as other opcodes, except that CondModifier
        * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
        */
@@ -1190,6 +1225,22 @@ void brw_math2(struct brw_compile *p,
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
 
    assert(intel->gen >= 6);
+   (void) intel;
+
+
+   assert(dest.file == BRW_GENERAL_REGISTER_FILE);
+   assert(src0.file == BRW_GENERAL_REGISTER_FILE);
+   assert(src1.file == BRW_GENERAL_REGISTER_FILE);
+
+   assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
+   assert(src0.hstride == BRW_HORIZONTAL_STRIDE_1);
+   assert(src1.hstride == BRW_HORIZONTAL_STRIDE_1);
+
+   if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
+       function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
+      assert(src0.type == BRW_REGISTER_TYPE_F);
+      assert(src1.type == BRW_REGISTER_TYPE_F);
+   }
 
    /* Math is the same ISA format as other opcodes, except that CondModifier
     * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
@@ -1821,7 +1872,8 @@ void brw_ff_sync(struct brw_compile *p,
    if (intel->gen >= 6) {
       brw_push_insn_state(p);
       brw_set_mask_control( p, BRW_MASK_DISABLE );
-      brw_MOV(p, brw_message_reg(msg_reg_nr), src0);
+      brw_MOV(p, retype(brw_message_reg(msg_reg_nr), BRW_REGISTER_TYPE_UD),
+             retype(src0, BRW_REGISTER_TYPE_UD));
       brw_pop_insn_state(p);
       src0 = brw_message_reg(msg_reg_nr);
    }