* The multiplication by sgn(x) can be simplified using CMP:
* y * sgn(x) = (x < 0 ? -y : y)
*/
+
+ struct rc_src_register abs;
+
+ if (c->is_r500) {
+ abs = absolute(inst->U.I.SrcReg[0]);
+ } else {
+ /* abs isn't free on r300/r400, so we want
+ * to avoid doing it twice
+ */
+ int tmp = rc_find_free_temporary(c);
+
+ emit2(c, inst->Prev, RC_OPCODE_MAX, NULL, dstregtmpmask(tmp, RC_MASK_XYZW),
+ srcregswz(inst->U.I.SrcReg[0].File, inst->U.I.SrcReg[0].Index, RC_SWIZZLE_XYZW),
+ negate(srcregswz(inst->U.I.SrcReg[0].File, inst->U.I.SrcReg[0].Index, RC_SWIZZLE_XYZW)));
+ abs = srcregswz(RC_FILE_TEMPORARY, tmp, inst->U.I.SrcReg[0].Swizzle);
+
+ }
struct rc_dst_register dst = try_to_reuse_dst(c, inst);
- emit1(c, inst->Prev, RC_OPCODE_FRC, NULL, dst, absolute(inst->U.I.SrcReg[0]));
- emit2(c, inst->Prev, RC_OPCODE_ADD, NULL, dst, absolute(inst->U.I.SrcReg[0]),
+ emit1(c, inst->Prev, RC_OPCODE_FRC, NULL, dst, abs);
+ emit2(c, inst->Prev, RC_OPCODE_ADD, NULL, dst, abs,
negate(srcreg(RC_FILE_TEMPORARY, dst.Index)));
emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, inst->U.I.SrcReg[0],
negate(srcreg(RC_FILE_TEMPORARY, dst.Index)), srcreg(RC_FILE_TEMPORARY, dst.Index));
+
rc_remove_instruction(inst);
}