diff options
author | kugwa <kugwa2000@gmail.com> | 2015-12-31 18:18:45 +0800 |
---|---|---|
committer | kugwa <kugwa2000@gmail.com> | 2015-12-31 18:18:45 +0800 |
commit | be8b0c2eb7b040f4bf9338bfdeb72b794f56ac9a (patch) | |
tree | ecc619a4457db1d2bfc5a8e58f354db8b3c8f709 | |
parent | fdefb21ebaeb6e6de2d7cd4cfdefab0de1ab7fa7 (diff) | |
download | compiler2015-be8b0c2eb7b040f4bf9338bfdeb72b794f56ac9a.tar.gz compiler2015-be8b0c2eb7b040f4bf9338bfdeb72b794f56ac9a.tar.zst compiler2015-be8b0c2eb7b040f4bf9338bfdeb72b794f56ac9a.zip |
Add code for register management
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | src/code-generation.c | 1 | ||||
-rw-r--r-- | src/register.c | 117 | ||||
-rw-r--r-- | src/register.h | 37 |
4 files changed, 157 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index f5972eb..a75c137 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,8 @@ parser_SOURCES = \ src/code-generation.c \ src/draw.h \ src/draw.c \ + src/register.h \ + src/register.c \ src/semantic-analysis.h \ src/semantic-analysis.c \ src/state.h \ diff --git a/src/code-generation.c b/src/code-generation.c index d455968..7709d59 100644 --- a/src/code-generation.c +++ b/src/code-generation.c @@ -3,6 +3,7 @@ #endif #include "code-generation.h" +#include "register.h" #include <assert.h> #include <inttypes.h> diff --git a/src/register.c b/src/register.c new file mode 100644 index 0000000..82631f8 --- /dev/null +++ b/src/register.c @@ -0,0 +1,117 @@ +#include "register.h" + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> + +#define REG_NUM 6 +#define REG_RESERVED "x9" +#define REG_LOCK_MAX 3 + +static const char *reg_name[REG_NUM] = { + "x10", "x11", "x12", "x13", "x14", "x15"}; + +/* static void mov(CcmmcTmp *a, CcmmcTmp *b) +{ +} */ + +CcmmcRegPool *ccmmc_register_init(void) +{ + CcmmcRegPool *pool = malloc(sizeof(CcmmcRegPool)); + pool->num = REG_NUM; + pool->list = malloc(sizeof(CcmmcReg*) * pool->num); + for (int i = 0; i < pool->num; i++) { + pool->list[i] = malloc(sizeof(CcmmcReg)); + pool->list[i]->tmp = NULL; + pool->list[i]->lock = 0; + pool->list[i]->name = reg_name[i]; + } + pool->lock_max = REG_LOCK_MAX; + pool->lock_cnt = 0; + pool->top = 0; + pool->exceed = 0; + return pool; +} + +CcmmcTmp *ccmmc_register_alloc(CcmmcRegPool *pool) +{ + CcmmcTmp *tmp = malloc(sizeof(CcmmcTmp)); + if (pool->top < pool->num) { + tmp->reg = pool->list[pool->top]; + tmp->addr = 0; + tmp->reg->tmp = tmp; + pool->top++; + } + else { + tmp->reg = NULL; + tmp->addr = (pool->exceed + 1) * (-8); // TODO: assign an offset for original tmp + pool->exceed++; + } + return tmp; +} + +const char *ccmmc_register_lock(CcmmcRegPool *pool, CcmmcTmp *tmp) +{ + const char *reg = NULL; + if (pool->lock_cnt < pool->lock_max) { + if (tmp->reg !=NULL) { + if (tmp->reg->lock == 0) { + tmp->reg->lock = 1; + pool->lock_cnt++; + } + reg = tmp->reg->name; + } + else { // find a unlocked reg + int i; + for (i = 0; i < pool->num && pool->list[i]->lock == 1; i++); + + // TODO: mov REG_RESERVED, pool->list[i]->name + // TODO: ldr pool->list[i]->name, tmp->addr + // TODO: str REG_RESERVED, tmp->addr + + pool->list[i]->tmp->reg = NULL; + pool->list[i]->tmp->addr = tmp->addr; + tmp->reg = pool->list[i]; + tmp->addr = 0; + + tmp->reg->lock = 1; + pool->lock_cnt++; + reg = tmp->reg->name; + } + } + return reg; +} + +void ccmmc_register_unlock(CcmmcRegPool *pool, CcmmcTmp *tmp) +{ + if (tmp->reg != NULL && tmp->reg->lock == 1) { + tmp->reg->lock = 0; + pool->lock_cnt--; + } +} + +void ccmmc_register_free(CcmmcRegPool *pool, CcmmcTmp *tmp) +{ + if (pool->exceed == 0) { + int i; + for (i = 0; i < pool->num && pool->list[i] != tmp->reg; i++); + if (i < pool->top - 1) { + CcmmcReg *swap = pool->list[i]; + pool->list[i] = pool->list[pool->top - 1]; + pool->list[pool->top - 1] = swap; + } + pool->top--; + free(tmp); + } + else { + assert(false); + } +} + +void ccmmc_register_caller_save(CcmmcRegPool *pool) +{ +} + +void ccmmc_register_caller_load(CcmmcRegPool *pool) +{ +} diff --git a/src/register.h b/src/register.h new file mode 100644 index 0000000..2f52e6d --- /dev/null +++ b/src/register.h @@ -0,0 +1,37 @@ +#ifndef CCMMC_HEADER_REGISTER_H +#define CCMMC_HEADER_REGISTER_H + +typedef struct CcmmcRegStruct CcmmcReg; +typedef struct CcmmcTmpStruct { + CcmmcReg *reg; + int addr; +} CcmmcTmp; + +typedef struct CcmmcRegStruct { + CcmmcTmp *tmp; + int lock; + const char *name; +} CcmmcReg; + +typedef struct CcmmcRegPoolStruct { + CcmmcReg **list; + int num; + int lock_cnt; + int lock_max; + int top; + int exceed; +} CcmmcRegPool; + +CcmmcRegPool *ccmmc_register_init (void); +CcmmcTmp *ccmmc_register_alloc (CcmmcRegPool *pool); +const char *ccmmc_register_lock (CcmmcRegPool *pool, + CcmmcTmp *tmp); +void ccmmc_register_unlock (CcmmcRegPool *pool, + CcmmcTmp *tmp); +void ccmmc_register_free (CcmmcRegPool *pool, + CcmmcTmp *tmp); +void ccmmc_register_caller_save (CcmmcRegPool *pool); +void ccmmc_register_caller_load (CcmmcRegPool *pool); + +#endif +// vim: set sw=4 ts=4 sts=4 et: |