summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/code-generation.c1
-rw-r--r--src/register.c117
-rw-r--r--src/register.h37
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: