X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=util.c;h=4adcb4a9d13132d381c862b59be52ca668263176;hp=ba7db5ff510a496e2fefe71976cc9bcc147f0803;hb=893f204b30affbb4407fcddb16576156a648eac6;hpb=3070c03fc0df299df630d5bbaddc3b767b0a1566 diff --git a/util.c b/util.c index ba7db5f..4adcb4a 100644 --- a/util.c +++ b/util.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013, 2014 + * Copyright (C) 2012, 2013, 2014, 2015 * Dale Weiler * Wolfgang Bumiller * @@ -58,7 +58,7 @@ const char *util_instr_str[VINSTR_END] = { * only required if big endian .. otherwise no need to swap * data. */ -#if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG +#if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG || PLATFORM_BYTE_ORDER == -1 static GMQCC_INLINE void util_swap16(uint16_t *d, size_t l) { while (l--) { d[l] = (d[l] << 8) | (d[l] >> 8); @@ -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,41 +96,95 @@ const char *util_instr_str[VINSTR_END] = { } #endif -void util_tolittleendianarray(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: - con_err ("util_tolittleendianarray: I don't know how to swap a %d byte structure!\n", typesize); + con_err ("util_endianswap: I don't know how to swap a %u byte structure!\n", typesize); exit(EXIT_FAILURE); /* please blow the fuck up! */ } # endif #endif } -void util_tolittleendian(void *_data, unsigned int typesize) { - util_tolittleendianarray(_data, 1, typesize); +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(§ion[i].type, 1, sizeof(section[i].type)); + util_endianswap(§ion[i].offset, 1, sizeof(section[i].offset)); + util_endianswap(§ion[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)); } /*