home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / kaffevm / jit / basecode.c next >
C/C++ Source or Header  |  1996-09-28  |  7KB  |  410 lines

  1. /*
  2.  * basecode.c
  3.  *
  4.  * Copyright (c) 1996 Systems Architecture Research Centre,
  5.  *           City University, London, UK.
  6.  *
  7.  * See the file "license.terms" for information on usage and redistribution
  8.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  9.  *
  10.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, June 1996.
  11.  */
  12.  
  13. #include <assert.h>
  14. #include "gtypes.h"
  15. #include "slots.h"
  16. #include "seq.h"
  17. #include "registers.h"
  18. #include "icode.h"
  19. #include "basecode.h"
  20. #include "md.h"
  21. #include "flags.h"
  22.  
  23. /* Modify references */
  24. #define    INCREF(_s)    if ((_s) && (_s)->insn) {        \
  25.                 (_s)->insn->ref++;        \
  26.             }
  27. #define    LINCREF(_s)    if (_s) {                \
  28.                 if ((_s)[0].insn) {        \
  29.                     (_s)[0].insn->ref++;    \
  30.                 }                \
  31.                 if ((_s)[1].insn) {        \
  32.                     (_s)[1].insn->ref++;    \
  33.                 }                \
  34.             }
  35. #define    ASSIGNSLOT(_d, _s)                    \
  36.             (_d).s.slot = (_s);            \
  37.             (_d).s.seq = ((_s) ? (_s)->insn : 0)
  38. #define    LASSIGNSLOT(_d, _s)                    \
  39.             ASSIGNSLOT(_d, _s)
  40.  
  41. /*
  42.  * Optimise destination to remove any overwrites.
  43.  */
  44. #define    OPTIMISE_WRITE(_d) if (flag_optimise) overwrite_optimise((_d)->insn)
  45. /*
  46.  * Optimise operands to eliminate addition moves.
  47.  */
  48. #define    OPTIMISE_READ(_s) if (flag_optimise) (_s) = move_optimise(_s)
  49.  
  50. static slots* move_optimise(slots*);
  51. void overwrite_optimise(sequence*);
  52.  
  53. extern void nop(sequence*);
  54.  
  55. void
  56. _slot_const_const(slots* dst, int s1, int s2, ifunc f, int type)
  57. {
  58.     sequence* seq = nextSeq();
  59.  
  60.     seq->u[1].iconst = s1;
  61.     seq->u[2].iconst = s2;
  62.     ASSIGNSLOT(seq->u[0], dst);
  63.     if (dst != 0) {
  64.         OPTIMISE_WRITE(dst);
  65.         dst->insn = seq;
  66.     }
  67.  
  68.     seq->opt = USE_NO_SLOTS;
  69.     seq->type = type;
  70.     seq->func = f;
  71. }
  72.  
  73. void
  74. _slot_slot_const(slots* dst, slots* s1, int s2, ifunc f, int type)
  75. {
  76.     sequence* seq;
  77. #if defined(TWO_OPERAND)
  78.     slots* olddst = 0;
  79. #endif
  80.  
  81.     OPTIMISE_READ(s1);
  82.  
  83. #if defined(TWO_OPERAND)
  84.     /* Two operand systems cannot handle three operand ops.
  85.      * We need to fixit so the dst is one of the source ops.
  86.      */
  87.     if (s1 != 0 && dst != 0) {
  88.         if (s1 != dst && type != Tload) {
  89.             move_any(dst, s1);
  90.             s1 = dst;
  91.         }
  92.     }
  93. #endif
  94.     seq = nextSeq();
  95.  
  96.     INCREF(s1);
  97.  
  98.     ASSIGNSLOT(seq->u[1], s1);
  99.     seq->u[2].iconst = s2;
  100.     ASSIGNSLOT(seq->u[0], dst);
  101.     if (dst != 0) {
  102.         OPTIMISE_WRITE(dst);
  103.         dst->insn = seq;
  104.     }
  105.  
  106.     seq->opt = USE_SLOT_1;
  107.     seq->type = type;
  108.     seq->func = f;
  109. }
  110.  
  111. void
  112. _slot_slot_fconst(slots* dst, slots* s1, double s2, ifunc f, int type)
  113. {
  114.     sequence* seq = nextSeq();
  115.  
  116.     OPTIMISE_READ(s1);
  117.  
  118.     ASSIGNSLOT(seq->u[1], s1);
  119.     seq->u[2].fconst = s2;
  120.     ASSIGNSLOT(seq->u[0], dst);
  121.     INCREF(s1);
  122.     if (dst != 0) {
  123.         OPTIMISE_WRITE(dst);
  124.         dst->insn = seq;
  125.     }
  126.  
  127.     seq->opt = USE_SLOT_1;
  128.     seq->type = type;
  129.     seq->func = f;
  130. }
  131.  
  132. void
  133. _slot_slot_slot(slots* dst, slots* s1, slots* s2, ifunc f, int type)
  134. {
  135.     sequence* seq;
  136. #if defined(TWO_OPERAND)
  137.     slots* olddst = 0;
  138. #endif
  139.  
  140.     OPTIMISE_READ(s1);
  141.     OPTIMISE_READ(s2);
  142.  
  143. #if defined(TWO_OPERAND)
  144.     /* Two operand systems cannot handle three operand ops.
  145.      * We need to fixit so the dst is one of the source ops.
  146.      */
  147.     if (s1 != 0 && s2 != 0 && dst != 0) {
  148.         if (s2 == dst) {
  149.             olddst = dst;
  150.             slot_alloctmp(dst);
  151.         }
  152.         if (s1 != dst) {
  153.             move_any(dst, s1);
  154.             s1 = dst;
  155.         }
  156.     }
  157. #endif
  158.     seq = nextSeq();
  159.  
  160.     INCREF(s1);
  161.     INCREF(s2);
  162.  
  163.     ASSIGNSLOT(seq->u[1], s1);
  164.     ASSIGNSLOT(seq->u[2], s2);
  165.     ASSIGNSLOT(seq->u[0], dst);
  166.     if (dst != 0) {
  167.         OPTIMISE_WRITE(dst);
  168.         dst->insn = seq;
  169.     }
  170.  
  171.     seq->opt = USE_SLOT_12;
  172.     seq->type = type;
  173.     seq->func = f;
  174.  
  175. #if defined(TWO_OPERAND)
  176.     if (olddst != 0) {
  177.         move_any(olddst, dst);
  178.     }
  179. #endif
  180. }
  181.  
  182. void
  183. _lslot_lslot_lslot(slots* dst, slots* s1, slots* s2, ifunc f, int type)
  184. {
  185.     sequence* seq;
  186. #if defined(TWO_OPERAND)
  187.     /* Two operand systems cannot handle three operand ops.
  188.      * We need to fixit so the dst is one of the source ops.
  189.      */
  190.     slots* olddst = 0;
  191.     if (s1 != 0 && s2 != 0 && dst != 0) {
  192.         if (s2 == dst) {
  193.             olddst = dst;
  194.             slot_alloc2tmp(dst);
  195.         }
  196.         if (s1 != dst) {
  197.             move_anylong(dst, s1);
  198.             s1 = dst;
  199.         }
  200.     }
  201. #endif
  202.     seq = nextSeq();
  203.  
  204.     LASSIGNSLOT(seq->u[1], s1);
  205.     LASSIGNSLOT(seq->u[2], s2);
  206.     ASSIGNSLOT(seq->u[0], dst);
  207.     LINCREF(s1);
  208.     LINCREF(s2);
  209.     if (dst != 0) {
  210.         dst[0].insn = seq;
  211.         dst[1].insn = 0;
  212.     }
  213.  
  214.     seq->opt = USE_NO_SLOTS;
  215.     seq->type = type;
  216.     seq->func = f;
  217.  
  218.     if (olddst != 0) {
  219.         move_anylong(olddst, dst);
  220.     }
  221. }
  222.  
  223. void
  224. _lslot_lslot_slot(slots* dst, slots* s1, slots* s2, ifunc f, int type)
  225. {
  226.     sequence* seq;
  227. #if defined(TWO_OPERAND)
  228.     /* Two operand systems cannot handle three operand ops.
  229.      * We need to fixit so the dst is one of the source ops.
  230.      */
  231.     slots* olddst = 0;
  232.     if (s1 != 0 && s2 != 0 && dst != 0) {
  233.         if (s2 == dst) {
  234.             olddst = dst;
  235.             slot_alloctmp(dst);
  236.         }
  237.         if (s1 != dst) {
  238.             move_any(dst, s1);
  239.             s1 = dst;
  240.         }
  241.     }
  242. #endif
  243.     seq = nextSeq();
  244.  
  245.     LASSIGNSLOT(seq->u[1], s1);
  246.     ASSIGNSLOT(seq->u[2], s2);
  247.     ASSIGNSLOT(seq->u[0], dst);
  248.     LINCREF(s1);
  249.     INCREF(s2);
  250.     if (dst != 0) {
  251.         dst[0].insn = seq;
  252.         dst[1].insn = 0;
  253.     }
  254.  
  255.     seq->opt = USE_NO_SLOTS;
  256.     seq->type = type;
  257.     seq->func = f;
  258.  
  259. #if defined(TWO_OPERAND)
  260.     if (olddst != 0) {
  261.         move_any(olddst, dst);
  262.     }
  263. #endif
  264. }
  265.  
  266. void
  267. _slot_slot_lslot(slots* dst, slots* s1, slots* s2, ifunc f, int type)
  268. {
  269.     sequence* seq;
  270. #if defined(TWO_OPERAND)
  271.     /* Two operand systems cannot handle three operand ops.
  272.      * We need to fixit so the dst is one of the source ops.
  273.      */
  274.     slots* olddst = 0;
  275.     if (s1 != 0 && s2 != 0 && dst != 0) {
  276.         if (s2 == dst) {
  277.             olddst = dst;
  278.             slot_alloctmp(dst);
  279.         }
  280.         if (s1 != dst) {
  281.             move_any(dst, s1);
  282.             s1 = dst;
  283.         }
  284.     }
  285. #endif
  286.     seq = nextSeq();
  287.  
  288.     ASSIGNSLOT(seq->u[1], s1);
  289.     LASSIGNSLOT(seq->u[2], s2);
  290.     ASSIGNSLOT(seq->u[0], dst);
  291.     INCREF(s1);
  292.     LINCREF(s2);
  293.     if (dst != 0) {
  294.         dst->insn = seq;
  295.     }
  296.  
  297.     seq->type = type;
  298.     seq->func = f;
  299.  
  300. #if defined(TWO_OPERAND)
  301.     if (olddst != 0) {
  302.         move_any(olddst, dst);
  303.     }
  304. #endif
  305. }
  306.  
  307. void
  308. _lslot_slot_lconst(slots* dst, slots* s1, jlong s2, ifunc f, int type)
  309. {
  310.     sequence* seq = nextSeq();
  311.  
  312.     ASSIGNSLOT(seq->u[1], s1);
  313.     seq->u[2].lconst = s2;
  314.     ASSIGNSLOT(seq->u[0], dst);
  315.     INCREF(s1);
  316.     if (dst != 0) {
  317.         dst[0].insn = seq;
  318.         dst[1].insn = 0;
  319.     }
  320.  
  321.     seq->opt = USE_NO_SLOTS;
  322.     seq->type = type;
  323.     seq->func = f;
  324. }
  325.  
  326. void
  327. _lslot_slot_fconst(slots* dst, slots* s1, double s2, ifunc f, int type)
  328. {
  329.     sequence* seq = nextSeq();
  330.  
  331.     ASSIGNSLOT(seq->u[1], s1);
  332.     seq->u[2].fconst = s2;
  333.     ASSIGNSLOT(seq->u[0], dst);
  334.     INCREF(s1);
  335.     if (dst != 0) {
  336.         dst[0].insn = seq;
  337.         dst[1].insn = 0;
  338.     }
  339.  
  340.     seq->opt = USE_NO_SLOTS;
  341.     seq->type = type;
  342.     seq->func = f;
  343. }
  344.  
  345. /*
  346.  * Optimise sources by removing move operations.
  347.  */
  348. static
  349. slots*
  350. move_optimise(slots* s)
  351. {
  352.     sequence* nseq;
  353.  
  354.     if (s == 0) {
  355.         return (s);
  356.     }
  357.     nseq = s->insn;
  358.     if (nseq == 0) {
  359.         return (s);
  360.     }
  361.     for (;;) {
  362.         if (nseq->type != Tcopy) {
  363.             return (s);
  364.         }
  365.         if (seq_seq(nseq, 2) == 0) {
  366.             return (s);
  367.         }
  368.         if (seq_slot(nseq, 2)->insn != seq_seq(nseq, 2)) {
  369.             return (s);
  370.         }
  371.         s = seq_slot(nseq, 2);
  372.         nseq = seq_seq(nseq, 2);
  373.     }
  374. }
  375.  
  376. /*
  377.  * Optimise destinations by cancelling overwrites.
  378.  */
  379. void
  380. overwrite_optimise(sequence* seq)
  381. {
  382.     if (seq != 0 && --seq->ref == 0) {
  383.         if (SLOT_1(seq->opt)) {
  384.             overwrite_optimise(seq_seq(seq, 1));
  385.         }
  386.         if (SLOT_2(seq->opt)) {
  387.             overwrite_optimise(seq_seq(seq, 2));
  388.         }
  389.     }
  390. }
  391.  
  392. /*
  393.  * Pop a sequence.
  394.  */
  395. void
  396. seq_pop(sequence* seq)
  397. {
  398.     seq->ref--;
  399.     if (seq->ref != 0) {
  400.         return;
  401.     }
  402.  
  403.     if (SLOT_1(seq->opt) && seq_slot(seq, 1)) {
  404.         seq_slot(seq, 1)->insn = seq_seq(seq, 1);
  405.     }
  406.     if (SLOT_2(seq->opt) && seq_slot(seq, 2)) {
  407.         seq_slot(seq, 2)->insn = seq_seq(seq, 2);
  408.     }
  409. }
  410.