diff options
author | Jason Ekstrand <[email protected]> | 2016-01-13 15:05:39 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-01-13 15:18:36 -0800 |
commit | cac99fffdb87a42ab4a2a75747d11afca9a57bf7 (patch) | |
tree | ca85d127f41467d58e11597f2ca28543ce295bc9 /src/glsl/nir/nir_opcodes.py | |
parent | 0079523a0d42538020ba89add961f09507e41949 (diff) |
nir: Add more modulus and remainder opcodes
SPIR-V makes a distinction between "modulus" and "remainder" for both
floating-point and signed integer variants. The difference is primarily
one of which source they take their sign from. The "remainder" opcode for
integers is equivalent to the C/C++ "%" operation while the "modulus"
opcode is more mathematically correct (at least for an unsigned divisor).
This commit adds corresponding opcodes to NIR.
Diffstat (limited to 'src/glsl/nir/nir_opcodes.py')
-rw-r--r-- | src/glsl/nir/nir_opcodes.py | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/glsl/nir/nir_opcodes.py b/src/glsl/nir/nir_opcodes.py index 9dbb341d91c..d4f400d020d 100644 --- a/src/glsl/nir/nir_opcodes.py +++ b/src/glsl/nir/nir_opcodes.py @@ -369,9 +369,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 # |