From 9f1ff3eae07f9e1ba8c33fed9809dd534531cae4 Mon Sep 17 00:00:00 2001 From: michaelh Date: Tue, 15 May 2001 01:07:03 +0000 Subject: [PATCH] Added missing files git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@821 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/izt/aop.c | 165 ++++++++++++++++++++++++++++++++++++++++ src/izt/aop.h | 39 ++++++++++ src/izt/i186_mappings.i | 54 +++++++++++++ src/izt/regs.h | 60 +++++++++++++++ src/izt/util.c | 25 ++++++ 5 files changed, 343 insertions(+) create mode 100644 src/izt/aop.c create mode 100644 src/izt/aop.h create mode 100644 src/izt/i186_mappings.i create mode 100644 src/izt/regs.h create mode 100644 src/izt/util.c diff --git a/src/izt/aop.c b/src/izt/aop.c new file mode 100644 index 00000000..a4b88cba --- /dev/null +++ b/src/izt/aop.c @@ -0,0 +1,165 @@ +/** @file izt/aop.c + Assembler Operand support. +*/ +#include "izt.h" + +asmop *_new(int type) +{ + return NULL; +} + +asmop *_newForLiteral(operand *op) +{ + asmop *aop = _new(AOP_TYPE_LITERAL); + aop->u.literal = op->operand.valOperand; + aop->size = getSize(operandType(op)); + + return aop; +} + +asmop *_newForSymbol(symbol *sym, iCode *ic) +{ + memmap *space; + asmop *aop; + + wassert(ic); + wassert(sym); + wassert(sym->etype); + + space = SPEC_OCLS(sym->etype); + + if (sym->aop != NULL) { + // Already has one. + aop = sym->aop; + } + else if (sym->onStack || sym->iaccess) { + // On the stack or only available by indirect access. + aop = _new(AOP_TYPE_STACK); + aop->size = getSize(sym->type); + + aop->u.stack = sym->stack; + } + else if (IS_FUNC(sym->type)) { + // Functions are special. The symbol is constant and available. + aop = _new(AOP_TYPE_IMMEDIATE); + aop->u.immediate = gc_strdup(sym->rname); + // PENDING: Size of a function pointer. + aop->size = 2; + } + else { + // Somewhere in 'far' space. ie only accessable through a pointer register. + aop = _new(AOP_TYPE_SCRATCH_PTR); + aop->size = getSize(sym->type); + aop->u.scratch = sym->rname; + } + + // Attach the asmop to the symbol. + sym->aop = aop; + + return aop; +} + +asmop *_newForRemat(symbol *sym) +{ + char *s = buffer; + iCode *ic = sym->rematiCode; + asmop *aop = _new(AOP_TYPE_IMMEDIATE); + + // Terminate the string first up. + *s = '\0'; + + // Combine up any offsets. + while (ic->op == '+' || ic->op == '-') { + sprintf(s, "0x%04X %c ", (int)operandLitValue(IC_RIGHT(ic)), ic->op); + s += strlen(s); + + ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; + } + + sprintf(s, "%s", OP_SYMBOL(IC_LEFT(ic))->rname); + + aop->size = getSize(sym->type); + aop->u.immediate = gc_strdup(buffer); + + return aop; +}; + +asmop *_newForTemporary(operand *op, iCode *ic) +{ + symbol *sym = OP_SYMBOL(op); + asmop *aop; + + if (sym->regType == REG_TYPE_CND) { + // Conditionals have no size due to being stored in carry. + aop = _new(AOP_TYPE_CARRY); + aop->size = 0; + } + else if (sym->isspilt || sym->nRegs == 0) { + // No registers so it must be somewhere on the stack or remat. + if (sym->remat) { + aop = _newForRemat(sym); + } + else if (sym->accuse) { + // Packed into one of the normally unavailable registers. + wassert(0); + } + else if (sym->ruonly) { + // Only used in the return. + wassert(0); + } + else { + // Must be spilt. + aop = _newForSymbol(sym->usl.spillLoc, ic); + } + } + else { + // Must be in registers. + aop = _new(AOP_TYPE_REG); + aop->size = sym->nRegs; + aop->u.reg = sym->regs[0]; + } + // Attach to the op and symbol. + op->aop = aop; + sym->aop = aop; + + return aop; +} + +/** Bind a new AOP to the given operand. + */ +void izt_bindAop(operand *op, iCode *ic) +{ + if (op == NULL) { + // Do nothing. Just return. + } + else if (IS_OP_LITERAL(op)) { + op->aop = _newForLiteral(op); + } + else if (op->aop != NULL) { + // It already has one allocated. Use it. + // Do nothing. + } + else if (IS_SYMOP(op) && OP_SYMBOL(op)->aop != NULL) { + // The attached symbol already has an asmop. Reuse it. + op->aop = OP_SYMBOL(op)->aop; + } + else if (IS_TRUE_SYMOP(op)) { + // Its a true symbol, so bind in a symbol asmop. + op->aop = _newForSymbol(OP_SYMBOL(op), ic); + } + else { + // A temporary. Find where the temporary is stored and setup an asmop for it. + op->aop = _newForTemporary(op, ic); + } +} + +/** Creates a new asmop that wraps the return value registers. + */ +asmop *izt_getAopForReturn(int size) +{ + asmop *aop = _new(AOP_TYPE_REG); + aop->size = size; + aop->u.reg = izt_port->returnRegs[izt_util_binLog(size)]; + + return aop; +} diff --git a/src/izt/aop.h b/src/izt/aop.h new file mode 100644 index 00000000..b37e9d10 --- /dev/null +++ b/src/izt/aop.h @@ -0,0 +1,39 @@ +/** @file izt/aop.h + */ +#ifndef IZT_AOP_INCLUDE +#define IZT_AOP_INCLUDE + +typedef enum { + AOP_TYPE_REG, + AOP_TYPE_CARRY, + AOP_TYPE_LITERAL, + AOP_TYPE_STACK, + AOP_TYPE_SCRATCH_PTR, + AOP_TYPE_IMMEDIATE +} AOP_TYPE; + +typedef struct asmop { + AOP_TYPE type; + int size; + union { + value *literal; + REG *reg; + int stack; + const char *immediate; + const char *scratch; + } u; +} asmop; + +#define AOP(op) op->aop +#define AOP_TYPE(op) AOP(op)->type +#define AOP_SIZE(op) AOP(op)->size + +/** Bind a new AOP to the given operand. + */ +void izt_bindAop(operand *op, iCode *ic); + +/** Creates a new asmop that wraps the return value registers. + */ +asmop *izt_getAopForReturn(int size); + +#endif diff --git a/src/izt/i186_mappings.i b/src/izt/i186_mappings.i new file mode 100644 index 00000000..5fa73ed2 --- /dev/null +++ b/src/izt/i186_mappings.i @@ -0,0 +1,54 @@ +static const ASM_MAPPING _as86_mapping[] = { + { "global", ".GLOBAL %s" }, + { "labeldef", "%s:" }, + { "tlabeldef", "l%05d:" }, + { "tlabel", "l%05d" }, + { "fileprelude", "" }, + { "functionheader", + "; ---------------------------------\n" + "; Function %s\n" + "; ---------------------------------" + }, + { "functionlabeldef", "%s:" }, + { "zero", "$00" }, + { "one", "$01" }, + { "area", ".SECT %s" }, + { "areadata", ".SECT .DATA" }, + { "areacode", ".SECT .TEXT" }, + { "areahome", ".SECT .TEXT" }, + { "module", "; Module %s" }, + { "ascii", ".ASCII \"%s\"" }, + { "ds", "lcomm %d" }, + { "db", ".B" }, + { "dbs", "DB %s" }, + { "dw", "DW" }, + { "dws", "DW %s" }, + { "immed", "" }, + { "constbyte", "$%02X" }, + { "constword", "$%04X" }, + { "immedword", "$%04X" }, + { "immedbyte", "$%02X" }, + { "hashedstr", "%s" }, + { "lsbimmeds", "%s & $FF" }, + { "msbimmeds", "%s >> 8" }, + { NULL, NULL } +}; + +static const ASM_MAPPING _as86_i186_mapping[] = { + { "adjustsp", "add sp,*-%d" }, + { "enter", "enter 0,0" }, + { "enterx", "enter -%d,0" }, + { "leave", "leave" }, + { "leavex", "leave" }, + { NULL, NULL } +}; + +static const ASM_MAPPINGS _as86_mappings = { + NULL, + _as86_mapping, +}; + +static const ASM_MAPPINGS _as86_i186_mappings = { + &_as86_mappings, + _as86_i186_mapping +}; diff --git a/src/izt/regs.h b/src/izt/regs.h new file mode 100644 index 00000000..6e1501aa --- /dev/null +++ b/src/izt/regs.h @@ -0,0 +1,60 @@ +#ifndef REGS_INCLUDE +#define REGS_INCLUDE + +typedef enum { + REG_ID_NONE, + // Z80 + REG_ID_A, + REG_ID_B, + REG_ID_C, + REG_ID_D, + REG_ID_E, + REG_ID_H, + REG_ID_L, + REG_ID_AF, + REG_ID_BC, + REG_ID_DE, + REG_ID_HL, + REG_ID_IX, + REG_ID_IY, + // TLCS-900H + REG_ID_XBC, + REG_ID_XDE, + // i186 + REG_ID_AL, + REG_ID_AH, + REG_ID_AX, + REG_ID_BL, + REG_ID_BH, + REG_ID_BX, + + REG_ID_BP, + + REG_ID_CL, + REG_ID_CH, + REG_ID_CX, + REG_ID_DL, + REG_ID_DH, + REG_ID_DX, + REG_ID_MAX +} REG_ID; + +enum { + REG_USED = 1, + REG_USED_HIDDEN = 2 +}; + +enum { + REG_TYPE_CND = 1, + REG_TYPE_GPR = 2 +} REG_TYPE; + +typedef struct regs { + int size; + REG_ID id; + const char *name; + int used; + REG_ID hides[3]; +} REG; + +#endif diff --git a/src/izt/util.c b/src/izt/util.c new file mode 100644 index 00000000..7481beda --- /dev/null +++ b/src/izt/util.c @@ -0,0 +1,25 @@ +/** @file izt/util.c + */ +#include "izt.h" + +int izt_util_binLog(int i) +{ + static const int lookup[] = { + 0, 0, 1, -1, 2, -1, -1, -1, 3 + }; + + if (i < NUM_OF(lookup)) { + if (lookup[i] != -1) { + return lookup[i]; + } + else { + // Unsupported. + wassert(0); + } + } + else { + // Unsupported. + wassert(0); + } + return 0; +} -- 2.39.5