]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Merge remote-tracking branch 'origin/master' into cooking
authorWolfgang Bumiller <wry.git@bumiller.com>
Mon, 7 Apr 2014 12:23:35 +0000 (14:23 +0200)
committerWolfgang Bumiller <wry.git@bumiller.com>
Mon, 7 Apr 2014 12:23:35 +0000 (14:23 +0200)
code.c
exec.c
fold.c
gmqcc.h
tests/defs.qh
tests/exponentiation.qc
tests/exponentiation.tmpl
util.c

diff --git a/code.c b/code.c
index 540093f74457d77bb342cfc7955e12b0931508e9..ddfbb977f2b1dd6b451d4d4d3becc4426de1dea7 100644 (file)
--- a/code.c
+++ b/code.c
@@ -260,59 +260,18 @@ static void code_create_header(code_t *code, prog_header_t *code_header, const c
     }
 
     /* ensure all data is in LE format */
-    util_endianswap(&code_header->version,              1, sizeof(code_header->version));
-    util_endianswap(&code_header->crc16,                1, sizeof(code_header->crc16));
-    util_endianswap(&code_header->statements.offset,    1, sizeof(code_header->statements.offset));
-    util_endianswap(&code_header->statements.length,    1, sizeof(code_header->statements.length));
-    util_endianswap(&code_header->defs.offset,          1, sizeof(code_header->defs.offset));
-    util_endianswap(&code_header->defs.length,          1, sizeof(code_header->defs.length));
-    util_endianswap(&code_header->fields.offset,        1, sizeof(code_header->fields.offset));
-    util_endianswap(&code_header->fields.length,        1, sizeof(code_header->fields.length));
-    util_endianswap(&code_header->functions.offset,     1, sizeof(code_header->functions.offset));
-    util_endianswap(&code_header->functions.length,     1, sizeof(code_header->functions.length));
-    util_endianswap(&code_header->strings.offset,       1, sizeof(code_header->strings.offset));
-    util_endianswap(&code_header->strings.length,       1, sizeof(code_header->strings.length));
-    util_endianswap(&code_header->globals.offset,       1, sizeof(code_header->globals.offset));
-    util_endianswap(&code_header->globals.length,       1, sizeof(code_header->globals.length));
-    util_endianswap(&code_header->entfield,             1, sizeof(code_header->entfield));
+    util_swap_header(code_header);
 
     /*
      * These are not part of the header but we ensure LE format here to save on duplicated
      * code.
      */
 
-    for (i = 0; i < vec_size(code->statements); ++i) {
-        util_endianswap(&code->statements[i].opcode,    1, sizeof(code->statements[i].opcode));
-        util_endianswap(&code->statements[i].o1,        1, sizeof(code->statements[i].o1));
-        util_endianswap(&code->statements[i].o2,        1, sizeof(code->statements[i].o2));
-        util_endianswap(&code->statements[i].o3,        1, sizeof(code->statements[i].o3));
-    }
-
-    for (i = 0; i < vec_size(code->defs); ++i) {
-        util_endianswap(&code->defs[i].type,   1, sizeof(code->defs[i].type));
-        util_endianswap(&code->defs[i].offset, 1, sizeof(code->defs[i].offset));
-        util_endianswap(&code->defs[i].name,   1, sizeof(code->defs[i].name));
-    }
-
-    for (i = 0; i < vec_size(code->fields); ++i) {
-        util_endianswap(&code->fields[i].type,   1, sizeof(code->fields[i].type));
-        util_endianswap(&code->fields[i].offset, 1, sizeof(code->fields[i].offset));
-        util_endianswap(&code->fields[i].name,   1, sizeof(code->fields[i].name));
-    }
-
-    for (i = 0; i < vec_size(code->functions); ++i) {
-        util_endianswap(&code->functions[i].entry,         1, sizeof(code->functions[i].entry));
-        util_endianswap(&code->functions[i].firstlocal,    1, sizeof(code->functions[i].firstlocal));
-        util_endianswap(&code->functions[i].locals,        1, sizeof(code->functions[i].locals));
-        util_endianswap(&code->functions[i].profile,       1, sizeof(code->functions[i].profile));
-        util_endianswap(&code->functions[i].name,          1, sizeof(code->functions[i].name));
-        util_endianswap(&code->functions[i].file,          1, sizeof(code->functions[i].file));
-        util_endianswap(&code->functions[i].nargs,         1, sizeof(code->functions[i].nargs));
-        /* Don't swap argsize[] - it's just a byte array, which Quake uses only as such. */
-    }
-
-    util_endianswap(code->globals, vec_size(code->globals), sizeof(int32_t));
-
+    util_swap_statements (code->statements);
+    util_swap_defs_fields(code->defs);
+    util_swap_defs_fields(code->fields);
+    util_swap_functions  (code->functions);
+    util_swap_globals    (code->globals);
 
     if (!OPTS_OPTION_BOOL(OPTION_QUIET)) {
         if (lnofile)
diff --git a/exec.c b/exec.c
index d4e75b82e8b580394a8d0300ead3705b1364486f..29a04a3fcc689f8faeabd40264e4876a9ce2acce 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -66,6 +66,8 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
         return NULL;
     }
 
+    util_swap_header(&header);
+
     if (!skipversion && header.version != 6) {
         loaderror("header says this is a version %i progs, we need version 6\n", header.version);
         fs_file_close(file);
@@ -114,6 +116,12 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
     read_data1(strings);
     read_data2(globals, 2); /* reserve more in case a RETURN using with the global at "the end" exists */
 
+    util_swap_statements (prog->code);
+    util_swap_defs_fields(prog->defs);
+    util_swap_defs_fields(prog->fields);
+    util_swap_functions  (prog->functions);
+    util_swap_globals    (prog->globals);
+
     fs_file_close(file);
 
     /* profile counters */
@@ -814,6 +822,16 @@ static int qc_floor(qc_program_t *prog) {
     return 0;
 }
 
+static int qc_pow(qc_program_t *prog) {
+    qcany_t *base, *exp, out;
+    CheckArgs(2);
+    base = GetArg(0);
+    exp = GetArg(1);
+    out._float = powf(base->_float, exp->_float);
+    Return(out);
+    return 0;
+}
+
 static prog_builtin_t qc_builtins[] = {
     NULL,
     &qc_print,       /*   1   */
@@ -829,7 +847,8 @@ static prog_builtin_t qc_builtins[] = {
     &qc_strcmp,      /*   11  */
     &qc_normalize,   /*   12  */
     &qc_sqrt,        /*   13  */
-    &qc_floor        /*   14  */
+    &qc_floor,       /*   14  */
+    &qc_pow          /*   15  */
 };
 
 static const char *arg0 = NULL;
diff --git a/fold.c b/fold.c
index f064f29fa5d599c48dfda5e49342e32aaee3b98b..af37c4c76f652c7e083f02ffa55e7188de0bc5f8 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -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)(floorf(fold_immvalue_float(a) * powf(2.0f, fold_immvalue_float(b))))) & 0xFFFFFF));
+        return fold_constgen_float(fold, (qcfloat_t)floorf(fold_immvalue_float(a) * powf(2.0f, fold_immvalue_float(b))));
     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)(floorf(fold_immvalue_float(a) / powf(2.0f, fold_immvalue_float(b))))) & 0xFFFFFF));
+        return fold_constgen_float(fold, (qcfloat_t)floorf(fold_immvalue_float(a) / powf(2.0f, fold_immvalue_float(b))));
     return NULL;
 }
 
diff --git a/gmqcc.h b/gmqcc.h
index 97f0e4d1774be599c661fe409e18cf1e7522f853..34c0ed8ff60833d5a667f83b68bfd04a3d29f28d 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -627,6 +627,11 @@ enum {
 /* TODO: elide */
 extern const char *util_instr_str[VINSTR_END];
 
+void util_swap_header     (prog_header_t              *code_header);
+void util_swap_statements (prog_section_statement_t   *statements);
+void util_swap_defs_fields(prog_section_both_t        *section);
+void util_swap_functions  (prog_section_function_t    *functions);
+void util_swap_globals    (int32_t                    *globals);
 
 typedef float    qcfloat_t;
 typedef int32_t  qcint_t;
index 772797a13f43a2e2a5330f3d1c1920740e74d582..ed8a5df96b552bd1ded7923e5e994f457f120e35 100644 (file)
@@ -17,3 +17,4 @@ float  (string, string) strcmp    = #11;
 vector (vector)         normalize = #12;
 float  (float)          sqrt      = #13;
 float  (float)          floor     = #14;
+float  (float, float)   pow       = #15;
index 5b8f24e155b776f570202d5d2789ead95ba71bf9..199c4af1acbed7df669f43f85cec813258bd320b 100644 (file)
@@ -1,13 +1,13 @@
-float pow(float x, float y) {
-    return __builtin_pow(x, y);
-}
-
 void main() {
-    float hundy = pow(10, 2); // 10^2 == 100
+    float hundy = __builtin_pow(10, 2); // 10^2 == 100
     print(ftos(hundy), "\n");      // prints: 100
 
+    hundy = pow(10, 2);
+    print(ftos(hundy), "\n");
+
     hundy -= 90; // 100-90 = 10
     print(ftos(hundy ** 2), "\n"); // prints: 100
+    print(ftos(pow(hundy, 2)), "\n"); // prints: 100
 
     hundy = 10.0f;
     print(ftos(__builtin_exp(hundy)), "\n"); // prints: 22026.5
index 0aa7f85525cd06f64b76f5d6ae926060132e6111..8609624f3afa1dc24500ba7e42169fbd683dc99a 100644 (file)
@@ -6,4 +6,6 @@ C: -std=gmqcc
 E: $null
 M: 100
 M: 100
+M: 100
+M: 100
 M: 22026.5
diff --git a/util.c b/util.c
index 030f54fa36e643ab091fbbeb98bb5db1e289df2b..8a0758e8d2efa888cb89921df0ded32040ff27af 100644 (file)
--- a/util.c
+++ b/util.c
@@ -86,6 +86,7 @@ const char *util_instr_str[VINSTR_END] = {
         }
         */
         size_t i;
+        l *= 2;
         for (i = 0; i < l; i += 2) {
             uint32_t v1 = d[i];
             d[i] = d[i+1];
@@ -95,29 +96,29 @@ const char *util_instr_str[VINSTR_END] = {
     }
 #endif
 
-void util_endianswap(void *_data, size_t length, unsigned int typesize) {
+void util_endianswap(void *_data, size_t count, unsigned int typesize) {
 #   if PLATFORM_BYTE_ORDER == -1 /* runtime check */
     if (*((char*)&typesize))
         return;
 #else
-    /* prevent unused warnings */
-    (void) _data;
-    (void) length;
-    (void) typesize;
 
 #   if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_LITTLE
+        /* prevent unused warnings */
+        (void) _data;
+        (void) count;
+        (void) typesize;
         return;
 #   else
         switch (typesize) {
             case 1: return;
             case 2:
-                util_swap16((uint16_t*)_data, length);
+                util_swap16((uint16_t*)_data, count);
                 return;
             case 4:
-                util_swap32((uint32_t*)_data, length);
+                util_swap32((uint32_t*)_data, count);
                 return;
             case 8:
-                util_swap64((uint32_t*)_data, length<<1); /* swap64 operates on 32 bit words, thus scale to that length. */
+                util_swap64((uint32_t*)_data, count);
                 return;
 
             default:
@@ -128,6 +129,64 @@ void util_endianswap(void *_data, size_t length, unsigned int typesize) {
 #endif
 }
 
+void util_swap_header(prog_header_t *code_header) {
+    util_endianswap(&code_header->version,              1, sizeof(code_header->version));
+    util_endianswap(&code_header->crc16,                1, sizeof(code_header->crc16));
+    util_endianswap(&code_header->statements.offset,    1, sizeof(code_header->statements.offset));
+    util_endianswap(&code_header->statements.length,    1, sizeof(code_header->statements.length));
+    util_endianswap(&code_header->defs.offset,          1, sizeof(code_header->defs.offset));
+    util_endianswap(&code_header->defs.length,          1, sizeof(code_header->defs.length));
+    util_endianswap(&code_header->fields.offset,        1, sizeof(code_header->fields.offset));
+    util_endianswap(&code_header->fields.length,        1, sizeof(code_header->fields.length));
+    util_endianswap(&code_header->functions.offset,     1, sizeof(code_header->functions.offset));
+    util_endianswap(&code_header->functions.length,     1, sizeof(code_header->functions.length));
+    util_endianswap(&code_header->strings.offset,       1, sizeof(code_header->strings.offset));
+    util_endianswap(&code_header->strings.length,       1, sizeof(code_header->strings.length));
+    util_endianswap(&code_header->globals.offset,       1, sizeof(code_header->globals.offset));
+    util_endianswap(&code_header->globals.length,       1, sizeof(code_header->globals.length));
+    util_endianswap(&code_header->entfield,             1, sizeof(code_header->entfield));
+}
+
+void util_swap_statements(prog_section_statement_t *statements) {
+    size_t i;
+
+    for (i = 0; i < vec_size(statements); ++i) {
+        util_endianswap(&statements[i].opcode,  1, sizeof(statements[i].opcode));
+        util_endianswap(&statements[i].o1,      1, sizeof(statements[i].o1));
+        util_endianswap(&statements[i].o2,      1, sizeof(statements[i].o2));
+        util_endianswap(&statements[i].o3,      1, sizeof(statements[i].o3));
+    }
+}
+
+void util_swap_defs_fields(prog_section_both_t *section) {
+    size_t i;
+
+    for (i = 0; i < vec_size(section); ++i) {
+        util_endianswap(&section[i].type,   1, sizeof(section[i].type));
+        util_endianswap(&section[i].offset, 1, sizeof(section[i].offset));
+        util_endianswap(&section[i].name,   1, sizeof(section[i].name));
+    }
+}
+
+void util_swap_functions(prog_section_function_t *functions) {
+    size_t i;
+
+    for (i = 0; i < vec_size(functions); ++i) {
+        util_endianswap(&functions[i].entry,        1, sizeof(functions[i].entry));
+        util_endianswap(&functions[i].firstlocal,   1, sizeof(functions[i].firstlocal));
+        util_endianswap(&functions[i].locals,       1, sizeof(functions[i].locals));
+        util_endianswap(&functions[i].profile,      1, sizeof(functions[i].profile));
+        util_endianswap(&functions[i].name,         1, sizeof(functions[i].name));
+        util_endianswap(&functions[i].file,         1, sizeof(functions[i].file));
+        util_endianswap(&functions[i].nargs,        1, sizeof(functions[i].nargs));
+        /* Don't swap argsize[] - it's just a byte array, which Quake uses only as such. */
+    }
+}
+
+void util_swap_globals(int32_t *globals) {
+    util_endianswap(globals, vec_size(globals), sizeof(int32_t));
+}
+
 /*
 * Based On:
 *   Slicing-by-8 algorithms by Michael E.