mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 18:51:24 +00:00
Fix util_endianswap; and endianswap the LNO data as well
This commit is contained in:
parent
8d86d7d1c1
commit
1d3fdea432
4 changed files with 81 additions and 11 deletions
27
code.c
27
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;
|
||||
|
|
2
gmqcc.h
2
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);
|
||||
|
|
4
ir.c
4
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;
|
||||
}
|
||||
|
||||
|
|
59
util.c
59
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,
|
||||
|
|
Loading…
Reference in a new issue