summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_opcodes.py
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2016-03-25 11:13:40 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2016-04-13 15:44:00 -0700
commit745b3d295e0c432b95d43f979c74f9e91baaf6de (patch)
tree00f4c8721eb876bde18f860ebf64c493c59b40a6 /src/compiler/nir/nir_opcodes.py
parentd880c6f9f59dac7cfe33713fff1c09c63ab7fb4f (diff)
downloadexternal_mesa3d-745b3d295e0c432b95d43f979c74f9e91baaf6de.zip
external_mesa3d-745b3d295e0c432b95d43f979c74f9e91baaf6de.tar.gz
external_mesa3d-745b3d295e0c432b95d43f979c74f9e91baaf6de.tar.bz2
nir: Add more modulus opcodes
These are all needed for SPIR-V Reviewed-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'src/compiler/nir/nir_opcodes.py')
-rw-r--r--src/compiler/nir/nir_opcodes.py16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index 9f62e08..e75ca28 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -443,9 +443,23 @@ binop_convert("uadd_carry", tuint, tuint, commutative, "src0 + src1 < src0")
binop_convert("usub_borrow", tuint, tuint, "", "src0 < src1")
-binop("fmod", tfloat, "", "src0 - src1 * floorf(src0 / src1)")
binop("umod", tuint, "", "src1 == 0 ? 0 : src0 % src1")
+# For signed integers, there are several different possible definitions of
+# "modulus" or "remainder". We follow the conventions used by LLVM and
+# SPIR-V. The irem opcode implements the standard C/C++ signed "%"
+# operation while the imod opcode implements the more mathematical
+# "modulus" operation. For details on the difference, see
+#
+# http://mathforum.org/library/drmath/view/52343.html
+
+binop("irem", tint, "", "src1 == 0 ? 0 : src0 % src1")
+binop("imod", tint, "",
+ "src1 == 0 ? 0 : ((src0 % src1 == 0 || (src0 >= 0) == (src1 >= 0)) ?"
+ " src0 % src1 : src0 % src1 + src1)")
+binop("fmod", tfloat, "", "src0 - src1 * floorf(src0 / src1)")
+binop("frem", tfloat, "", "src0 - src1 * truncf(src0 / src1)")
+
#
# Comparisons
#