diff options
author | Søren Sandmann <ssp@redhat.com> | 2013-12-22 11:44:48 -0500 |
---|---|---|
committer | Søren Sandmann <ssp@redhat.com> | 2013-12-22 11:44:48 -0500 |
commit | 4dadd937f66bf8a91ebff16fc40afa8505c88007 (patch) | |
tree | ac66b72ff70d11d8e3ae05094f308ed0ea95f28d | |
parent | 181eef863b38bba050225b15e057f18845edccdf (diff) |
More reggroups
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | iterjit.c | 32 | ||||
-rw-r--r-- | reggroups.c | 86 | ||||
-rw-r--r-- | reggroups.h | 2 |
4 files changed, 89 insertions, 38 deletions
@@ -6,7 +6,6 @@ COMMON = $(COMMON_SOURCES) $(COMMON_HEADERS) COMMON_SOURCES = \ simplex86.c \ code-manager.c \ - simple-reg.c \ array.c \ stack-man.c \ crc32.c @@ -22,16 +21,16 @@ COMMON_HEADERS = \ all: genrender blitter testsuite iterjit genrender: $(COMMON) main.c - $(CC) $(CFLAGS) -o genrender $(COMMON_SOURCES) main.c $(LDFLAGS) + $(CC) $(CFLAGS) -o genrender $(COMMON_SOURCES) main.c simple-reg.c $(LDFLAGS) blitter: $(COMMON) blitter.c - $(CC) $(CFLAGS) -o blitter $(COMMON_SOURCES) blitter.c $(LDFLAGS) + $(CC) $(CFLAGS) -o blitter $(COMMON_SOURCES) blitter.c simple-reg.c $(LDFLAGS) testsuite: $(COMMON) testsuite.c $(CC) $(CFLAGS) -o testsuite $(COMMON_SOURCES) testsuite.c $(LDFLAGS) iterjit: $(COMMON) iterjit.c - $(CC) $(CFLAGS) -o iterjit $(COMMON_SOURCES) iterjit.c $(LDFLAGS) + $(CC) $(CFLAGS) -o iterjit $(COMMON_SOURCES) iterjit.c reggroups.c $(LDFLAGS) clean: rm -f genrender blitter testsuite iterjit @@ -247,20 +247,50 @@ struct jit_dest_iter_t #define MEMBER(variable, type, member) \ BASE((variable), offsetof (type, member)) +static const reg_pool_t xmm_pool = +{ + 16 /* n_registers */, 16 /* register size */, + { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, + }, +}; + +static const reg_pool_t gp64_pool = +{ + 14 /* n_registers */, 8 /* register size */, + { rax, rbx, rcx, rdx, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + } +}; + jit_t * jit_new (void) { jit_t *jit = malloc (sizeof (jit_t)); + jit->assembler = assembler_new ("pixman"); + jit->fragment = fragment_new (jit->assembler); + + stack_manager_init (&jit->stack_man); + + reg_alloc_init (&jit->xmm_allocator, &jit->stack_man, &xmm_pool); + reg_alloc_init (&jit->gp_allocator, &jit->stack_man, &gp64_pool); + return jit; } void jit_switch_group (jit_t *jit, const char *group) { + +} + +reg_t +jit_alloc_gp (jit_t *jit) +{ + return reg_alloc_alloc (&jit->gp_allocator); } -reg_t jit_alloc_gp (jit_t *jit); reg_t jit_alloc_xmm (jit_t *jit); void jit_preserve_gp (jit_t *jit, reg_t reg); void jit_free_gp (jit_t *jit, reg_t reg); diff --git a/reggroups.c b/reggroups.c index 9e4592a..bc85ada 100644 --- a/reggroups.c +++ b/reggroups.c @@ -1,3 +1,7 @@ +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include "reggroups.h" #include "stack-man.h" #include "simplex86.h" @@ -7,7 +11,7 @@ reg_to_index (reg_alloc_t *ra, reg_t reg) const reg_pool_t *pool = ra->reg_pool; int i; - for (i = 0; i < MAX_REGISTER; ++i) + for (i = 0; i < MAX_REGISTERS; ++i) { if (pool->registers[i] == reg) return i; @@ -20,8 +24,6 @@ void reg_alloc_init (reg_alloc_t *ra, stack_man_t *stack, const reg_pool_t *reg_pool) { - int i; - ra->reg_pool = reg_pool; memset (ra->groups, 0, sizeof (ra->groups)); @@ -68,9 +70,9 @@ reg_alloc_reload (reg_alloc_t *ra, int n_regs, reg_t reg, ...) while (reg != (reg_t)0) { - int idx = op_to_index (reg); + int idx = reg_to_index (ra, reg); - if (ra->active->allocated[idx] && ra->active->spilled[idx] != -1) + if (ra->active->allocated[idx] && ra->active->spill_offset[idx] != -1) { /* FIXME: unspill */ } @@ -83,20 +85,33 @@ reg_alloc_reload (reg_alloc_t *ra, int n_regs, reg_t reg, ...) reg_t reg_alloc_alloc (reg_alloc_t *ra) { - reg_t r; int i, j; - /* Is there a register that doesn't currently have a value? */ + /* Is there a register that is + * - unallocated in the current group + * - either unallocated or spilled in all other groups? + */ for (i = 0; i < MAX_REGISTERS; ++i) { if (ra->active->allocated[i]) - continue; - - if (unloaded (ra, i)) + goto next_register; + + for (j = 0; j < MAX_GROUPS; ++j) { - ra->active->allocate[i] = 1; - return ra->reg_pool[i]; + reg_group_t *group = &ra->groups[i]; + + if (group->name == NULL || group == ra->active) + continue; + + if (group->allocated[i] && group->spill_offset[i] == -1) + goto next_register; } + + /* Found one */ + return ra->reg_pool->registers[i]; + + next_register: + ; } /* No, then in order of best to worst group, @@ -120,12 +135,12 @@ reg_alloc_alloc (reg_alloc_t *ra) /* Have a winner (or loser) */ /* FIXME: insert spill code */ group->spill_offset[i] = 100; - return i; + return ra->reg_pool->registers[i]; } } } - /* At this point something is seriously wrong. Either: + /* If we get here, something is seriously wrong. Either: * - an internal error in the register allocator has * produced a situation where a register is in used * but no group claims it is loaded. @@ -150,10 +165,33 @@ reg_alloc_alloc (reg_alloc_t *ra) /* @reg becomes allocated in the current group, though it * may be moved to another register */ -op_t +reg_t reg_alloc_preserve (reg_alloc_t *ra, reg_t reg) { int idx = reg_to_index (ra, reg); + int in_use; + int i; + + /* If the register is not in use by another group, then + * just mark it allocated in the current group. + */ + + /* Otherwise, if reg is not allocated in the current group, + * then spill it in the other group, and mark it in-use here. + */ + + /* Otherwise, a new register must be allocated, and the + * content moved there. FIXME: so that means the allocator + * must know how to do reg-reg moves. + */ + + /* Otherwise, a new register must be allocated + + /* Is the register in question being used by another group? */ + for (i = 0; i < MAX_GROUPS; ++i) + { + reg_group_t *group = &ra->groups[i]; + } if (ra->active->allocated[idx]) { @@ -164,21 +202,13 @@ reg_alloc_preserve (reg_alloc_t *ra, reg_t reg) } void -reg_alloc_free (reg_alloc_t *ra, op_t reg); +reg_alloc_free (reg_alloc_t *ra, reg_t reg); typedef struct reg_info_t reg_info_t; typedef struct reg_alloc_t reg_alloc_t; typedef struct reg_context_t reg_context_t; -#define MAX_REGISTERS 64 - -struct reg_alloc_t -{ - const reg_pool_t * registers; - stack_man_t * stack_man; -}; - typedef enum { UNUSED, /* not in use by us, and not in use by parent */ @@ -202,13 +232,5 @@ struct reg_context_t reg_info_t info[MAX_REGISTERS]; }; -void -reg_alloc_init (reg_alloc_t * reg_alloc, - const reg_pool_t *registers, - stack_man_t * stack_man, - reg_context_t * initial_context, - int n_initial, - /* op_t reg, */ ...); - /* The registers */ diff --git a/reggroups.h b/reggroups.h index b8c0dc7..95ac758 100644 --- a/reggroups.h +++ b/reggroups.h @@ -42,7 +42,7 @@ reg_alloc_free_group (reg_alloc_t *ra, const char *name); * all registers that will be used again before switching away. */ void -reg_alloc_reload (reg_alloc_t *ra, op_t reg, ...); +reg_alloc_reload (reg_alloc_t *ra, int n_regs, reg_t reg, ...); /* allocate some register within the current group */ reg_t |