aboutsummaryrefslogtreecommitdiff
path: root/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils.h')
-rw-r--r--utils.h19
1 files changed, 14 insertions, 5 deletions
diff --git a/utils.h b/utils.h
index 9b9db2a..e1258c9 100644
--- a/utils.h
+++ b/utils.h
@@ -60,7 +60,17 @@ static unsigned scaleu(unsigned x, unsigned srcmax, unsigned dstmax);
"div bx" /* ax = dx:ax / srcmax */\
__parm [ax] [bx] [cx] \
__value [ax] \
- __modify [ax dx]
+ __modify exact [ax dx]
+
+/** Map x linearly from range [0, srcmax] to [0, 2^dstmax].
+ * Equivalent to above, but uses shift instead of division. */
+static unsigned scaleu_shift(unsigned x, unsigned char srcmax, unsigned dstmax);
+#pragma aux scaleu_shift = \
+ "mul dx" /* dx:ax = x * dstmax */ \
+ "shrd ax, dx, cl" /* ax = dx:ax / 2^srcmax */ \
+ __parm [ax] [cl] [dx] \
+ __value [ax] \
+ __modify exact [ax dx]
/** Map x linearly from range [0, srcmax] to [0, dstmax].
* Equivalent of (x * dstmax) / srcmax but with 32-bit signed precision. */
@@ -70,12 +80,11 @@ static int scalei(int x, int srcmax, int dstmax);
"idiv bx" /* ax = dx:ax / srcmax */ \
__parm [ax] [bx] [cx] \
__value [ax] \
- __modify [ax dx]
+ __modify exact [ax dx]
/** Map x linearly from range [0, srcmax] to [0, dstmax].
- * Equivalent of (x * dstmax) / srcmax but with 32-bit signed precision.
- * Division remainder is returned in rem, which should be reused
- * in future calls to reduce rounding error. */
+ * Equivalent to scalei, but the division remainder is returned in rem,
+ * which can be reused in future calls to reduce rounding error. */
static int scalei_rem(int x, int srcmax, int dstmax, short *rem);
#pragma aux scalei_rem = \
"imul cx" /* dx:ax = x * dstmax */ \