]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - fold.c
Fix lshift/rshift for runtime and const-fold consistency.
[xonotic/gmqcc.git] / fold.c
diff --git a/fold.c b/fold.c
index 84b01c772e707c2b8e86fc5633b99120e0c678a4..173d613abda50068ee7410df74c305e2e76ada38 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014
  *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
@@ -550,13 +550,13 @@ static GMQCC_INLINE ast_expression *fold_op_xor(fold_t *fold, ast_value *a, ast_
 
 static GMQCC_INLINE ast_expression *fold_op_lshift(fold_t *fold, ast_value *a, ast_value *b) {
     if (fold_can_2(a, b) && isfloats(a, b))
-        return fold_constgen_float(fold, (qcfloat_t)((qcuint_t)(fold_immvalue_float(a)) << (qcuint_t)(fold_immvalue_float(b))));
+        return fold_constgen_float(fold, (qcfloat_t)(((qcuint_t)floorf(fold_immvalue_float(a) * powf(2, fold_immvalue_float(b)))) & 0xFFFFFF));
     return NULL;
 }
 
 static GMQCC_INLINE ast_expression *fold_op_rshift(fold_t *fold, ast_value *a, ast_value *b) {
     if (fold_can_2(a, b) && isfloats(a, b))
-        return fold_constgen_float(fold, (qcfloat_t)((qcuint_t)(fold_immvalue_float(a)) >> (qcuint_t)(fold_immvalue_float(b))));
+        return fold_constgen_float(fold, (qcfloat_t)(((qcuint_t)floorf(fold_immvalue_float(a) / powf(2, fold_immvalue_float(b)))) & 0xFFFFFF));
     return NULL;
 }
 
@@ -609,11 +609,11 @@ static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_
         if (isfloat(a) && isfloat(b)) {
             float la = fold_immvalue_float(a);
             float lb = fold_immvalue_float(b);
-            return (ast_expression*)fold->imm_float[!!(ne ? la != lb : la == lb)];
+            return (ast_expression*)fold->imm_float[!(ne ? la == lb : la != lb)];
         } if (isvector(a) && isvector(b)) {
             vec3_t la = fold_immvalue_vector(a);
             vec3_t lb = fold_immvalue_vector(b);
-            return (ast_expression*)fold->imm_float[!!(ne ? vec3_cmp(la, lb) : !vec3_cmp(la, lb))];
+            return (ast_expression*)fold->imm_float[!(ne ? vec3_cmp(la, lb) : !vec3_cmp(la, lb))];
         }
     }
     return NULL;