notaz.gp2x.de
/
ia32rtools.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
96e4884
)
translate: handle arg push for multiple funcs better
author
notaz
<notasas@gmail.com>
Sat, 24 May 2014 17:24:55 +0000
(20:24 +0300)
committer
notaz
<notasas@gmail.com>
Sat, 24 May 2014 17:24:55 +0000
(20:24 +0300)
tools/translate.c
patch
|
blob
|
blame
|
history
diff --git
a/tools/translate.c
b/tools/translate.c
index
2655cec
..
ef29a40
100644
(file)
--- a/
tools/translate.c
+++ b/
tools/translate.c
@@
-156,9
+156,10
@@
struct parsed_op {
unsigned char pfo;
unsigned char pfo_inv;
unsigned char operand_cnt;
unsigned char pfo;
unsigned char pfo_inv;
unsigned char operand_cnt;
- unsigned char p_argnum; // push: altered before call arg #
- unsigned char p_argpass;// push: arg of host func
- unsigned char pad[3];
+ unsigned char p_argnum; // arg push: altered before call arg #
+ unsigned char p_arggrp; // arg push: arg group # for above
+ unsigned char p_argpass;// arg push: arg of host func
+ short p_argnext;// arg push: same arg pushed elsewhere or -1
int regmask_src; // all referensed regs
int regmask_dst;
int pfomask; // flagop: parsed_flag_op that can't be delayed
int regmask_src; // all referensed regs
int regmask_dst;
int pfomask; // flagop: parsed_flag_op that can't be delayed
@@
-210,7
+211,9
@@
enum ida_func_attr {
IDAFA_FPD = (1 << 5),
};
IDAFA_FPD = (1 << 5),
};
-#define MAX_OPS 4096
+// note: limited to 32k due to p_argnext
+#define MAX_OPS 4096
+#define MAX_ARG_GRP 2
static struct parsed_op ops[MAX_OPS];
static struct parsed_equ *g_eqs;
static struct parsed_op ops[MAX_OPS];
static struct parsed_equ *g_eqs;
@@
-2809,12
+2812,15
@@
static int try_resolve_const(int i, const struct parsed_opr *opr,
}
static int collect_call_args_r(struct parsed_op *po, int i,
}
static int collect_call_args_r(struct parsed_op *po, int i,
- struct parsed_proto *pp, int *regmask, int *save_arg_vars,
int arg,
- int magic, int need_op_saving, int may_reuse)
+ struct parsed_proto *pp, int *regmask, int *save_arg_vars,
+ int
*arg_grp, int arg, int
magic, int need_op_saving, int may_reuse)
{
struct parsed_proto *pp_tmp;
{
struct parsed_proto *pp_tmp;
+ struct parsed_op *po_tmp;
struct label_ref *lr;
int need_to_save_current;
struct label_ref *lr;
int need_to_save_current;
+ int arg_grp_current = 0;
+ int save_args_seen = 0;
int save_args;
int ret = 0;
int reg;
int save_args;
int ret = 0;
int reg;
@@
-2853,7
+2859,7
@@
static int collect_call_args_r(struct parsed_op *po, int i,
if ((ops[lr->i].flags & (OPF_JMP|OPF_CJMP)) != OPF_JMP)
may_reuse = 1;
ret = collect_call_args_r(po, lr->i, pp, regmask, save_arg_vars,
if ((ops[lr->i].flags & (OPF_JMP|OPF_CJMP)) != OPF_JMP)
may_reuse = 1;
ret = collect_call_args_r(po, lr->i, pp, regmask, save_arg_vars,
- arg, magic, need_op_saving, may_reuse);
+ arg
_grp, arg
, magic, need_op_saving, may_reuse);
if (ret < 0)
return ret;
}
if (ret < 0)
return ret;
}
@@
-2868,7
+2874,7
@@
static int collect_call_args_r(struct parsed_op *po, int i,
}
need_op_saving = 1;
ret = collect_call_args_r(po, lr->i, pp, regmask, save_arg_vars,
}
need_op_saving = 1;
ret = collect_call_args_r(po, lr->i, pp, regmask, save_arg_vars,
- arg, magic, need_op_saving, may_reuse);
+ arg
_grp, arg
, magic, need_op_saving, may_reuse);
if (ret < 0)
return ret;
}
if (ret < 0)
return ret;
}
@@
-2916,7
+2922,12
@@
static int collect_call_args_r(struct parsed_op *po, int i,
if (pp->is_unresolved && (ops[j].flags & OPF_RMD))
break;
if (pp->is_unresolved && (ops[j].flags & OPF_RMD))
break;
+ ops[j].p_argnext = -1;
+ po_tmp = pp->arg[arg].datap;
+ if (po_tmp != NULL)
+ ops[j].p_argnext = po_tmp - ops;
pp->arg[arg].datap = &ops[j];
pp->arg[arg].datap = &ops[j];
+
need_to_save_current = 0;
save_args = 0;
reg = -1;
need_to_save_current = 0;
save_args = 0;
reg = -1;
@@
-2940,6
+2951,14
@@
static int collect_call_args_r(struct parsed_op *po, int i,
ops[j].p_argnum = arg + 1;
save_args |= 1 << arg;
}
ops[j].p_argnum = arg + 1;
save_args |= 1 << arg;
}
+
+ if (save_args_seen & (1 << (ops[j].p_argnum - 1))) {
+ save_args_seen = 0;
+ arg_grp_current++;
+ if (arg_grp_current >= MAX_ARG_GRP)
+ ferr(&ops[j], "out of arg groups (arg%d), f %s\n",
+ ops[j].p_argnum, pp->name);
+ }
}
else if (ops[j].p_argnum == 0)
ops[j].flags |= OPF_RMD;
}
else if (ops[j].p_argnum == 0)
ops[j].flags |= OPF_RMD;
@@
-3005,6
+3024,13
@@
static int collect_call_args_r(struct parsed_op *po, int i,
}
magic = (magic & 0xffffff) | (arg << 24);
}
}
magic = (magic & 0xffffff) | (arg << 24);
}
+
+ if (ops[j].p_arggrp > arg_grp_current) {
+ save_args_seen = 0;
+ arg_grp_current = ops[j].p_arggrp;
+ }
+ if (ops[j].p_argnum > 0)
+ save_args_seen |= 1 << (ops[j].p_argnum - 1);
}
if (arg < pp->argc) {
}
if (arg < pp->argc) {
@@
-3013,6
+3039,9
@@
static int collect_call_args_r(struct parsed_op *po, int i,
return -1;
}
return -1;
}
+ if (arg_grp_current > *arg_grp)
+ *arg_grp = arg_grp_current;
+
return arg;
}
return arg;
}
@@
-3020,14
+3049,37
@@
static int collect_call_args(struct parsed_op *po, int i,
struct parsed_proto *pp, int *regmask, int *save_arg_vars,
int magic)
{
struct parsed_proto *pp, int *regmask, int *save_arg_vars,
int magic)
{
+ // arg group is for cases when pushes for
+ // multiple funcs are going on
+ struct parsed_op *po_tmp;
+ int save_arg_vars_current = 0;
+ int arg_grp = 0;
int ret;
int a;
int ret;
int a;
- ret = collect_call_args_r(po, i, pp, regmask,
save_arg_vars,
- 0, magic, 0, 0);
+ ret = collect_call_args_r(po, i, pp, regmask,
+
&save_arg_vars_current, &arg_grp,
0, magic, 0, 0);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
+ if (arg_grp != 0) {
+ // propagate arg_grp
+ for (a = 0; a < pp->argc; a++) {
+ if (pp->arg[a].reg != NULL)
+ continue;
+
+ po_tmp = pp->arg[a].datap;
+ while (po_tmp != NULL) {
+ po_tmp->p_arggrp = arg_grp;
+ if (po_tmp->p_argnext > 0)
+ po_tmp = &ops[po_tmp->p_argnext];
+ else
+ po_tmp = NULL;
+ }
+ }
+ }
+ save_arg_vars[arg_grp] |= save_arg_vars_current;
+
if (pp->is_unresolved) {
pp->argc += ret;
pp->argc_stack += ret;
if (pp->is_unresolved) {
pp->argc += ret;
pp->argc_stack += ret;
@@
-3156,6
+3208,18
@@
static void output_pp_attrs(FILE *fout, const struct parsed_proto *pp,
fprintf(fout, "noreturn ");
}
fprintf(fout, "noreturn ");
}
+static char *saved_arg_name(char *buf, size_t buf_size, int grp, int num)
+{
+ char buf1[16];
+
+ buf1[0] = 0;
+ if (grp > 0)
+ snprintf(buf1, sizeof(buf1), "%d", grp);
+ snprintf(buf, buf_size, "s%s_a%d", buf1, num);
+
+ return buf;
+}
+
static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt)
{
struct parsed_op *po, *delayed_flag_op = NULL, *tmp_op;
static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt)
{
struct parsed_op *po, *delayed_flag_op = NULL, *tmp_op;
@@
-3166,7
+3230,7
@@
static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt)
struct parsed_data *pd;
const char *tmpname;
unsigned int uval;
struct parsed_data *pd;
const char *tmpname;
unsigned int uval;
- int save_arg_vars
= 0
;
+ int save_arg_vars
[MAX_ARG_GRP] = { 0, }
;
int cond_vars = 0;
int need_tmp_var = 0;
int need_tmp64 = 0;
int cond_vars = 0;
int need_tmp_var = 0;
int need_tmp64 = 0;
@@
-3557,7
+3621,7
@@
tailcall:
if (!pp->is_unresolved && !(po->flags & OPF_ATAIL)) {
// since we know the args, collect them
if (!pp->is_unresolved && !(po->flags & OPF_ATAIL)) {
// since we know the args, collect them
- collect_call_args(po, i, pp, ®mask,
&
save_arg_vars,
+ collect_call_args(po, i, pp, ®mask, save_arg_vars,
i + opcnt * 2);
}
i + opcnt * 2);
}
@@
-3731,7
+3795,7
@@
tailcall:
if (pp->is_unresolved) {
int regmask_stack = 0;
if (pp->is_unresolved) {
int regmask_stack = 0;
- collect_call_args(po, i, pp, ®mask,
&
save_arg_vars,
+ collect_call_args(po, i, pp, ®mask, save_arg_vars,
i + opcnt * 2);
// this is pretty rough guess:
i + opcnt * 2);
// this is pretty rough guess:
@@
-4040,10
+4104,13
@@
tailcall:
}
}
}
}
- if (save_arg_vars) {
+ for (i = 0; i < ARRAY_SIZE(save_arg_vars); i++) {
+ if (save_arg_vars[i] == 0)
+ continue;
for (reg = 0; reg < 32; reg++) {
for (reg = 0; reg < 32; reg++) {
- if (save_arg_vars & (1 << reg)) {
- fprintf(fout, " u32 s_a%d;\n", reg + 1);
+ if (save_arg_vars[i] & (1 << reg)) {
+ fprintf(fout, " u32 %s;\n",
+ saved_arg_name(buf1, sizeof(buf1), i, reg + 1));
had_decl = 1;
}
}
had_decl = 1;
}
}
@@
-4887,7
+4954,9
@@
tailcall:
fprintf(fout, "a%d", tmp_op->p_argpass);
}
else if (tmp_op->p_argnum != 0) {
fprintf(fout, "a%d", tmp_op->p_argpass);
}
else if (tmp_op->p_argnum != 0) {
- fprintf(fout, "%ss_a%d", cast, tmp_op->p_argnum);
+ fprintf(fout, "%s%s", cast,
+ saved_arg_name(buf1, sizeof(buf1),
+ tmp_op->p_arggrp, tmp_op->p_argnum));
}
else {
fprintf(fout, "%s",
}
else {
fprintf(fout, "%s",
@@
-4977,7
+5046,9
@@
tailcall:
out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
if (po->p_argnum != 0) {
// special case - saved func arg
out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
if (po->p_argnum != 0) {
// special case - saved func arg
- fprintf(fout, " s_a%d = %s;", po->p_argnum, buf1);
+ fprintf(fout, " %s = %s;",
+ saved_arg_name(buf2, sizeof(buf2),
+ po->p_arggrp, po->p_argnum), buf1);
break;
}
else if (po->flags & OPF_RSAVE) {
break;
}
else if (po->flags & OPF_RSAVE) {