aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-17 10:43:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:06:10 -0700
commit23ae0366c41a5656f60d49ace2091a3f2c7e7b7e (patch)
tree888e39211dff662424ab6fe6ee0e9918fbacd82b /example.c
parentToplevel symbols are externally addressable only if they (diff)
downloadsparse-23ae0366c41a5656f60d49ace2091a3f2c7e7b7e.tar.gz
sparse-23ae0366c41a5656f60d49ace2091a3f2c7e7b7e.tar.bz2
sparse-23ae0366c41a5656f60d49ace2091a3f2c7e7b7e.zip
Make the argument storage setup be a bit more accurate.
Take argument type into account (somewhat), and do a first (broken, but it's a good example) cut at having different calling conventions for different kinds of functions.
Diffstat (limited to 'example.c')
-rw-r--r--example.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/example.c b/example.c
index e6bd7d0..39ffe90 100644
--- a/example.c
+++ b/example.c
@@ -12,6 +12,7 @@
#include "linearize.h"
#include "flow.h"
#include "storage.h"
+#include "target.h"
static const char* opcodes[] = {
[OP_BADOP] = "bad_op",
@@ -1712,33 +1713,55 @@ static void output_bb(struct basic_block *bb, unsigned long generation)
generate_list(bb->children, generation);
}
+/*
+ * We should set up argument sources here..
+ *
+ * Things like "first three arguments in registers" etc
+ * are all for this place.
+ *
+ * On x86, we default to stack, unless it's a static
+ * function that doesn't have its address taken.
+ *
+ * I should implement the -mregparm=X cmd line option.
+ */
static void set_up_arch_entry(struct entrypoint *ep, struct instruction *entry)
{
- int i;
pseudo_t arg;
-
- /*
- * We should set up argument sources here..
- *
- * Things like "first three arguments in registers" etc
- * are all for this place.
- */
+ struct symbol *sym, *argtype;
+ int i, offset, regparm;
+
+ sym = ep->name;
+ regparm = 0;
+ if (!(sym->ctype.modifiers & MOD_ADDRESSABLE))
+ regparm = 3;
+ sym = sym->ctype.base_type;
i = 0;
+ offset = 0;
+ PREPARE_PTR_LIST(sym->arguments, argtype);
FOR_EACH_PTR(entry->arg_list, arg) {
struct storage *in = lookup_storage(entry->bb, arg, STOR_IN);
if (!in) {
in = alloc_storage();
add_storage(in, entry->bb, arg, STOR_IN);
}
- if (i < 3) {
+ if (i < regparm) {
in->type = REG_REG;
in->regno = i;
} else {
+ int bits = argtype ? argtype->bit_size : 0;
+
+ if (bits < bits_in_int)
+ bits = bits_in_int;
+
in->type = REG_FRAME;
- in->offset = (i-3)*4;
+ in->offset = offset;
+
+ offset += bits >> 3;
}
i++;
+ NEXT_PTR_LIST(argtype);
} END_FOR_EACH_PTR(arg);
+ FINISH_PTR_LIST(argtype);
}
/*