gallivm: remove LICM pass
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_tgsi.c
index 614c6558ede13591412ce90f45e6590a411667e9..64d2cd703be7fc805b2a39d54749103b2ce200c9 100644 (file)
@@ -186,30 +186,30 @@ void lp_build_fetch_args(
 }
 
 /**
- * with doubles src and dst channels aren't 1:1.
+ * with 64-bit src and dst channels aren't 1:1.
  * check the src/dst types for the opcode,
- * 1. if neither is double then src == dst;
- * 2. if dest is double
+ * 1. if neither is 64-bit then src == dst;
+ * 2. if dest is 64-bit
  *     - don't store to y or w
- *     - if src is double then src == dst.
+ *     - if src is 64-bit then src == dst.
  *     - else for f2d, d.xy = s.x
  *     - else for f2d, d.zw = s.y
- * 3. if dst is single, src is double
+ * 3. if dst is single, src is 64-bit
  *    - map dst x,z to src xy;
  *    - map dst y,w to src zw;
  */
-static int get_src_chan_idx(unsigned opcode,
+static int get_src_chan_idx(enum tgsi_opcode opcode,
                             int dst_chan_index)
 {
-   enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(opcode);
-   enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(opcode);
+   enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(opcode, 0);
+   enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(opcode, 0);
 
-   if (dtype != TGSI_TYPE_DOUBLE && stype != TGSI_TYPE_DOUBLE)
+   if (!tgsi_type_is_64bit(dtype) && !tgsi_type_is_64bit(stype))
       return dst_chan_index;
-   if (dtype == TGSI_TYPE_DOUBLE) {
+   if (tgsi_type_is_64bit(dtype)) {
       if (dst_chan_index == 1 || dst_chan_index == 3)
          return -1;
-      if (stype == TGSI_TYPE_DOUBLE)
+      if (tgsi_type_is_64bit(stype))
          return dst_chan_index;
       if (dst_chan_index == 0)
          return 0;
@@ -232,10 +232,10 @@ lp_build_tgsi_inst_llvm(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_instruction * inst)
 {
-   unsigned tgsi_opcode = inst->Instruction.Opcode;
-   const struct tgsi_opcode_info * info = tgsi_get_opcode_info(tgsi_opcode);
+   enum tgsi_opcode opcode = inst->Instruction.Opcode;
+   const struct tgsi_opcode_info * info = tgsi_get_opcode_info(opcode);
    const struct lp_build_tgsi_action * action =
-                                         &bld_base->op_actions[tgsi_opcode];
+                                         &bld_base->op_actions[opcode];
    struct lp_build_emit_data emit_data;
    unsigned chan_index;
    LLVMValueRef val;
@@ -251,9 +251,6 @@ lp_build_tgsi_inst_llvm(
    case TGSI_OPCODE_UP2US:
    case TGSI_OPCODE_UP4B:
    case TGSI_OPCODE_UP4UB:
-   case TGSI_OPCODE_PUSHA:
-   case TGSI_OPCODE_POPA:
-   case TGSI_OPCODE_SAD:
       /* deprecated? */
       assert(0);
       return FALSE;
@@ -267,11 +264,17 @@ lp_build_tgsi_inst_llvm(
 
    memset(&emit_data, 0, sizeof(emit_data));
 
-   assert(info->num_dst <= 1);
+   assert(info->num_dst <= 2);
    if (info->num_dst) {
       TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
          emit_data.output[chan_index] = bld_base->base.undef;
       }
+
+      if (info->num_dst >= 2) {
+         TGSI_FOR_EACH_DST1_ENABLED_CHANNEL( inst, chan_index ) {
+            emit_data.output1[chan_index] = bld_base->base.undef;
+         }
+      }
    }
 
    emit_data.inst = inst;
@@ -312,30 +315,38 @@ lp_build_tgsi_inst_llvm(
          TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) {
             emit_data.output[chan_index] = val;
          }
+
+         if (info->num_dst >= 2) {
+            val = emit_data.output1[0];
+            memset(emit_data.output1, 0, sizeof(emit_data.output1));
+            TGSI_FOR_EACH_DST1_ENABLED_CHANNEL(inst, chan_index) {
+               emit_data.output1[chan_index] = val;
+            }
+         }
       }
    }
 
    if (info->num_dst > 0 && info->opcode != TGSI_OPCODE_STORE) {
-      bld_base->emit_store(bld_base, inst, info, emit_data.output);
+      bld_base->emit_store(bld_base, inst, info, 0, emit_data.output);
+      if (info->num_dst >= 2)
+         bld_base->emit_store(bld_base, inst, info, 1, emit_data.output1);
    }
    return TRUE;
 }
 
 
 LLVMValueRef
-lp_build_emit_fetch(
+lp_build_emit_fetch_src(
    struct lp_build_tgsi_context *bld_base,
-   const struct tgsi_full_instruction *inst,
-   unsigned src_op,
+   const struct tgsi_full_src_register *reg,
+   enum tgsi_opcode_type stype,
    const unsigned chan_index)
 {
-   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
    unsigned swizzle;
    LLVMValueRef res;
-   enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
 
    if (chan_index == LP_CHAN_ALL) {
-      swizzle = ~0;
+      swizzle = ~0u;
    } else {
       swizzle = tgsi_util_get_full_src_register_swizzle(reg, chan_index);
       if (swizzle > 3) {
@@ -360,10 +371,12 @@ lp_build_emit_fetch(
       case TGSI_TYPE_DOUBLE:
       case TGSI_TYPE_UNTYPED:
           /* modifiers on movs assume data is float */
-         res = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS, res);
+         res = lp_build_abs(&bld_base->base, res);
          break;
       case TGSI_TYPE_UNSIGNED:
       case TGSI_TYPE_SIGNED:
+      case TGSI_TYPE_UNSIGNED64:
+      case TGSI_TYPE_SIGNED64:
       case TGSI_TYPE_VOID:
       default:
          /* abs modifier is only legal on floating point types */
@@ -387,6 +400,10 @@ lp_build_emit_fetch(
       case TGSI_TYPE_UNSIGNED:
          res = lp_build_negate( &bld_base->int_bld, res );
          break;
+      case TGSI_TYPE_SIGNED64:
+      case TGSI_TYPE_UNSIGNED64:
+         res = lp_build_negate( &bld_base->int64_bld, res );
+         break;
       case TGSI_TYPE_VOID:
       default:
          assert(0);
@@ -398,7 +415,7 @@ lp_build_emit_fetch(
     * Swizzle the argument
     */
 
-   if (swizzle == ~0) {
+   if (swizzle == ~0u) {
       res = bld_base->emit_swizzle(bld_base, res,
                      reg->Register.SwizzleX,
                      reg->Register.SwizzleY,
@@ -407,7 +424,21 @@ lp_build_emit_fetch(
    }
 
    return res;
+}
+
+
+LLVMValueRef
+lp_build_emit_fetch(
+   struct lp_build_tgsi_context *bld_base,
+   const struct tgsi_full_instruction *inst,
+   unsigned src_op,
+   const unsigned chan_index)
+{
+   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
+   enum tgsi_opcode_type stype =
+      tgsi_opcode_infer_src_type(inst->Instruction.Opcode, src_op);
 
+   return lp_build_emit_fetch_src(bld_base, reg, stype, chan_index);
 }
 
 
@@ -453,7 +484,7 @@ lp_build_emit_fetch_texoffset(
     * Swizzle the argument
     */
 
-   if (swizzle == ~0) {
+   if (swizzle == ~0u) {
       res = bld_base->emit_swizzle(bld_base, res,
                                    off->SwizzleX,
                                    off->SwizzleY,
@@ -512,11 +543,9 @@ lp_build_tgsi_llvm(
    while (bld_base->pc != -1) {
       const struct tgsi_full_instruction *instr =
          bld_base->instructions + bld_base->pc;
-      const struct tgsi_opcode_info *opcode_info =
-         tgsi_get_opcode_info(instr->Instruction.Opcode);
       if (!lp_build_tgsi_inst_llvm(bld_base, instr)) {
          _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
-                       opcode_info->mnemonic);
+                       tgsi_get_opcode_name(instr->Instruction.Opcode));
          return FALSE;
       }
    }