X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Fcvt_data.c;h=237abef7c11dc2246f334ee353e6f8dfdd7562c8;hb=179b79a987ed0f464f47f724032aff6c90bc50c0;hp=9fb6eb9da0618bf9f621b6d70ee28a37945cacfe;hpb=c87eb4703a05444f446dabe74b61eb55db55eae8;p=ia32rtools.git diff --git a/tools/cvt_data.c b/tools/cvt_data.c index 9fb6eb9..237abef 100644 --- a/tools/cvt_data.c +++ b/tools/cvt_data.c @@ -1,3 +1,11 @@ +/* + * ia32rtools + * (C) notaz, 2013,2014 + * + * This work is licensed under the terms of 3-clause BSD license. + * See COPYING file in the top-level directory. + */ + #define _GNU_SOURCE #include #include @@ -19,6 +27,7 @@ static const struct parsed_proto *g_func_sym_pp; static char g_comment[256]; static int g_warn_cnt; static int g_cconv_novalidate; +static int g_arm_mode; // note: must be in ascending order enum dx_type { @@ -137,7 +146,7 @@ static const char *type_name(enum dx_type type) case DXT_BYTE: return ".byte"; case DXT_WORD: - return ".word"; + return ".hword"; case DXT_DWORD: return ".long"; case DXT_QUAD: @@ -238,8 +247,8 @@ static const struct parsed_proto *check_var(FILE *fhdr, const char *sym, const char *varname) { const struct parsed_proto *pp, *pp_sym; - char fp_sym[256], fp_var[256]; - int i, bad = 0; + char fp_sym[256], fp_var[256], *p; + int i; pp = proto_parse(fhdr, varname, 1); if (pp == NULL) { @@ -269,6 +278,20 @@ static const struct parsed_proto *check_var(FILE *fhdr, } check_sym: + // fptrs must use 32bit args, callsite might have no information and + // lack a cast to smaller types, which results in incorrectly masked + // args passed (callee may assume masked args, it does on ARM) + for (i = 0; i < pp->argc; i++) { + if (pp->arg[i].type.is_ptr) + continue; + p = pp->arg[i].type.name; + if (strstr(p, "int8") || strstr(p, "int16") + || strstr(p, "char") || strstr(p, "short")) + { + awarn("reference to %s with arg%d '%s'\n", pp->name, i + 1, p); + } + } + sprint_pp_short(pp, g_comment, sizeof(g_comment)); if (sym != NULL) { @@ -286,24 +309,7 @@ check_sym: return pp; } - if (pp->argc != pp_sym->argc || pp->argc_reg != pp_sym->argc_reg) - bad = 1; - else { - for (i = 0; i < pp->argc; i++) { - if ((pp->arg[i].reg != NULL) != (pp_sym->arg[i].reg != NULL)) { - bad = 1; - break; - } - if ((pp->arg[i].reg != NULL) - && !IS(pp->arg[i].reg, pp_sym->arg[i].reg)) - { - bad = 1; - break; - } - } - } - - if (bad) { + if (pp_cmp_func(pp, pp_sym)) { pp_print(fp_sym, sizeof(fp_sym), pp_sym); anote("var: %s\n", fp_var); anote("sym: %s\n", fp_sym); @@ -323,6 +329,18 @@ static void output_decorated_pp(FILE *fout, fprintf(fout, "@%d", pp->argc * 4); } +static int align_value(int src_val) +{ + if (src_val <= 0) { + awarn("bad align: %d\n", src_val); + src_val = 1; + } + if (!g_arm_mode) + return src_val; + + return __builtin_ffs(src_val) - 1; +} + static int cmpstringp(const void *p1, const void *p2) { return strcmp(*(char * const *)p1, *(char * const *)p2); @@ -366,6 +384,7 @@ int main(int argc, char *argv[]) FILE *fout, *fasm, *fhdr, *frlist; const struct parsed_proto *pp; int no_decorations = 0; + char comment_char = '#'; char words[20][256]; char word[256]; char line[256]; @@ -393,7 +412,7 @@ int main(int argc, char *argv[]) if (argc < 4) { // -nd: no symbol decorations - printf("usage:\n%s [-nd] [-i] <.s> <.asm> [rlist]*\n", + printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> [rlist]*\n", argv[0]); return 1; } @@ -403,6 +422,10 @@ int main(int argc, char *argv[]) no_decorations = 1; else if (IS(argv[arg], "-i")) g_cconv_novalidate = 1; + else if (IS(argv[arg], "-a")) { + comment_char = '@'; + g_arm_mode = 1; + } else break; } @@ -475,7 +498,7 @@ int main(int argc, char *argv[]) else aerr("unhandled section: '%s'\n", line); - fprintf(fout, ".align 4\n"); + fprintf(fout, ".align %d\n", align_value(4)); while (fgets(line, sizeof(line), fasm)) { @@ -483,9 +506,19 @@ int main(int argc, char *argv[]) asmln++; p = sskip(line); - if (*p == 0 || *p == ';') + if (*p == 0) continue; + if (*p == ';') { + if (IS_START(p, ";org") && sscanf(p + 5, "%Xh", &i) == 1) { + // ;org is only seen at section start, so assume . addr 0 + i &= 0xfff; + if (i != 0) + fprintf(fout, "\t\t .skip 0x%x\n", i); + } + continue; + } + for (wordc = 0; wordc < ARRAY_SIZE(words); wordc++) { p = sskip(next_word_s(words[wordc], sizeof(words[0]), p)); if (*p == 0 || *p == ';') { @@ -516,7 +549,7 @@ int main(int argc, char *argv[]) if (IS(words[0], "align")) { val = parse_number(words[1]); - fprintf(fout, "\t\t .align %ld", val); + fprintf(fout, "\t\t .align %d", align_value(val)); goto fin; } @@ -653,7 +686,13 @@ int main(int argc, char *argv[]) if (w != wordc - 1) aerr("TODO\n"); - fprintf(fout, "%s %s", type_name_float(type), words[w]); + if (g_arm_mode && type == DXT_TEN) { + fprintf(fout, ".fill 10"); + snprintf(g_comment, sizeof(g_comment), "%s %s", + type_name_float(type), words[w]); + } + else + fprintf(fout, "%s %s", type_name_float(type), words[w]); goto fin; } @@ -719,7 +758,7 @@ int main(int argc, char *argv[]) fin: if (g_comment[0] != 0) { - fprintf(fout, "\t\t# %s", g_comment); + fprintf(fout, "\t\t%c %s", comment_char, g_comment); g_comment[0] = 0; } fprintf(fout, "\n");