Fix util_endianswap; and endianswap the LNO data as well

This commit is contained in:
Wolfgang Bumiller 2012-12-20 22:03:51 +01:00
parent 8d86d7d1c1
commit 1d3fdea432
4 changed files with 81 additions and 11 deletions

27
code.c
View file

@ -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;

View file

@ -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
View file

@ -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
View file

@ -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,