cell: Added support for ABS instruction
authorJonathan White <jwhite@tungstengraphics.com>
Mon, 15 Sep 2008 18:27:10 +0000 (12:27 -0600)
committerJonathan White <jwhite@tungstengraphics.com>
Mon, 15 Sep 2008 18:27:10 +0000 (12:27 -0600)
src/gallium/drivers/cell/ppu/cell_gen_fp.c

index 9eae57bb76b7659a94ecb780e2bb406a850de69a..33f3c74b56901ae4e539cefce20af4557a81157d 100644 (file)
@@ -424,7 +424,7 @@ static boolean
 emit_MAD(struct codegen *gen, const struct tgsi_full_instruction *inst)
 {
    int ch;
-   spe_comment(gen->f, -4, "MUL:");
+   spe_comment(gen->f, -4, "MAD:");
    for (ch = 0; ch < 4; ch++) {
       if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << ch)) {
          int s1_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
@@ -463,6 +463,33 @@ emit_MUL(struct codegen *gen, const struct tgsi_full_instruction *inst)
    return true;
 }
 
+/**
+ * Emit absolute value.  See emit_ADD for comments.
+ */
+static boolean
+emit_ABS(struct codegen *gen, const struct tgsi_full_instruction *inst)
+{
+   int ch;
+   spe_comment(gen->f, -4, "ABS:");
+   for (ch = 0; ch < 4; ch++) {
+      if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << ch)) {
+         int s1_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
+         int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+         const int bit31mask_reg = get_itemp(gen);
+
+         /* mask with bit 31 set, the rest cleared */  
+         spe_load_int(gen->f, bit31mask_reg, (1 << 31));
+
+         /* d = sign bit cleared in s1 */
+         spe_andc(gen->f, d_reg, s1_reg, bit31mask_reg);
+
+         store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+         free_itemps(gen);
+      }
+   }
+   return true;
+}
+
 /**
  * Emit set-if-greater-than.
  * Note that the SPE fcgt instruction produces 0x0 and 0xffffffff as
@@ -625,6 +652,8 @@ emit_instruction(struct codegen *gen,
       return emit_SUB(gen, inst);
    case TGSI_OPCODE_MAD:
       return emit_MAD(gen, inst);
+   case TGSI_OPCODE_ABS:
+      return emit_ABS(gen, inst);
    case TGSI_OPCODE_SGT:
       return emit_SGT(gen, inst);
    case TGSI_OPCODE_END: