11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2008 Nicolai Haehnle. 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved. 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions: 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software. 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @file 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Shareable transformations that transform "special" ALU instructions 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * into ALU instructions that are supported by hardware. 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program_alu.h" 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler.h" 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_compiler_util.h" 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_instruction *emit1( 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, struct rc_instruction * after, 4473249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard rc_opcode Opcode, struct rc_sub_instruction * base, 4573249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard struct rc_dst_register DstReg, struct rc_src_register SrcReg) 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *fpi = rc_insert_new_instruction(c, after); 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4973249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard if (base) { 5073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard memcpy(&fpi->U.I, base, sizeof(struct rc_sub_instruction)); 5173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard } 5273249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.Opcode = Opcode; 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.DstReg = DstReg; 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[0] = SrcReg; 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return fpi; 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_instruction *emit2( 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, struct rc_instruction * after, 6173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard rc_opcode Opcode, struct rc_sub_instruction * base, 6273249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard struct rc_dst_register DstReg, 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register SrcReg0, struct rc_src_register SrcReg1) 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *fpi = rc_insert_new_instruction(c, after); 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6773249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard if (base) { 6873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard memcpy(&fpi->U.I, base, sizeof(struct rc_sub_instruction)); 6973249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard } 7073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.Opcode = Opcode; 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.DstReg = DstReg; 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[0] = SrcReg0; 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[1] = SrcReg1; 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return fpi; 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_instruction *emit3( 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, struct rc_instruction * after, 8073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard rc_opcode Opcode, struct rc_sub_instruction * base, 8173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard struct rc_dst_register DstReg, 821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register SrcReg0, struct rc_src_register SrcReg1, 831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register SrcReg2) 841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *fpi = rc_insert_new_instruction(c, after); 861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8773249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard if (base) { 8873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard memcpy(&fpi->U.I, base, sizeof(struct rc_sub_instruction)); 8973249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard } 9073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard 911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.Opcode = Opcode; 921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.DstReg = DstReg; 931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[0] = SrcReg0; 941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[1] = SrcReg1; 951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák fpi->U.I.SrcReg[2] = SrcReg2; 961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return fpi; 971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_dst_register dstregtmpmask(int index, int mask) 1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 10132faaea743ca74f4ba29184ef44ebf2c0e962a46Brian Paul struct rc_dst_register dst = {0, 0, 0}; 1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.File = RC_FILE_TEMPORARY; 1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.Index = index; 1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.WriteMask = mask; 1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return dst; 1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic const struct rc_src_register builtin_zero = { 1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .File = RC_FILE_NONE, 1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Index = 0, 1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Swizzle = RC_SWIZZLE_0000 1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic const struct rc_src_register builtin_one = { 1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .File = RC_FILE_NONE, 1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Index = 0, 1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Swizzle = RC_SWIZZLE_1111 1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 1183d32e589879806297258e36ea80aae5044293ca3Tom Stellard 1193d32e589879806297258e36ea80aae5044293ca3Tom Stellardstatic const struct rc_src_register builtin_half = { 1203d32e589879806297258e36ea80aae5044293ca3Tom Stellard .File = RC_FILE_NONE, 1213d32e589879806297258e36ea80aae5044293ca3Tom Stellard .Index = 0, 1223d32e589879806297258e36ea80aae5044293ca3Tom Stellard .Swizzle = RC_SWIZZLE_HHHH 1233d32e589879806297258e36ea80aae5044293ca3Tom Stellard}; 1243d32e589879806297258e36ea80aae5044293ca3Tom Stellard 1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic const struct rc_src_register srcreg_undefined = { 1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .File = RC_FILE_NONE, 1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Index = 0, 1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák .Swizzle = RC_SWIZZLE_XYZW 1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register srcreg(int file, int index) 1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src = srcreg_undefined; 1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.File = file; 1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.Index = index; 1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return src; 1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register srcregswz(int file, int index, int swz) 1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src = srcreg_undefined; 1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.File = file; 1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.Index = index; 1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.Swizzle = swz; 1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return src; 1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register absolute(struct rc_src_register reg) 1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register newreg = reg; 1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák newreg.Abs = 1; 1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák newreg.Negate = RC_MASK_NONE; 1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return newreg; 1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register negate(struct rc_src_register reg) 1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register newreg = reg; 1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák newreg.Negate = newreg.Negate ^ RC_MASK_XYZW; 1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return newreg; 1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle(struct rc_src_register reg, 1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_swizzle x, rc_swizzle y, rc_swizzle z, rc_swizzle w) 1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register swizzled = reg; 1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzled.Swizzle = combine_swizzles4(reg.Swizzle, x, y, z, w); 1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzled; 1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle_smear(struct rc_src_register reg, 1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_swizzle x) 1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzle(reg, x, x, x, x); 1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle_xxxx(struct rc_src_register reg) 1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzle_smear(reg, RC_SWIZZLE_X); 1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle_yyyy(struct rc_src_register reg) 1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzle_smear(reg, RC_SWIZZLE_Y); 1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle_zzzz(struct rc_src_register reg) 1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzle_smear(reg, RC_SWIZZLE_Z); 1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_src_register swizzle_wwww(struct rc_src_register reg) 1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return swizzle_smear(reg, RC_SWIZZLE_W); 1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int is_dst_safe_to_reuse(struct rc_instruction *inst) 1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák const struct rc_opcode_info *info = rc_get_opcode_info(inst->U.I.Opcode); 2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned i; 2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák assert(info->HasDstReg); 2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.DstReg.File != RC_FILE_TEMPORARY) 2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (i = 0; i < info->NumSrcRegs; i++) { 2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY && 2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[i].Index == inst->U.I.DstReg.Index) 2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic struct rc_dst_register try_to_reuse_dst(struct radeon_compiler *c, 2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst) 2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned tmp; 2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (is_dst_safe_to_reuse(inst)) 2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp = inst->U.I.DstReg.Index; 2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák else 2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp = rc_find_free_temporary(c); 2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return dstregtmpmask(tmp, inst->U.I.DstReg.WriteMask); 2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_ABS(struct radeon_compiler* c, 2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src = inst->U.I.SrcReg[0]; 2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.Abs = 1; 2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src.Negate = RC_MASK_NONE; 23573249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_MOV, &inst->U.I, inst->U.I.DstReg, src); 2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_CEIL(struct radeon_compiler* c, 2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Assuming: 2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ceil(x) = -floor(-x) 2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * After inlining floor: 2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ceil(x) = -(-x-frac(-x)) 2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * After simplification: 2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ceil(x) = x+frac(-x) 2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dst, negate(inst->U.I.SrcReg[0])); 25473249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_ADD, &inst->U.I, inst->U.I.DstReg, 2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, dst.Index)); 2561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 2571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_CLAMP(struct radeon_compiler *c, 2601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst) 2611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* CLAMP dst, src, min, max 2631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * into: 2641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MIN tmp, src, max 2651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MAX dst, tmp, min 2661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 2671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 2681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MIN, 0, dst, 2691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], inst->U.I.SrcReg[2]); 27073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_MAX, &inst->U.I, inst->U.I.DstReg, 2711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[1]); 2721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 2731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_DP2(struct radeon_compiler* c, 2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src0 = inst->U.I.SrcReg[0]; 2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src1 = inst->U.I.SrcReg[1]; 2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Negate &= ~(RC_MASK_Z | RC_MASK_W); 2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle &= ~(63 << (3 * 2)); 2821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle |= (RC_SWIZZLE_ZERO << (3 * 2)) | (RC_SWIZZLE_ZERO << (3 * 3)); 2831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Negate &= ~(RC_MASK_Z | RC_MASK_W); 2841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Swizzle &= ~(63 << (3 * 2)); 2851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Swizzle |= (RC_SWIZZLE_ZERO << (3 * 2)) | (RC_SWIZZLE_ZERO << (3 * 3)); 28673249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_DP3, &inst->U.I, inst->U.I.DstReg, src0, src1); 2871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 2881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 2891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_DPH(struct radeon_compiler* c, 2911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 2921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 2931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src0 = inst->U.I.SrcReg[0]; 2941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Negate &= ~RC_MASK_W; 2951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle &= ~(7 << (3 * 3)); 2961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle |= RC_SWIZZLE_ONE << (3 * 3); 29773249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_DP4, &inst->U.I, inst->U.I.DstReg, src0, inst->U.I.SrcReg[1]); 2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * [1, src0.y*src1.y, src0.z, src1.w] 3031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * So basically MUL with lotsa swizzling. 3041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_DST(struct radeon_compiler* c, 3061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 30873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_MUL, &inst->U.I, inst->U.I.DstReg, 3091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_ONE, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ONE), 3101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[1], RC_SWIZZLE_ONE, RC_SWIZZLE_Y, RC_SWIZZLE_ONE, RC_SWIZZLE_W)); 3111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 3121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_FLR(struct radeon_compiler* c, 3151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 3161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 3181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dst, inst->U.I.SrcReg[0]); 31973249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_ADD, &inst->U.I, inst->U.I.DstReg, 3201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], negate(srcreg(RC_FILE_TEMPORARY, dst.Index))); 3211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 3221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3247f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšákstatic void transform_TRUNC(struct radeon_compiler* c, 3257f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák struct rc_instruction* inst) 3267f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák{ 3277f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák /* Definition of trunc: 3287f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák * trunc(x) = (abs(x) - fract(abs(x))) * sgn(x) 3297f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák * 3307f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák * The multiplication by sgn(x) can be simplified using CMP: 3317f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák * y * sgn(x) = (x < 0 ? -y : y) 3327f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák */ 3337f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 3347f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dst, absolute(inst->U.I.SrcReg[0])); 3357f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, absolute(inst->U.I.SrcReg[0]), 3367f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák negate(srcreg(RC_FILE_TEMPORARY, dst.Index))); 3377f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, inst->U.I.SrcReg[0], 3387f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák negate(srcreg(RC_FILE_TEMPORARY, dst.Index)), srcreg(RC_FILE_TEMPORARY, dst.Index)); 3397f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák rc_remove_instruction(inst); 3407f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák} 3417f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák 3421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Definition of LIT (from ARB_fragment_program): 3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * tmp = VectorLoad(op0); 3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if (tmp.x < 0) tmp.x = 0; 3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if (tmp.y < 0) tmp.y = 0; 3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon); 3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon; 3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * result.x = 1.0; 3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * result.y = tmp.x; 3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0; 3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * result.w = 1.0; 3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The longest path of computation is the one leading to result.z, 3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * consisting of 5 operations. This implementation of LIT takes 3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 5 slots, if the subsequent optimization passes are clever enough 3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * to pair instructions correctly. 3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_LIT(struct radeon_compiler* c, 3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constant; 3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constant_swizzle; 3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int temp; 3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register srctemp; 3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constant = rc_constants_add_immediate_scalar(&c->Program.Constants, -127.999999, &constant_swizzle); 3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.DstReg.WriteMask != RC_MASK_XYZW || inst->U.I.DstReg.File != RC_FILE_TEMPORARY) { 3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst_mov; 3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst_mov = emit1(c, inst, 3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_OPCODE_MOV, 0, inst->U.I.DstReg, 3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, rc_find_free_temporary(c))); 3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index; 3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg.WriteMask = RC_MASK_XYZW; 3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák temp = inst->U.I.DstReg.Index; 3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srctemp = srcreg(RC_FILE_TEMPORARY, temp); 3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.x = max(0.0, Src.x); */ 3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.y = max(0.0, Src.y); */ 3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.w = clamp(Src.z, -128+eps, 128-eps); */ 3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MAX, 0, 3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_XYW), 3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], 3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(srcreg(RC_FILE_CONSTANT, constant), 3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák RC_SWIZZLE_ZERO, RC_SWIZZLE_ZERO, RC_SWIZZLE_ZERO, constant_swizzle&3)); 3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MIN, 0, 3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_Z), 3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srctemp), 3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle))); 3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.w = Pow(tmp.y, tmp.w) */ 3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_LG2, 0, 4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_W), 4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_yyyy(srctemp)); 4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, 4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_W), 4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srctemp), 4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_zzzz(srctemp)); 4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_EX2, 0, 4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_W), 4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srctemp)); 4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.z = (tmp.x > 0) ? tmp.w : 0.0 */ 41173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, 4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_Z), 4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(swizzle_xxxx(srctemp)), 4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srctemp), 4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_zero); 4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* tmp.x, tmp.y, tmp.w = 1.0, tmp.x, 1.0 */ 41873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_MOV, &inst->U.I, 4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(temp, RC_MASK_XYW), 4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(srctemp, RC_SWIZZLE_ONE, RC_SWIZZLE_X, RC_SWIZZLE_ONE, RC_SWIZZLE_ONE)); 4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_LRP(struct radeon_compiler* c, 4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, 4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst, 4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1], negate(inst->U.I.SrcReg[2])); 43373249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_MAD, &inst->U.I, 4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[2]); 4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_POW(struct radeon_compiler* c, 4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register tempdst = try_to_reuse_dst(c, inst); 4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register tempsrc = srcreg(RC_FILE_TEMPORARY, tempdst.Index); 4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tempdst.WriteMask = RC_MASK_W; 4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tempsrc.Swizzle = RC_SWIZZLE_WWWW; 4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_LG2, 0, tempdst, swizzle_xxxx(inst->U.I.SrcReg[0])); 4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, tempdst, tempsrc, swizzle_xxxx(inst->U.I.SrcReg[1])); 45073249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_EX2, &inst->U.I, inst->U.I.DstReg, tempsrc); 4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4553d32e589879806297258e36ea80aae5044293ca3Tom Stellard/* dst = ROUND(src) : 4563d32e589879806297258e36ea80aae5044293ca3Tom Stellard * add = src + .5 4573d32e589879806297258e36ea80aae5044293ca3Tom Stellard * frac = FRC(add) 4583d32e589879806297258e36ea80aae5044293ca3Tom Stellard * dst = add - frac 4593d32e589879806297258e36ea80aae5044293ca3Tom Stellard * 4603d32e589879806297258e36ea80aae5044293ca3Tom Stellard * According to the GLSL spec, the implementor can decide which way to round 4613d32e589879806297258e36ea80aae5044293ca3Tom Stellard * when the fraction is .5. We round down for .5. 4623d32e589879806297258e36ea80aae5044293ca3Tom Stellard * 4633d32e589879806297258e36ea80aae5044293ca3Tom Stellard */ 4643d32e589879806297258e36ea80aae5044293ca3Tom Stellardstatic void transform_ROUND(struct radeon_compiler* c, 4653d32e589879806297258e36ea80aae5044293ca3Tom Stellard struct rc_instruction* inst) 4663d32e589879806297258e36ea80aae5044293ca3Tom Stellard{ 4673d32e589879806297258e36ea80aae5044293ca3Tom Stellard unsigned int mask = inst->U.I.DstReg.WriteMask; 4683d32e589879806297258e36ea80aae5044293ca3Tom Stellard unsigned int frac_index, add_index; 4693d32e589879806297258e36ea80aae5044293ca3Tom Stellard struct rc_dst_register frac_dst, add_dst; 4703d32e589879806297258e36ea80aae5044293ca3Tom Stellard struct rc_src_register frac_src, add_src; 4713d32e589879806297258e36ea80aae5044293ca3Tom Stellard 4723d32e589879806297258e36ea80aae5044293ca3Tom Stellard /* add = src + .5 */ 4733d32e589879806297258e36ea80aae5044293ca3Tom Stellard add_index = rc_find_free_temporary(c); 4743d32e589879806297258e36ea80aae5044293ca3Tom Stellard add_dst = dstregtmpmask(add_index, mask); 4753d32e589879806297258e36ea80aae5044293ca3Tom Stellard emit2(c, inst->Prev, RC_OPCODE_ADD, 0, add_dst, inst->U.I.SrcReg[0], 4763d32e589879806297258e36ea80aae5044293ca3Tom Stellard builtin_half); 4773d32e589879806297258e36ea80aae5044293ca3Tom Stellard add_src = srcreg(RC_FILE_TEMPORARY, add_dst.Index); 4783d32e589879806297258e36ea80aae5044293ca3Tom Stellard 4793d32e589879806297258e36ea80aae5044293ca3Tom Stellard 4803d32e589879806297258e36ea80aae5044293ca3Tom Stellard /* frac = FRC(add) */ 4813d32e589879806297258e36ea80aae5044293ca3Tom Stellard frac_index = rc_find_free_temporary(c); 4823d32e589879806297258e36ea80aae5044293ca3Tom Stellard frac_dst = dstregtmpmask(frac_index, mask); 4833d32e589879806297258e36ea80aae5044293ca3Tom Stellard emit1(c, inst->Prev, RC_OPCODE_FRC, 0, frac_dst, add_src); 4843d32e589879806297258e36ea80aae5044293ca3Tom Stellard frac_src = srcreg(RC_FILE_TEMPORARY, frac_dst.Index); 4853d32e589879806297258e36ea80aae5044293ca3Tom Stellard 4863d32e589879806297258e36ea80aae5044293ca3Tom Stellard /* dst = add - frac */ 4873d32e589879806297258e36ea80aae5044293ca3Tom Stellard emit2(c, inst->Prev, RC_OPCODE_ADD, 0, inst->U.I.DstReg, 4883d32e589879806297258e36ea80aae5044293ca3Tom Stellard add_src, negate(frac_src)); 4893d32e589879806297258e36ea80aae5044293ca3Tom Stellard rc_remove_instruction(inst); 4903d32e589879806297258e36ea80aae5044293ca3Tom Stellard} 4913d32e589879806297258e36ea80aae5044293ca3Tom Stellard 4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_RSQ(struct radeon_compiler* c, 4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0] = absolute(inst->U.I.SrcReg[0]); 4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SEQ(struct radeon_compiler* c, 4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1])); 50473249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(absolute(srcreg(RC_FILE_TEMPORARY, dst.Index))), builtin_zero, builtin_one); 5061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SFL(struct radeon_compiler* c, 5111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 51373249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_MOV, &inst->U.I, inst->U.I.DstReg, builtin_zero); 5141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SGE(struct radeon_compiler* c, 5181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1])); 52373249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_zero, builtin_one); 5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SGT(struct radeon_compiler* c, 5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]); 53573249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_one, builtin_zero); 5371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SLE(struct radeon_compiler* c, 5421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, negate(inst->U.I.SrcReg[0]), inst->U.I.SrcReg[1]); 54773249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_zero, builtin_one); 5491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SLT(struct radeon_compiler* c, 5541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1])); 55973249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), builtin_one, builtin_zero); 5611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SNE(struct radeon_compiler* c, 5661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 5691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dst, inst->U.I.SrcReg[0], negate(inst->U.I.SrcReg[1])); 57173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_CMP, &inst->U.I, inst->U.I.DstReg, 5721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(absolute(srcreg(RC_FILE_TEMPORARY, dst.Index))), builtin_one, builtin_zero); 5731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 5751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 5761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SSG(struct radeon_compiler* c, 5781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 5791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 5801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* result = sign(x) 5811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 5821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * CMP tmp0, -x, 1, 0 5831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * CMP tmp1, x, 1, 0 5841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ADD result, tmp0, -tmp1; 5851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 5861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst0; 5871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned tmp1; 5881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* 0 < x */ 5901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst0 = try_to_reuse_dst(c, inst); 5911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_CMP, 0, 5921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst0, 5931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(inst->U.I.SrcReg[0]), 5941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_one, 5951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_zero); 5961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x < 0 */ 5981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp1 = rc_find_free_temporary(c); 5991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_CMP, 0, 6001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(tmp1, inst->U.I.DstReg.WriteMask), 6011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], 6021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_one, 6031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_zero); 6041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Either both are zero, or one of them is one and the other is zero. */ 6061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* result = tmp0 - tmp1 */ 6071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, 6081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 6091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst0.Index), 6101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(srcreg(RC_FILE_TEMPORARY, tmp1))); 6111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 6131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SUB(struct radeon_compiler* c, 6161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 6171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_ADD; 6191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1] = negate(inst->U.I.SrcReg[1]); 6201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_SWZ(struct radeon_compiler* c, 6231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 6241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_MOV; 6261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_XPD(struct radeon_compiler* c, 6291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 6301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 6321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dst, 6341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W), 6351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[1], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W)); 63673249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit3(c, inst->Prev, RC_OPCODE_MAD, &inst->U.I, inst->U.I.DstReg, 6371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W), 6381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(inst->U.I.SrcReg[1], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W), 6391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(srcreg(RC_FILE_TEMPORARY, dst.Index))); 6401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 6421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 6461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Can be used as a transformation for @ref radeonClauseLocalTransform, 6471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * no userData necessary. 6481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 6491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Eliminates the following ALU instructions: 6501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ABS, CEIL, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD 6511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * using: 6521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP 6531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 6541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Transforms RSQ to Radeon's native RSQ by explicitly setting 6551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * absolute value. 6561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 6571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @note should be applicable to R300 and R500 fragment programs. 6581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 6591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint radeonTransformALU( 6601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 6611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst, 6621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void* unused) 6631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(inst->U.I.Opcode) { 6651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_ABS: transform_ABS(c, inst); return 1; 6661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1; 6671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1; 6681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP2: transform_DP2(c, inst); return 1; 6691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DPH: transform_DPH(c, inst); return 1; 6701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DST: transform_DST(c, inst); return 1; 6711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_FLR: transform_FLR(c, inst); return 1; 6721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_LIT: transform_LIT(c, inst); return 1; 6731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_LRP: transform_LRP(c, inst); return 1; 6741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_POW: transform_POW(c, inst); return 1; 6753d32e589879806297258e36ea80aae5044293ca3Tom Stellard case RC_OPCODE_ROUND: transform_ROUND(c, inst); return 1; 6761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_RSQ: transform_RSQ(c, inst); return 1; 6771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SEQ: transform_SEQ(c, inst); return 1; 6781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SFL: transform_SFL(c, inst); return 1; 6791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SGE: transform_SGE(c, inst); return 1; 6801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SGT: transform_SGT(c, inst); return 1; 6811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SLE: transform_SLE(c, inst); return 1; 6821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SLT: transform_SLT(c, inst); return 1; 6831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SNE: transform_SNE(c, inst); return 1; 6841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SSG: transform_SSG(c, inst); return 1; 6851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SUB: transform_SUB(c, inst); return 1; 6861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1; 6877f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák case RC_OPCODE_TRUNC: transform_TRUNC(c, inst); return 1; 6881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_XPD: transform_XPD(c, inst); return 1; 6891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 6901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 6911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 6921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 6931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_ABS(struct radeon_compiler* c, 6961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 6971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 6981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Note: r500 can take absolute values, but r300 cannot. */ 6991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_MAX; 7001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1] = inst->U.I.SrcReg[0]; 7011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW; 7021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_CMP(struct radeon_compiler* c, 7051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 7061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* There is no decent CMP available, so let's rig one up. 7081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * CMP is defined as dst = src0 < 0.0 ? src1 : src2 7091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The following sequence consumes zero to two temps and two extra slots 7101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * (the second temp and the second slot is consumed by transform_LRP), 7111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * but should be equivalent: 7121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 7131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * SLT tmp0, src0, 0.0 7141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LRP dst, tmp0, src1, src2 7151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 7161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Yes, I know, I'm a mad scientist. ~ C. & M. */ 7171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 7181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* SLT tmp0, src0, 0.0 */ 7201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SLT, 0, 7211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst, 7221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], builtin_zero); 7231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* LRP dst, tmp0, src1, src2 */ 7251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák transform_LRP(c, 7261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_LRP, 0, 7271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 7281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[1], inst->U.I.SrcReg[2])); 7291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 7311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_DP2(struct radeon_compiler* c, 7341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 7351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *next_inst = inst->Next; 7371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák transform_DP2(c, inst); 7381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák next_inst->Prev->U.I.Opcode = RC_OPCODE_DP4; 7391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_DP3(struct radeon_compiler* c, 7421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 7431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src0 = inst->U.I.SrcReg[0]; 7451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_src_register src1 = inst->U.I.SrcReg[1]; 7461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Negate &= ~RC_MASK_W; 7471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle &= ~(7 << (3 * 3)); 7481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src0.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3); 7491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Negate &= ~RC_MASK_W; 7501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Swizzle &= ~(7 << (3 * 3)); 7511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src1.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3); 75273249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit2(c, inst->Prev, RC_OPCODE_DP4, &inst->U.I, inst->U.I.DstReg, src0, src1); 7531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 7541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_fix_LIT(struct radeon_compiler* c, 7571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 7581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst = try_to_reuse_dst(c, inst); 7601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned constant_swizzle; 7611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int constant = rc_constants_add_immediate_scalar(&c->Program.Constants, 7621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0.0000000000000000001, 7631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák &constant_swizzle); 7641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* MOV dst, src */ 7661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.WriteMask = RC_MASK_XYZW; 7671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_MOV, 0, 7681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst, 7691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0]); 7701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* MAX dst.y, src, 0.00...001 */ 7721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MAX, 0, 7731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(dst.Index, RC_MASK_Y), 7741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst.Index), 7751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle)); 7761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0] = srcreg(RC_FILE_TEMPORARY, dst.Index); 7781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 7791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_SEQ(struct radeon_compiler *c, 7811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst) 7821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 7831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x = y <==> x >= y && y >= x */ 7841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int tmp = rc_find_free_temporary(c); 7851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x <= y */ 7871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SGE, 0, 7881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(tmp, inst->U.I.DstReg.WriteMask), 7891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], 7901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1]); 7911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* y <= x */ 7931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SGE, 0, 7941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 7951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1], 7961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0]); 7971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 7981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x && y = x * y */ 7991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, 8001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 8011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, tmp), 8021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(inst->U.I.DstReg.File, inst->U.I.DstReg.Index)); 8031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 8051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_SNE(struct radeon_compiler *c, 8081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst) 8091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x != y <==> x < y || y < x */ 8111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int tmp = rc_find_free_temporary(c); 8121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x < y */ 8141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SLT, 0, 8151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(tmp, inst->U.I.DstReg.WriteMask), 8161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], 8171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1]); 8181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* y < x */ 8201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SLT, 0, 8211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 8221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1], 8231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0]); 8241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x || y = max(x, y) */ 8261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MAX, 0, 8271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 8281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, tmp), 8291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(inst->U.I.DstReg.File, inst->U.I.DstReg.Index)); 8301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 8321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_SGT(struct radeon_compiler* c, 8351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 8361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x > y <==> -x < -y */ 8381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_SLT; 8391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0].Negate ^= RC_MASK_XYZW; 8401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW; 8411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_SLE(struct radeon_compiler* c, 8441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 8451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x <= y <==> -x >= -y */ 8471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_SGE; 8481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0].Negate ^= RC_MASK_XYZW; 8491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW; 8501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void transform_r300_vertex_SSG(struct radeon_compiler* c, 8531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst) 8541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 8551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* result = sign(x) 8561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 8571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * SLT tmp0, 0, x; 8581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * SLT tmp1, x, 0; 8591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ADD result, tmp0, -tmp1; 8601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 8611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst0 = try_to_reuse_dst(c, inst); 8621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned tmp1; 8631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* 0 < x */ 8651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst0 = try_to_reuse_dst(c, inst); 8661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SLT, 0, 8671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst0, 8681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_zero, 8691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0]); 8701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* x < 0 */ 8721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tmp1 = rc_find_free_temporary(c); 8731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_SLT, 0, 8741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dstregtmpmask(tmp1, inst->U.I.DstReg.WriteMask), 8751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0], 8761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák builtin_zero); 8771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Either both are zero, or one of them is one and the other is zero. */ 8791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* result = tmp0 - tmp1 */ 8801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_ADD, 0, 8811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, 8821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, dst0.Index), 8831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(srcreg(RC_FILE_TEMPORARY, tmp1))); 8841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 8861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 8871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 8887f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšákstatic void transform_vertex_TRUNC(struct radeon_compiler* c, 8897f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák struct rc_instruction* inst) 8907f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák{ 8917f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák struct rc_instruction *next = inst->Next; 8927f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák 8937f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák /* next->Prev is removed after each transformation and replaced 8947f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák * by a new instruction. */ 8957f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák transform_TRUNC(c, next->Prev); 8967f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák transform_r300_vertex_CMP(c, next->Prev); 8977f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák} 8987f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák 8991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 9001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * For use with rc_local_transform, this transforms non-native ALU 9011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * instructions of the r300 up to r500 vertex engine. 9021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 9031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint r300_transform_vertex_alu( 9041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler * c, 9051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst, 9061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void* unused) 9071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 9081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(inst->U.I.Opcode) { 9091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1; 9101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1; 9111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1; 9121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1; 9131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP2: transform_r300_vertex_DP2(c, inst); return 1; 9141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP3: transform_r300_vertex_DP3(c, inst); return 1; 9151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DPH: transform_DPH(c, inst); return 1; 9161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_FLR: transform_FLR(c, inst); return 1; 9171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_LIT: transform_r300_vertex_fix_LIT(c, inst); return 1; 9181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_LRP: transform_LRP(c, inst); return 1; 9191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SEQ: 9201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!c->is_r500) { 9211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák transform_r300_vertex_SEQ(c, inst); 9221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 9231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 9241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 9251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SFL: transform_SFL(c, inst); return 1; 9261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SGT: transform_r300_vertex_SGT(c, inst); return 1; 9271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SLE: transform_r300_vertex_SLE(c, inst); return 1; 9281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SNE: 9291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!c->is_r500) { 9301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák transform_r300_vertex_SNE(c, inst); 9311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 9321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 9331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 9341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SSG: transform_r300_vertex_SSG(c, inst); return 1; 9351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SUB: transform_SUB(c, inst); return 1; 9361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1; 9377f0fcf17c342dcb788c2182b20973c48806ee498Marek Olšák case RC_OPCODE_TRUNC: transform_vertex_TRUNC(c, inst); return 1; 9381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_XPD: transform_XPD(c, inst); return 1; 9391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 9401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 9411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 9421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 9431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 9441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void sincos_constants(struct radeon_compiler* c, unsigned int *constants) 9451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 9461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák static const float SinCosConsts[2][4] = { 9471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák { 9481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1.273239545, /* 4/PI */ 9491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák -0.405284735, /* -4/(PI*PI) */ 9501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3.141592654, /* PI */ 9511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0.2225 /* weight */ 9521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák }, 9531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák { 9541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0.75, 9551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0.5, 9561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 0.159154943, /* 1/(2*PI) */ 9571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 6.283185307 /* 2*PI */ 9581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 9591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák }; 9601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int i; 9611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 9621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < 2; ++i) 9631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constants[i] = rc_constants_add_immediate_vec4(&c->Program.Constants, SinCosConsts[i]); 9641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 9651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 9661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 9671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Approximate sin(x), where x is clamped to (-pi/2, pi/2). 9681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 9691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MUL tmp.xy, src, { 4/PI, -4/(PI^2) } 9701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MAD tmp.x, tmp.y, |src|, tmp.x 9711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MAD tmp.y, tmp.x, |tmp.x|, -tmp.x 9721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MAD dest, tmp.y, weight, tmp.x 9731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 9741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void sin_approx( 9751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct radeon_compiler* c, struct rc_instruction * inst, 9761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst, struct rc_src_register src, const unsigned int* constants) 9771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 9781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int tempreg = rc_find_free_temporary(c); 9791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 9801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstregtmpmask(tempreg, RC_MASK_XY), 9811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(src), 9821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_CONSTANT, constants[0])); 9831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_X), 9841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_yyyy(srcreg(RC_FILE_TEMPORARY, tempreg)), 9851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák absolute(swizzle_xxxx(src)), 9861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg))); 9871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_Y), 9881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg)), 9891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák absolute(swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg))), 9901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg)))); 9911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dst, 9921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_yyyy(srcreg(RC_FILE_TEMPORARY, tempreg)), 9931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_CONSTANT, constants[0])), 9941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg))); 9951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 9961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 9971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 9981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Translate the trigonometric functions COS, SIN, and SCS 9991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * using only the basic instructions 10001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MOV, ADD, MUL, MAD, FRC 10011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 10021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint r300_transform_trig_simple(struct radeon_compiler* c, 10031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst, 10041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void* unused) 10051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 10061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constants[2]; 10071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int tempreg; 10081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode != RC_OPCODE_COS && 10101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SIN && 10111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SCS) 10121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 10131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tempreg = rc_find_free_temporary(c); 10151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sincos_constants(c, constants); 10171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode == RC_OPCODE_COS) { 10191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* MAD tmp.x, src, 1/(2*PI), 0.75 */ 10201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* FRC tmp.x, tmp.x */ 10211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* MAD tmp.z, tmp.x, 2*PI, -PI */ 10221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W), 10231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(inst->U.I.SrcReg[0]), 10241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[1])), 10251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(srcreg(RC_FILE_CONSTANT, constants[1]))); 10261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_W), 10271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg))); 10281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W), 10291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg)), 10301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_CONSTANT, constants[1])), 10311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[0])))); 10321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sin_approx(c, inst, inst->U.I.DstReg, 10341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg)), 10351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constants); 10361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (inst->U.I.Opcode == RC_OPCODE_SIN) { 10371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W), 10381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(inst->U.I.SrcReg[0]), 10391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[1])), 10401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_yyyy(srcreg(RC_FILE_CONSTANT, constants[1]))); 10411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_W), 10421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg))); 10431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W), 10441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg)), 10451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_CONSTANT, constants[1])), 10461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[0])))); 10471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sin_approx(c, inst, inst->U.I.DstReg, 10491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_TEMPORARY, tempreg)), 10501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constants); 10511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 10521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register dst; 10531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_XY), 10551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(inst->U.I.SrcReg[0]), 10561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[1])), 10571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_W)); 10581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_XY), 10591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, tempreg)); 10601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_XY), 10611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, tempreg), 10621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_wwww(srcreg(RC_FILE_CONSTANT, constants[1])), 10631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák negate(swizzle_zzzz(srcreg(RC_FILE_CONSTANT, constants[0])))); 10641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst = inst->U.I.DstReg; 10661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.WriteMask = inst->U.I.DstReg.WriteMask & RC_MASK_X; 10681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sin_approx(c, inst, dst, 10691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(srcreg(RC_FILE_TEMPORARY, tempreg)), 10701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constants); 10711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dst.WriteMask = inst->U.I.DstReg.WriteMask & RC_MASK_Y; 10731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák sin_approx(c, inst, dst, 10741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_yyyy(srcreg(RC_FILE_TEMPORARY, tempreg)), 10751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constants); 10761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 10771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 10791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 10811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 10821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void r300_transform_SIN_COS_SCS(struct radeon_compiler *c, 10841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst, 10851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned srctmp) 10861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 10871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode == RC_OPCODE_COS) { 108873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_COS, &inst->U.I, inst->U.I.DstReg, 10891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_TEMPORARY, srctmp, RC_SWIZZLE_WWWW)); 10901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (inst->U.I.Opcode == RC_OPCODE_SIN) { 109173249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_SIN, &inst->U.I, 10921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.DstReg, srcregswz(RC_FILE_TEMPORARY, srctmp, RC_SWIZZLE_WWWW)); 10931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (inst->U.I.Opcode == RC_OPCODE_SCS) { 10941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_dst_register moddst = inst->U.I.DstReg; 10951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 10961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.DstReg.WriteMask & RC_MASK_X) { 10971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák moddst.WriteMask = RC_MASK_X; 109873249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_COS, &inst->U.I, moddst, 10991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_TEMPORARY, srctmp, RC_SWIZZLE_WWWW)); 11001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 11011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.DstReg.WriteMask & RC_MASK_Y) { 11021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák moddst.WriteMask = RC_MASK_Y; 110373249239cf71e3595ee19f3c1a02b8b0f58994cdTom Stellard emit1(c, inst->Prev, RC_OPCODE_SIN, &inst->U.I, moddst, 11041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_TEMPORARY, srctmp, RC_SWIZZLE_WWWW)); 11051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 11061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 11071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_remove_instruction(inst); 11091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 11101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 11131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Transform the trigonometric functions COS, SIN, and SCS 11141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * to include pre-scaling by 1/(2*PI) and taking the fractional 11151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * part, so that the input to COS and SIN is always in the range [0,1). 11161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * SCS is replaced by one COS and one SIN instruction. 11171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 11181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @warning This transformation implicitly changes the semantics of SIN and COS! 11191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 11201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint radeonTransformTrigScale(struct radeon_compiler* c, 11211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst, 11221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void* unused) 11231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 11241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák static const float RCP_2PI = 0.15915494309189535; 11251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int temp; 11261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constant; 11271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constant_swizzle; 11281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode != RC_OPCODE_COS && 11301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SIN && 11311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SCS) 11321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 11331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák temp = rc_find_free_temporary(c); 11351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constant = rc_constants_add_immediate_scalar(&c->Program.Constants, RCP_2PI, &constant_swizzle); 11361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstregtmpmask(temp, RC_MASK_W), 11381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(inst->U.I.SrcReg[0]), 11391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle)); 11401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(temp, RC_MASK_W), 11411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, temp)); 11421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák r300_transform_SIN_COS_SCS(c, inst, temp); 11441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 11451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 11461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 11481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Transform the trigonometric functions COS, SIN, and SCS 11491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * so that the input to COS and SIN is always in the range [-PI, PI]. 11501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * SCS is replaced by one COS and one SIN instruction. 11511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 11521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint r300_transform_trig_scale_vertex(struct radeon_compiler *c, 11531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction *inst, 11541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void *unused) 11551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 11561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák static const float cons[4] = {0.15915494309189535, 0.5, 6.28318530717959, -3.14159265358979}; 11571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int temp; 11581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int constant; 11591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode != RC_OPCODE_COS && 11611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SIN && 11621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode != RC_OPCODE_SCS) 11631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 11641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Repeat x in the range [-PI, PI]: 11661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 11671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * repeat(x) = frac(x / 2PI + 0.5) * 2PI - PI 11681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 11691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák temp = rc_find_free_temporary(c); 11711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák constant = rc_constants_add_immediate_vec4(&c->Program.Constants, cons); 11721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(temp, RC_MASK_W), 11741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák swizzle_xxxx(inst->U.I.SrcReg[0]), 11751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, RC_SWIZZLE_XXXX), 11761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, RC_SWIZZLE_YYYY)); 11771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(temp, RC_MASK_W), 11781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, temp)); 11791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(temp, RC_MASK_W), 11801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcreg(RC_FILE_TEMPORARY, temp), 11811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, RC_SWIZZLE_ZZZZ), 11821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák srcregswz(RC_FILE_CONSTANT, constant, RC_SWIZZLE_WWWW)); 11831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák r300_transform_SIN_COS_SCS(c, inst, temp); 11851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 11861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 11871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 11891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Rewrite DDX/DDY instructions to properly work with r5xx shaders. 11901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The r5xx MDH/MDV instruction provides per-quad partial derivatives. 11911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * It takes the form A*B+C. A and C are set by setting src0. B should be -1. 11921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 11931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @warning This explicitly changes the form of DDX and DDY! 11941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 11951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 11961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákint radeonTransformDeriv(struct radeon_compiler* c, 11971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction* inst, 11981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák void* unused) 11991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 12001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode != RC_OPCODE_DDX && inst->U.I.Opcode != RC_OPCODE_DDY) 12011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 12021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 12031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_1111; 12041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[1].Negate = RC_MASK_XYZW; 12051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 12061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 12071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 12081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 12091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 1210342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * IF Temp[0].x -> IF Temp[0].x 1211342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ... -> ... 1212342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * KILP -> KIL -abs(Temp[0].x) 1213342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ... -> ... 1214342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ENDIF -> ENDIF 1215342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 1216342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * === OR === 1217342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 12181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IF Temp[0].x -\ 12191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * KILP - > KIL -abs(Temp[0].x) 12201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * ENDIF -/ 12211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 1222342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * === OR === 1223342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 1224342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * IF Temp[0].x -> IF Temp[0].x 1225342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ... -> ... 1226342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ELSE -> ELSE 1227342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ... -> ... 1228342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * KILP -> KIL -abs(Temp[0].x) 1229342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ... -> ... 1230342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ENDIF -> ENDIF 1231342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 1232342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * === OR === 1233342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 1234342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * KILP -> KIL -none.1111 1235342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * 1236342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * This needs to be done in its own pass, because it might modify the 1237342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * instructions before and after KILP. 12381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 12391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid rc_transform_KILP(struct radeon_compiler * c, void *user) 12401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 12411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_instruction * inst; 12421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for (inst = c->Program.Instructions.Next; 12431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst != &c->Program.Instructions; inst = inst->Next) { 1244342cac71669662abad3435fd13ecf28d073874c3Tom Stellard struct rc_instruction * if_inst; 1245342cac71669662abad3435fd13ecf28d073874c3Tom Stellard unsigned in_if = 0; 12461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 12471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode != RC_OPCODE_KILP) 12481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 12491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1250342cac71669662abad3435fd13ecf28d073874c3Tom Stellard for (if_inst = inst->Prev; if_inst != &c->Program.Instructions; 1251342cac71669662abad3435fd13ecf28d073874c3Tom Stellard if_inst = if_inst->Prev) { 1252342cac71669662abad3435fd13ecf28d073874c3Tom Stellard 1253342cac71669662abad3435fd13ecf28d073874c3Tom Stellard if (if_inst->U.I.Opcode == RC_OPCODE_IF) { 1254342cac71669662abad3435fd13ecf28d073874c3Tom Stellard in_if = 1; 1255342cac71669662abad3435fd13ecf28d073874c3Tom Stellard break; 1256342cac71669662abad3435fd13ecf28d073874c3Tom Stellard } 1257342cac71669662abad3435fd13ecf28d073874c3Tom Stellard } 1258342cac71669662abad3435fd13ecf28d073874c3Tom Stellard 12591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.Opcode = RC_OPCODE_KIL; 12601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1261342cac71669662abad3435fd13ecf28d073874c3Tom Stellard if (!in_if) { 12621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0] = negate(builtin_one); 12631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 1264342cac71669662abad3435fd13ecf28d073874c3Tom Stellard /* This should work even if the KILP is inside the ELSE 1265342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * block, because -0.0 is considered negative. */ 12661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst->U.I.SrcReg[0] = 1267342cac71669662abad3435fd13ecf28d073874c3Tom Stellard negate(absolute(if_inst->U.I.SrcReg[0])); 1268342cac71669662abad3435fd13ecf28d073874c3Tom Stellard 1269342cac71669662abad3435fd13ecf28d073874c3Tom Stellard if (inst->Prev->U.I.Opcode != RC_OPCODE_IF 1270342cac71669662abad3435fd13ecf28d073874c3Tom Stellard && inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) { 1271342cac71669662abad3435fd13ecf28d073874c3Tom Stellard 1272342cac71669662abad3435fd13ecf28d073874c3Tom Stellard /* Optimize the special case: 1273342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * IF Temp[0].x 1274342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * KILP 1275342cac71669662abad3435fd13ecf28d073874c3Tom Stellard * ENDIF 1276342cac71669662abad3435fd13ecf28d073874c3Tom Stellard */ 1277342cac71669662abad3435fd13ecf28d073874c3Tom Stellard 1278342cac71669662abad3435fd13ecf28d073874c3Tom Stellard /* Remove IF */ 1279342cac71669662abad3435fd13ecf28d073874c3Tom Stellard rc_remove_instruction(inst->Prev); 1280342cac71669662abad3435fd13ecf28d073874c3Tom Stellard /* Remove ENDIF */ 1281342cac71669662abad3435fd13ecf28d073874c3Tom Stellard rc_remove_instruction(inst->Next); 1282342cac71669662abad3435fd13ecf28d073874c3Tom Stellard } 12831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 12841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 12851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1286