From 1d3fdea432b5bb4992ecd0d16ddd05a2174131f4 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 20 Dec 2012 22:03:51 +0100 Subject: [PATCH] Fix util_endianswap; and endianswap the LNO data as well --- code.c | 27 ++++++++++++++++++-------- gmqcc.h | 2 +- ir.c | 4 ++-- util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/code.c b/code.c index 0f8fc40..42a5595 100644 --- a/code.c +++ b/code.c @@ -134,6 +134,22 @@ bool code_write(const char *filename, const char *lnofile) { vec_push(code_chars, '\0'); /* P */ } + /* 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, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.defs, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.fields, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.functions, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.strings, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.globals, 2, sizeof(code_header.statements.offset)); + util_endianswap(&code_header.entfield, 1, sizeof(code_header.entfield)); + util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement)); + util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def)); + util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field)); + util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function)); + util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t)); + if (lnofile) { uint32_t lnotype = *(unsigned int*)"LNOF"; uint32_t version = 1; @@ -142,6 +158,9 @@ bool code_write(const char *filename, const char *lnofile) { if (!fp) return false; + util_endianswap(&version, 1, sizeof(version)); + util_endianswap(code_linenums, vec_size(code_linenums), sizeof(code_linenums[0])); + if (fwrite(&lnotype, sizeof(lnotype), 1, fp) != 1 || fwrite(&version, sizeof(version), 1, fp) != 1 || fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 || @@ -157,14 +176,6 @@ bool code_write(const char *filename, const char *lnofile) { fp = NULL; } - /* ensure all data is in LE format */ - util_endianswap(&code_header, 1, sizeof(prog_header)); - util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement)); - util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def)); - util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field)); - util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function)); - util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t)); - fp = util_fopen(filename, "wb"); if (!fp) return false; diff --git a/gmqcc.h b/gmqcc.h index af3d2c1..1adcd52 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -160,7 +160,7 @@ char *util_strsws (const char *); char *util_strchp (const char *, const char *); void util_debug (const char *, const char *, ...); int util_getline (char **, size_t *, FILE *); -void util_endianswap (void *, int, int); +void util_endianswap (void *, size_t, unsigned int); size_t util_strtocmd (const char *, char *, size_t); size_t util_strtononcmd (const char *, char *, size_t); diff --git a/ir.c b/ir.c index 2c65ad1..18b6387 100644 --- a/ir.c +++ b/ir.c @@ -1586,12 +1586,10 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0)); if (!in) return NULL; - /* if (noreturn) { self->final = true; self->is_return = true; } - */ out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype); if (!out) { ir_instr_delete(in); @@ -1605,6 +1603,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i return NULL; } vec_push(self->instr, in); + /* if (noreturn) { if (!ir_block_create_return(self, ctx, NULL)) { compile_error(ctx, "internal error: failed to generate dummy-return instruction"); @@ -1612,6 +1611,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i return NULL; } } + */ return in; } diff --git a/util.c b/util.c index aac66aa..03cf40e 100644 --- a/util.c +++ b/util.c @@ -263,6 +263,7 @@ void util_debug(const char *area, const char *ms, ...) { * reorders by stride and length, much nicer than other functions for * certian-sized types like short or int. */ +#if 0 void util_endianswap(void *m, int s, int l) { size_t w = 0; size_t i = 0; @@ -280,6 +281,64 @@ void util_endianswap(void *m, int s, int l) { } } } +#endif + +static void util_swap16(uint16_t *d, size_t l) { + while (l--) { + d[l] = (d[l] << 8) | (d[l] >> 8); + } +} + +static void util_swap32(uint32_t *d, size_t l) { + while (l--) { + uint32_t v; + v = ((d[l] << 8) & 0xFF00FF00) | ((d[l] >> 8) & 0x00FF00FF); + d[l] = (v << 16) | (v >> 16); + } +} + +/* Some strange system doesn't like constants that big, AND doesn't recognize an ULL suffix + * so let's go the safe way + */ +static void util_swap64(uint32_t *d, size_t l) { + /* + while (l--) { + uint64_t v; + v = ((d[l] << 8) & 0xFF00FF00FF00FF00) | ((d[l] >> 8) & 0x00FF00FF00FF00FF); + v = ((v << 16) & 0xFFFF0000FFFF0000) | ((v >> 16) & 0x0000FFFF0000FFFF); + d[l] = (v << 32) | (v >> 32); + } + */ + size_t i; + for (i = 0; i < l; i += 2) { + uint32_t v1 = d[i]; + d[i] = d[i+1]; + d[i+1] = v1; + util_swap32(d+i, 2); + } +} + +void util_endianswap(void *_data, size_t length, unsigned int typesize) { + /* I'm guessing there's no GOOD way to do this at compile time: + * FIXME: + */ + if (*((char*)&typesize)) + return; + if (typesize == 1) + return; + if (typesize == 2) { + util_swap16((uint16_t*)_data, length>>1); + return; + } + if (typesize == 4) { + util_swap32((uint32_t*)_data, length>>2); + return; + } + if (typesize == 4) { + util_swap64((uint32_t*)_data, length>>3); + return; + } +} /* * CRC algorithms vary in the width of the polynomial, the value of said polynomial, -- 2.39.2