2 Assembler Operand support.
11 asmop *_newForLiteral(operand *op)
13 asmop *aop = _new(AOP_TYPE_LITERAL);
14 aop->u.literal = op->operand.valOperand;
15 aop->size = getSize(operandType(op));
20 asmop *_newForSymbol(symbol *sym, iCode *ic)
29 space = SPEC_OCLS(sym->etype);
31 if (sym->aop != NULL) {
35 else if (sym->onStack || sym->iaccess) {
36 // On the stack or only available by indirect access.
37 aop = _new(AOP_TYPE_STACK);
38 aop->size = getSize(sym->type);
40 aop->u.stack = sym->stack;
42 else if (IS_FUNC(sym->type)) {
43 // Functions are special. The symbol is constant and available.
44 aop = _new(AOP_TYPE_IMMEDIATE);
45 aop->u.immediate = gc_strdup(sym->rname);
46 // PENDING: Size of a function pointer.
50 // Somewhere in 'far' space. ie only accessable through a pointer register.
51 aop = _new(AOP_TYPE_SCRATCH_PTR);
52 aop->size = getSize(sym->type);
53 aop->u.scratch = sym->rname;
56 // Attach the asmop to the symbol.
62 asmop *_newForRemat(symbol *sym)
65 iCode *ic = sym->rematiCode;
66 asmop *aop = _new(AOP_TYPE_IMMEDIATE);
68 // Terminate the string first up.
71 // Combine up any offsets.
72 while (ic->op == '+' || ic->op == '-') {
73 sprintf(s, "0x%04X %c ", (int)operandLitValue(IC_RIGHT(ic)), ic->op);
76 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
79 sprintf(s, "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
81 aop->size = getSize(sym->type);
82 aop->u.immediate = gc_strdup(buffer);
87 asmop *_newForTemporary(operand *op, iCode *ic)
89 symbol *sym = OP_SYMBOL(op);
92 if (sym->regType == REG_TYPE_CND) {
93 // Conditionals have no size due to being stored in carry.
94 aop = _new(AOP_TYPE_CARRY);
97 else if (sym->isspilt || sym->nRegs == 0) {
98 // No registers so it must be somewhere on the stack or remat.
100 aop = _newForRemat(sym);
102 else if (sym->accuse) {
103 // Packed into one of the normally unavailable registers.
106 else if (sym->ruonly) {
107 // Only used in the return.
112 aop = _newForSymbol(sym->usl.spillLoc, ic);
116 // Must be in registers.
117 aop = _new(AOP_TYPE_REG);
118 aop->size = sym->nRegs;
119 aop->u.reg = sym->regs[0];
121 // Attach to the op and symbol.
128 /** Bind a new AOP to the given operand.
130 void izt_bindAop(operand *op, iCode *ic)
133 // Do nothing. Just return.
135 else if (IS_OP_LITERAL(op)) {
136 op->aop = _newForLiteral(op);
138 else if (op->aop != NULL) {
139 // It already has one allocated. Use it.
142 else if (IS_SYMOP(op) && OP_SYMBOL(op)->aop != NULL) {
143 // The attached symbol already has an asmop. Reuse it.
144 op->aop = OP_SYMBOL(op)->aop;
146 else if (IS_TRUE_SYMOP(op)) {
147 // Its a true symbol, so bind in a symbol asmop.
148 op->aop = _newForSymbol(OP_SYMBOL(op), ic);
151 // A temporary. Find where the temporary is stored and setup an asmop for it.
152 op->aop = _newForTemporary(op, ic);
156 /** Creates a new asmop that wraps the return value registers.
158 asmop *izt_getAopForReturn(int size)
160 asmop *aop = _new(AOP_TYPE_REG);
162 aop->u.reg = izt_port->returnRegs[izt_util_binLog(size)];