+
+void izt_initEmitters(void)
+{
+ _G.htabs.base = newHashTable(100);
+ _G.htabs.proc = newHashTable(100);
+
+ izt_initBaseEmitters(&_G.htabs.base);
+}
+
+static int _emitterCompare(const void *p1, const void *p2)
+{
+ wassert(p1);
+ wassert(p2);
+ return ((EMITTER *)p1)->op == ((EMITTER *)p2)->op;
+}
+
+static bool _tryEmittingiCode(hTab *h, iCode *ic)
+{
+ EMITTER key = { ic->op, NULL };
+ EMITTER *found;
+
+ found = hTabFindByKey(h, ic->op, &key, _emitterCompare);
+
+ if (found) {
+ found->emit(ic);
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+// Add a NULL terminated array of emitters into the given hash table.
+void izt_addEmittersToHTab(hTab **into, EMITTER _base_emitters[])
+{
+ while (_base_emitters->emit != NULL) {
+ printf("Added an emitter for %u %p\n", _base_emitters->op, _base_emitters);
+ hTabAddItemLong(into, _base_emitters->op, _base_emitters, _base_emitters);
+ _base_emitters++;
+ }
+}
+
+void izt_gen(iCode *iic)
+{
+ iCode *ic = iic;
+ int cln = 0;
+
+ _G.lines.head = NULL;
+ _G.lines.current = NULL;
+
+ // No debug info support.
+
+ for (; ic; ic = ic->next) {
+ const char *name;
+
+ // Print out the source file line number.
+ if (cln != ic->lineno) {
+ iemit("; %s %d", ic->filename, ic->lineno);
+ cln = ic->lineno ;
+ }
+
+ if (ic->generated) {
+ // Code has already been generated. Skip.
+ continue;
+ }
+ if (_isResultRemat(ic)) {
+ // The code is spilt and remat. - no need to generate.
+ continue;
+ }
+
+ // Print the friendly name of the operation, if it has one.
+ name = _findOpName(ic->op);
+ if (name) {
+ iemit("; %s", name);
+ }
+ else {
+ iemit("; warning: unrecognised operation name for %u", ic->op);
+ }
+
+ fflush(stdout);
+ // Now actually call the code generator.
+ // The current processor handler gets first try.
+ if (_tryEmittingiCode(_G.htabs.proc, ic)) {
+ // Yay.
+ }
+ else if (_tryEmittingiCode(_G.htabs.base, ic)) {
+ // Base handler took it.
+ }
+ else {
+ // None took it. Warn the developer.
+ iemit("; warning: no handler for code %u", ic->op);
+ }
+ }
+
+ // Pass the code through the peephole optimiser.
+ if (!options.nopeep) {
+ peepHole(&_G.lines.head);
+ }
+
+ // And emit the remainder.
+ _printLines();
+}
+