summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2013-12-22 11:44:48 -0500
committerSøren Sandmann <ssp@redhat.com>2013-12-22 11:44:48 -0500
commit4dadd937f66bf8a91ebff16fc40afa8505c88007 (patch)
treeac66b72ff70d11d8e3ae05094f308ed0ea95f28d
parent181eef863b38bba050225b15e057f18845edccdf (diff)
More reggroups
-rw-r--r--Makefile7
-rw-r--r--iterjit.c32
-rw-r--r--reggroups.c86
-rw-r--r--reggroups.h2
4 files changed, 89 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 00b78ce..1886df7 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/iterjit.c b/iterjit.c
index 0f311c2..3329185 100644
--- a/iterjit.c
+++ b/iterjit.c
@@ -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