Initial revision
authorJan Brittenson <bson@gnu.org>
Wed, 22 Sep 1993 15:48:59 +0000 (08:48 -0700)
committerJan Brittenson <bson@gnu.org>
Wed, 22 Sep 1993 15:48:59 +0000 (08:48 -0700)
From-SVN: r5389

gcc/bi-defs.h [new file with mode: 0644]
gcc/bi-opname.c [new file with mode: 0644]
gcc/bi-reverse.c [new file with mode: 0644]
gcc/bytecode.def [new file with mode: 0644]

diff --git a/gcc/bi-defs.h b/gcc/bi-defs.h
new file mode 100644 (file)
index 0000000..dbf32b8
--- /dev/null
@@ -0,0 +1,47 @@
+/* Definitions for Bytecode Interpreter.
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+struct node
+{
+  char *text;
+  struct node *next;
+};
+
+struct variation
+{
+  char *name;
+  int code;
+  struct node *inputs;
+  struct node *outputs;
+  struct node *literals;
+  struct variation *next;
+};
+
+struct def
+{
+  char *basename;
+  char *template;
+  struct variation *variations;
+  struct def *next;
+};
+
+extern struct def *defs;
+extern int ndefs;
+extern void reverse();
diff --git a/gcc/bi-opname.c b/gcc/bi-opname.c
new file mode 100644 (file)
index 0000000..ac2d84a
--- /dev/null
@@ -0,0 +1,35 @@
+/* Utility to generate opcode name list from bytecode definition file.
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "bi-defs.h"
+
+int
+main()
+{
+  struct def *d;
+  struct variation *v;
+
+  yyparse();
+  reverse();
+
+  for (d = defs; d; d = d->next)
+    for (v = d->variations; v; v = v->next)
+      printf("\"%s%s\",\n", d->basename, v->name);
+  return 0;
+}
diff --git a/gcc/bi-reverse.c b/gcc/bi-reverse.c
new file mode 100644 (file)
index 0000000..30eecba
--- /dev/null
@@ -0,0 +1,61 @@
+/* Reverse order of definitions obtained from bytecode definition file.
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#include "bi-defs.h"
+
+#define NULL 0
+
+void
+reverse()
+{
+  struct def *dp, *d, *dn;
+  struct variation *vp, *v, *vn;
+
+  dp = defs;
+  if (dp)
+    {
+      vp = dp->variations;
+      if (vp)
+       {
+         for (v = vp->next, vp->next = NULL; v; vp = v, v = vn)
+           {
+             vn = v->next;
+             v->next = vp;
+           }
+         dp->variations = vp;
+       }
+      for (d = dp->next, dp->next = NULL; d; dp = d, d = dn)
+       {
+         vp = d->variations;
+         if (vp)
+           {
+             for (v = vp->next, vp->next = NULL; v; vp = v, v = vn)
+               {
+                 vn = v->next;
+                 v->next = vp;
+               }
+             d->variations = vp;
+           }
+         dn = d->next;
+         d->next = dp;
+       }
+      defs = dp;
+    }
+}
diff --git a/gcc/bytecode.def b/gcc/bytecode.def
new file mode 100644 (file)
index 0000000..5ac7284
--- /dev/null
@@ -0,0 +1,322 @@
+# -*- C -*-
+# bytecode.def - definitions of bytecodes for the stack machine.
+
+# The production of the bytecode interpreter and compiler is
+# heavily automated by using this file creatively.
+
+# Various elementary data types are understood by the bytecode interpreter.
+# Q[IU] - quarter word (byte) signed and unsigned integers (char).
+# H[IU] - half word signed and unsigned integers (short int, maybe int).
+# S[IU] - single word signed and unsigned integers (maybe int, long int).
+# D[IU] - double word signed and unsigned integers (long long int).
+# SF - single precision floating point (float).
+# DF - double precision floating point (double).
+# XF - extended precision floating point (long double).
+# P - pointer type for address arithmetic and other purposes.
+
+# The bytecode specification consists of a series of define_operator
+# forms, that are parsed by preprocessors to automatically build
+# various switch statements.
+#      define_operator(name,
+#                      <C prototype code for implementing the operator>,
+#                      <list of variations>)
+# The <C prototype> is self explanatory.
+# The <list of variations> consists of a (parenthesized list) of
+# variation items, each of which is in itself a list.  A variation
+# item consists of a name suffix, the types of the input arguments
+# expected on the stack (shallowest item first) and (optionally) the
+# types of the output arguments (similarly ordered).  Finally, the
+# types of the literal arguments (if any) may appear.
+
+# Substitution in the C prototype code is as follows:
+# Substitution happens only after a dollar sign.  To get a literal
+# dollar sign (why would you ever want one anyway?) use $$.
+# $R1 means "result 1" $TR1 means "type name of result one"
+# $S1 means "source 1" and similarly with $TS1.
+# $L1 means "literal (inline) argument 1" and $TL1 means type thereof.
+#
+
+# Notice that the number following $R doesn't affect the push order;
+# it's used only for clarity and orthogonality, although it's checked
+# to make sure it doesn't exceed the number of outputs. A $R reference
+# results in a push, and represents the result lvalue. E.g.
+
+#      $R1 = 2\, $R2 = 17
+# will expand to:
+#      INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17
+#
+
+# Opcode 0 should never happen.
+define_operator(neverneverland, abort\(\), (()))
+
+# Stack manipulations.
+define_operator(drop, 0, ((, (SI))))
+define_operator(dup, 0, ((, (SI), (SI, SI))))
+define_operator(over, 0, ((, (SI), (SI, SI))))
+
+# Adjust stack pointer
+
+define_operator(setstack, 0, ((SI,,,(SI))))
+define_operator(adjstack, 0, ((SI,,,(SI))))
+
+# Constants, loads, and stores.
+define_operator(const,
+               $R1 = $L1,
+               ((QI,, (QI), (QI)), (HI,, (HI), (HI)),
+                (SI,, (SI), (SI)), (DI,, (DI), (DI)),
+                (SF,, (SF), (SF)), (DF,, (DF), (DF)),
+                (XF,, (XF), (XF)), (P,, (P), (P))))
+define_operator(load,
+               $R1 = *\($TR1 *\) $S1,
+               ((QI, (P), (QI)), (HI, (P), (HI)),
+                (SI, (P), (SI)), (DI, (P), (DI)),
+                (SF, (P), (SF)), (DF, (P), (DF)),
+                (XF, (P), (XF)), (P, (P), (P))))
+define_operator(store,
+               *\($TS2 *\) $S1 = $S2,
+               ((QI, (P, QI)), (HI, (P, HI)),
+                (SI, (P, SI)), (DI, (P, DI)),
+                (SF, (P, SF)), (DF, (P, DF)),
+                (XF, (P, XF)), (P, (P, P)),
+                (BLK, (SI, BLK, BLK))))
+
+# Clear memory block
+
+define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK))))
+
+
+# Advance pointer by SI constant
+
+define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI))))
+
+
+# newlocalSI is used for creating variable-sized storage during function
+# initialization.
+
+# Create local space, return pointer to block
+
+define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P))))
+
+
+# Push the address of a local variable.
+define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI))))
+
+# Push the address of an argument variable.
+define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI))))
+
+# Arithmetic conversions.
+define_operator(convert,
+               $R1 = \($TR1\) $S1,
+               (# Signed integral promotions (sign extensions).
+                (QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)),
+                (QISI, (QI), (SI)),
+                # Unsigned integral promotions (zero extensions).
+                (QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)),
+                (QUSU, (QU), (SU)),
+                # Floating promotions.
+                (SFDF, (SF), (DF)), (DFXF, (DF), (XF)),
+                # Integral truncation.
+                (HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)),
+                (SIQI, (SI), (QI)),
+                 # Unsigned truncation.
+                (SUQU, (SU), (QU)),
+                # Floating truncation.
+                (DFSF, (DF), (SF)), (XFDF, (XF), (DF)),
+                # Integral conversions to floating types.
+                (SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)),
+                (SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)),
+                (DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)),
+                (DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)),
+                # Floating conversions to integral types.
+                (SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)),
+                (SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)),
+                (SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)),
+                (SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)),
+                # Pointer/integer conversions.
+                (PSI, (P), (SI)), (SIP, (SI), (P))))
+
+# Truth value conversion.  These are necessary because conversions of, e.g.,
+# floating types to integers may not function correctly for large values.
+define_operator(convert,
+               $R1 = !!$S1,
+               ((SIT, (SI), (T)), (DIT, (DI), (T)),
+                (SFT, (SF), (T)), (DFT, (DF), (T)),
+                (XFT, (XF), (T)), (PT, (P), (T))))
+
+# Bit field load/store.
+
+# Load and zero-extend bitfield
+
+define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU))))
+
+# Load and sign-extend bitfield
+
+define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI))))
+
+# Store integer in bitfield
+
+define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI))))
+
+
+# Binary operations.
+define_operator(add,
+               $R1 = $S1 + $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
+                (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
+                (XF, (XF, XF), (XF)),
+                (PSI, (P, SI), (P))))
+define_operator(sub,
+               $R1 = $S1 - $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
+                (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
+                (XF, (XF, XF), (XF)),
+                (PP, (P, P), (SI))))
+define_operator(mul,
+               $R1 = $S1 * $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
+                (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
+                (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
+                (XF, (XF, XF), (XF))))
+define_operator(div,
+               $R1 = $S1 / $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
+                (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
+                (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
+                (XF, (XF, XF), (XF))))
+define_operator(mod,
+               $R1 = $S1 % $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
+                (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU))))
+define_operator(and,
+               $R1 = $S1 & $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
+define_operator(ior,
+               $R1 = $S1 | $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
+define_operator(xor,
+               $R1 = $S1 ^ $S2,
+               ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
+define_operator(lshift,
+               $R1 = $S1 << $S2,
+               ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
+                (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
+define_operator(rshift,
+               $R1 = $S1 >> $S2,
+               ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
+                (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
+define_operator(lt,
+               $R1 = $S1 < $S2,
+               ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
+                (DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+define_operator(le,
+               $R1 = $S1 <= $S2,
+               ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
+                (DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+define_operator(ge,
+               $R1 = $S1 >= $S2,
+               ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
+                (DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+define_operator(gt,
+               $R1 = $S1 > $S2,
+               ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
+                (DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+define_operator(eq,
+               $R1 = $S1 == $S2,
+               ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+define_operator(ne,
+               $R1 = $S1 != $S2,
+               ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
+                (SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
+                (XF, (XF, XF), (T)), (P, (P, P), (T))))
+
+# Unary operations.
+define_operator(neg,
+               $R1 = -$S1,
+               ((SI, (SI), (SI)), (DI, (DI), (DI)),
+                (SF, (SF), (SF)), (DF, (DF), (DF)),
+                (XF, (XF), (XF))))
+define_operator(not,
+               $R1 = ~$S1,
+               ((SI, (SI), (SI)), (DI, (DI), (DI))))
+define_operator(not,
+               $R1 = !$S1,
+               ((T, (SI), (SI))))
+
+# Increment operations.
+define_operator(predec,
+               $R1 = *\($TR1 *\) $S1 -= $S2,
+               ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
+                (SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
+                (P, (P, SI), (P)), (SF, (P, SF), (SF)),
+                (DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
+                (BI, (SU, SU, P, SI), (SI))))
+
+define_operator(preinc,
+               $R1 = *\($TR1 *\) $S1 += $S2,
+               ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
+                (SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
+                (P, (P, SI), (P)), (SF, (P, SF), (SF)),
+                (DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
+                (BI, (SU, SU, P, SI), (SI))))
+
+define_operator(postdec,
+               $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2,
+               ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
+                (SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
+                (P, (P, SI), (P)), (SF, (P, SF), (SF)),
+                (DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
+                (BI, (SU, SU, P, SI), (SI))))
+
+define_operator(postinc,
+               $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2,
+               ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
+                (SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
+                (P, (P, SI), (P)), (SF, (P, SF), (SF)),
+                (DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
+                (BI, (SU, SU, P, SI), (SI))))
+
+# Jumps.
+define_operator(jumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
+define_operator(jumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
+define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI))))
+
+# This is for GCC2. It jumps to the address on the stack.
+define_operator(jump, pc = \(void *\) $S1, ((P,,)))
+
+# Switches.  In order to (eventually) support ranges we provide four different
+# varieties of switches.  Arguments are the switch index from the stack, the
+# bytecode offset of the switch table, the size of the switch table, and 
+# the default label.
+define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI))))
+define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI))))
+define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI))))
+define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI))))
+
+# Procedure call.
+# Stack arguments are (deepest first):
+#      procedure arguments in reverse order.
+#      pointer to the place to hold the return value.
+#      address of the call description vector.
+#      pointer to the procedure to be called.
+define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P))))
+
+# Procedure return.
+# Pushes on interpreter stack:
+#       value of retptr (pointer to return value storage slot)
+define_operator(return, $R1 = retptr, ((P,,(P))))
+
+# Really return.
+define_operator(ret, return, (()))
+
+# Print an obnoxious line number.
+define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI))))