24 // Clean up the line so that it is 'prettier'.
27 // If this is a comment line (starts with a ';') then indent it.
28 // PENDING: The outputter does its own pretty print. Disable for now.
30 else if (strchr (buf, ':'))
32 // Is a label - cant do anything.
36 /* Change the first (and probably only) ' ' to a tab so
52 iemit (const char *szFormat,...)
57 va_start (ap, szFormat);
59 tvsprintf (buffer, sizeof(buffer), szFormat, ap);
63 if (_G.lines.current == NULL)
65 _G.lines.head = newLineNode (buffer);
66 _G.lines.current = _G.lines.head;
70 _G.lines.current = connectLine (_G.lines.current, newLineNode (buffer));
73 // PENDING: Inline support.
74 // _G.lines.current->isInline = inLine;
77 // Mapping between operand type and a friendly name.
85 static OPNAME _opnames[] =
89 {UNARYMINUS, "genUminus"},
94 {FUNCTION, "genFunction"},
95 {ENDFUNCTION, "genEndFunction"},
107 {AND_OP, "genAndOp"},
111 {BITWISEAND, "genAnd"},
112 {INLINEASM, "genInline"},
115 {GETHBIT, "genHBIT"},
116 {LEFT_OP, "genLeftShift"},
117 {RIGHT_OP, "genRightShift"},
118 {GET_VALUE_AT_ADDRESS, "genPointerGet"},
121 {ADDRESS_OF, "genAddrOf"},
122 {JUMPTABLE, "genJumpTab"},
124 {RECEIVE, "genReceive"},
129 // Possible return codes for a find matcher.
133 // This element does match.
135 FIND_GREATER_THAN = 1,
136 // This element doesnt match.
137 FIND_NO_MATCH = FIND_GREATER_THAN,
138 // This element marks the end of list.
142 // Limits the given integer to the find result numbers.
148 return FIND_LESS_THAN;
152 return FIND_GREATER_THAN;
160 // Matches an opname id to the given id.
162 _opnamesMatcher (void *pthis, void *pkey)
164 OPNAME *name = pthis;
166 if (name->name == NULL)
172 return _limitToFind (name->op - *(int *) pkey);
176 // Find an element of an unordered list.
178 _find (void *base, size_t elemSize, void *pkey, int (*match) (void *pthis, void *pkey))
182 switch (match (base, pkey))
189 case FIND_GREATER_THAN:
190 base = (char *) base + elemSize;
199 // Finds the friendly operation name for an op number.
203 OPNAME *name = _find (_opnames, sizeof (*_opnames), &op, _opnamesMatcher);
216 _isResultRemat (iCode * ic)
218 if (SKIP_IC (ic) || ic->op == IFX)
221 if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
223 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
224 if (sym->remat && !POINTER_SET (ic))
231 // Print out the generated lines.
235 // Currently a holder function. The Z80 needs some special mangling
237 printLine (_G.lines.head, codeOutBuf);
241 izt_initEmitters (void)
243 _G.htabs.base = newHashTable (100);
244 _G.htabs.proc = newHashTable (100);
246 izt_initBaseEmitters (&_G.htabs.base);
250 _emitterCompare (const void *p1, const void *p2)
254 return ((EMITTER *) p1)->op == ((EMITTER *) p2)->op;
258 _tryEmittingiCode (hTab * h, iCode * ic)
260 EMITTER key; // = {ic->op, NULL}; Borland C chokes on this; initialize below
266 found = hTabFindByKey (h, ic->op, &key, _emitterCompare);
279 // Add a NULL terminated array of emitters into the given hash table.
281 izt_addEmittersToHTab (hTab ** into, EMITTER _base_emitters[])
283 while (_base_emitters->emit != NULL)
285 hTabAddItemLong (into, _base_emitters->op, _base_emitters, _base_emitters);
291 izt_gen (iCode * iic)
296 _G.lines.head = NULL;
297 _G.lines.current = NULL;
299 // No debug info support.
301 for (; ic; ic = ic->next)
305 // Print out the source file line number.
306 if (cln != ic->lineno)
308 iemit ("; %s %d", ic->filename, ic->lineno);
314 // Code has already been generated. Skip.
317 if (_isResultRemat (ic))
319 // The code is spilt and remat. - no need to generate.
323 // Print the friendly name of the operation, if it has one.
324 name = _findOpName (ic->op);
327 iemit ("; %s", name);
331 iemit ("; warning: unrecognised operation name for %u", ic->op);
335 // Now actually call the code generator.
336 // The current processor handler gets first try.
337 if (_tryEmittingiCode (_G.htabs.proc, ic))
341 else if (_tryEmittingiCode (_G.htabs.base, ic))
343 // Base handler took it.
347 // None took it. Warn the developer.
348 iemit ("; warning: no handler for code %u", ic->op);
352 // Pass the code through the peephole optimiser.
355 peepHole (&_G.lines.head);
358 // And emit the remainder.