summaryrefslogtreecommitdiff
path: root/reggroups.h
blob: 0984e827ebd44967b215217cad3c7f374d89c2eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "stack-man.h"
#include "simplex86.h"

typedef struct reg_alloc_t reg_alloc_t;
typedef struct reg_group_t reg_group_t;
typedef struct reg_pool_t reg_pool_t;

#define MAX_REGISTERS (16)
#define MAX_GROUPS    (16)

struct reg_pool_t
{
    int         n_registers;
    int         register_size;
    op_t	reg_reg_instruction;
    reg_t       registers[MAX_REGISTERS];
};

struct reg_group_t
{
    const char *name;
    int allocated[MAX_REGISTERS];
    int spill_offset[MAX_REGISTERS]; /* -1 if not spilled */
};

struct reg_alloc_t
{
    const reg_pool_t *reg_pool;
    reg_group_t groups[MAX_GROUPS];
    reg_group_t *active;
};

void
reg_alloc_init (reg_alloc_t *ra,
		stack_man_t *stack,
		const reg_pool_t *reg_pool);

void
reg_alloc_switch_group (reg_alloc_t *ra, const char *name);

void
reg_alloc_free_group (reg_alloc_t *ra, const char *name);

/* After switching back to a group, this should be called for
 * all registers that will be used again before switching away.
 */
void
reg_alloc_reload (reg_alloc_t *ra, reg_t *reg, ...);

/* allocate some register within the current group */
reg_t
reg_alloc_alloc (reg_alloc_t *ra);

/* @reg becomes allocated in the current group, though it
 * may be moved to another register
 */
reg_t
reg_alloc_preserve (reg_alloc_t *ra, reg_t reg);

void
reg_alloc_free (reg_alloc_t *ra, reg_t reg);