home *** CD-ROM | disk | FTP | other *** search
/ Java 1996 August / Java - Summer 1996.iso / kaffe-0.2 / kaffe / codegen / instruction.c next >
Encoding:
C/C++ Source or Header  |  1996-02-12  |  4.0 KB  |  195 lines

  1. /*
  2.  * instruction.c
  3.  * Manage instructions.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  12.  */
  13.  
  14. #define    IDBG(s)
  15.  
  16. #include <assert.h>
  17. #include <stdio.h>
  18. #include "instruction.h"
  19. #include "register.h"
  20. #include "constants.h"
  21. #include "classMethod.h"
  22. #include "gen.h"
  23. #include "exception.h"
  24. #include "translator.h"
  25. #include "soft.h"
  26.  
  27. #define    MAXLNK        512
  28. #define    NCODESIZE    16*1024
  29. #define    NCODERED    64
  30.  
  31. struct {
  32.     bool    internal;
  33.     int    pos;
  34.     int    pc;
  35.     int    relpc;
  36. } lnkTable[MAXLNK];
  37.  
  38. int jtpos;
  39. nativecode ncodebuf[NCODESIZE+NCODERED];
  40. nativecode* pc;
  41.  
  42. void
  43. dumpInstn(methods* m)
  44. {
  45.     int i;
  46.     int nrop;
  47.     instn* ipc;
  48.     int nr;
  49.  
  50. IDBG(    printf("Method `%s:%s' : flgs=0x%x in=%d, out=%d, local=%d, stk=%d\n",
  51.         m->class->name, m->name, m->accflags, m->ins,
  52.         m->outs, m->localsz, m->stacksz);            )
  53.  
  54.     pc = ncodebuf;
  55.     m->ncode = 0;
  56.     ipc = m->insn;
  57.     nr = m->codelen;
  58.     jtpos = 0;
  59.  
  60.     INSTRUCTION_PROLOGUE(m->localsz);
  61.  
  62.     /* If this is a synchronised method, make sure we enter the monitor
  63.        now. */
  64.     if (m->accflags & ACC_SYNCHRONISED) {
  65.         INSTRUCTION_MONITORENTER(m);
  66.     }
  67.  
  68.     for (; nr > 0; nr--, ipc++) {
  69.         ipc->addr = (int)pc;
  70.         nrop = instnTable[ipc->op].in;
  71.         for (i = 0; i < nrop; i++) {
  72.             if (ipc->in[i].valid == true) {
  73.                 INSTRUCTION_POP(ipc->in[i].reg);
  74.             }
  75.         }
  76.         (*(genfunc)instnTable[ipc->op].func)(ipc);
  77.         nrop = instnTable[ipc->op].out;
  78.         for (i = nrop - 1; i >= 0; i--) {
  79.             if (ipc->out[i].valid == true) {
  80.                 INSTRUCTION_PUSH(ipc->out[i].reg);
  81.             }
  82.         }
  83.  
  84.         /* Cannot overrun the ncode buffer */
  85.         if (pc > &ncodebuf[NCODESIZE]) {
  86.             fprintf(stderr, "Internal error: too little ncode space.\n");
  87.             abort();
  88.         }
  89.     }
  90.  
  91.     /* Move the code to a malloced buffer then fill in the jumps */
  92.     m->ncode = (nativecode*)malloc(pc - ncodebuf);
  93.     if (m->ncode == 0) {
  94.         abort();
  95.     }
  96.     m->ncode_end = m->ncode + (pc - ncodebuf);
  97.     memcpy(m->ncode, ncodebuf, pc - ncodebuf);
  98.     fillinLinks(m);
  99. }
  100.  
  101. /*
  102.  * Add a relative link to the link table for later fixup.
  103.  */
  104. void
  105. addLink(int offset, int point, int relpoint, bool in)
  106. {
  107.     lnkTable[jtpos].internal = in;
  108.     lnkTable[jtpos].pos = offset;
  109.     lnkTable[jtpos].pc = point;
  110.     lnkTable[jtpos].relpc = relpoint;
  111.     jtpos++;
  112.     if (jtpos == MAXLNK) {
  113.         fprintf(stderr, "Internal error: Out of jump table space.\n");
  114.         exit(1);
  115.     }
  116. }
  117.  
  118. /*
  119.  * Run down link table fixing up links.
  120.  */
  121. fillinLinks(methods* m)
  122. {
  123.     int i;
  124.     instn* ipc;
  125.     int clen;
  126.     int adjust;
  127.  
  128.     ipc = m->insn;
  129.     clen = m->codelen;
  130.     adjust = m->ncode - ncodebuf;
  131.  
  132.     for (i = 0; i < jtpos; i++) {
  133.         if (lnkTable[i].internal == true) {
  134.             assert(lnkTable[i].pos >= 0);
  135.             assert(lnkTable[i].pos < clen);
  136.             *(int*)(lnkTable[i].pc + adjust) = ipc[lnkTable[i].pos].addr - lnkTable[i].relpc;
  137.         }
  138.         else {
  139.             *(int*)(lnkTable[i].pc + adjust) = lnkTable[i].pos - (lnkTable[i].relpc + adjust);
  140.         }
  141.     }
  142. }
  143.  
  144. /*
  145.  * Translate exception table.
  146.  */
  147. void
  148. dumpExceptions(methods* m)
  149. {
  150.     int i;
  151.     exception* e;
  152.     int adjust;
  153.  
  154.     /* If no exception table then ignore */
  155.     if (m->exception_table == 0) {
  156.         return;
  157.     }
  158.  
  159.     adjust = m->ncode - ncodebuf;
  160.  
  161.     /* Translate into real addresses */
  162.     for (i = 0; i < m->exception_table_len; i++) {
  163.         e = &m->exception_table[i];
  164.         e->start_pc = m->insn[e->start_pc].addr + adjust;
  165.         e->end_pc = m->insn[e->end_pc].addr + adjust;
  166.         e->handler_pc = m->insn[e->handler_pc].addr + adjust;
  167.     }
  168. }
  169.  
  170. /*
  171.  * Translate lookup and table switches.
  172.  */
  173. void
  174. dumpSwitches(methods* m)
  175. {
  176.     tableswitch* table;
  177.     lookupswitch* lookup;
  178.     int adjust;
  179.     int i;
  180.  
  181.     adjust = m->ncode - ncodebuf;
  182.  
  183.     for (table = m->tableswitches; table != 0; table = table->next) {
  184.         for (i = 0; i < table->len; i++) {
  185.             table->offsets[i] = m->insn[table->offsets[i]].addr + adjust;
  186.         }
  187.     }
  188.  
  189.     for (lookup = m->lookupswitches; lookup != 0; lookup = lookup->next) {
  190.         for (i = 0; i < lookup->len; i++) {
  191.             lookup->offsets[i*2+1] = m->insn[lookup->offsets[i*2+1]].addr + adjust;
  192.         }
  193.     }
  194. }
  195.