bytecode: Add bytecode
authorDavid Schleef <ds@schleef.org>
Sun, 9 Oct 2011 06:17:10 +0000 (23:17 -0700)
committerDavid Schleef <ds@schleef.org>
Sun, 9 Oct 2011 06:17:10 +0000 (23:17 -0700)
orc/Makefile.am
orc/generate-bytecode.c [new file with mode: 0644]
orc/orcbytecode.c [new file with mode: 0644]
orc/orcbytecode.h [new file with mode: 0644]
orc/orcprogram.h
testsuite/Makefile.am
testsuite/bytecode_parse.c [new file with mode: 0644]

index 8f379e0..436eae0 100644 (file)
@@ -12,6 +12,7 @@ liborc_@ORC_MAJORMINOR@_la_CFLAGS = $(ORC_CFLAGS) \
 
 liborc_@ORC_MAJORMINOR@_la_SOURCES = \
        orc.c \
+       orcbytecode.c \
        orcemulateopcodes.c \
        orcexecutor.c \
        orcfunctions.c \
@@ -91,15 +92,20 @@ pkginclude_HEADERS = \
        orccpuinsn.h \
        orc-stdint.h
 
-noinst_PROGRAMS = generate-emulation
+noinst_PROGRAMS = generate-emulation generate-bytecode
 
 generate_emulation_LDADD = $(ORC_LIBS)
 generate_emulation_CFLAGS = $(ORC_CFLAGS)
 generate_emulation_DEPENDENCIES = liborc-0.4.la
 
-update: generate-emulation
+generate_bytecode_LDADD = $(ORC_LIBS)
+generate_bytecode_CFLAGS = $(ORC_CFLAGS)
+generate_bytecode_DEPENDENCIES = liborc-0.4.la
+
+update: generate-emulation generate-bytecode
        $(top_builddir)/tools/orcc$(EXEEXT) --implementation -o orcfunctions.c orcfunctions.orc
        $(top_builddir)/tools/orcc$(EXEEXT) --header -o orcfunctions.h orcfunctions.orc
        ./generate-emulation$(EXEEXT) -o orcemulateopcodes.c
        ./generate-emulation$(EXEEXT) --header -o orcemulateopcodes.h
+       ./generate-bytecode$(EXEEXT) --header -o orcbytecode.h
        
diff --git a/orc/generate-bytecode.c b/orc/generate-bytecode.c
new file mode 100644 (file)
index 0000000..32bb2eb
--- /dev/null
@@ -0,0 +1,191 @@
+
+#include "config.h"
+
+#include <orc/orc.h>
+#include <orc/orcparse.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+
+int verbose = 0;
+int error = 0;
+int compat;
+
+char *target = "sse";
+
+#define ORC_VERSION(a,b,c,d) ((a)*1000000 + (b)*10000 + (c)*100 + (d))
+#define REQUIRE(a,b,c,d) do { \
+  if (ORC_VERSION((a),(b),(c),(d)) > compat) { \
+    fprintf(stderr, "Feature used that is incompatible with --compat\n"); \
+    exit (1); \
+  } \
+} while (0)
+
+void help (void)
+{
+  printf("Usage:\n");
+  printf("  generate-bytecode [OPTION...]\n");
+  printf("\n");
+  printf("Help Options:\n");
+  printf("  -h, --help              Show help options\n");
+  printf("\n");
+  printf("Application Options:\n");
+  printf("  -o, --output FILE       Write output to FILE\n");
+  printf("\n");
+
+  exit (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *output_file = NULL;
+  char *input_file = NULL;
+  char *include_file = NULL;
+  FILE *output;
+  int i;
+  OrcOpcodeSet *opcode_set;
+  int output_header = FALSE;
+
+  orc_init ();
+
+  for(i=1;i<argc;i++) {
+    if (strcmp (argv[i], "--output") == 0 ||
+        strcmp(argv[i], "-o") == 0) {
+      if (i+1 < argc) {
+        output_file = argv[i+1];
+        i++;
+      } else {
+        help();
+      }
+    } else if (strcmp (argv[i], "--header") == 0) {
+      output_header = TRUE;
+    } else if (strncmp(argv[i], "-", 1) == 0) {
+      printf("Unknown option: %s\n", argv[i]);
+      exit (1);
+    } else {
+      if (input_file == NULL) {
+        input_file = argv[i];
+      } else {
+        printf("More than one input file specified: %s\n", argv[i]);
+        exit (1);
+      }
+    }
+  }
+
+  if (output_file == NULL) {
+    output_file = "out.c";
+  }
+
+  output = fopen (output_file, "w");
+  if (!output) {
+    printf("Could not write output file: %s\n", output_file);
+    exit(1);
+  }
+
+  opcode_set = orc_opcode_set_get ("sys");
+
+  fprintf(output, "\n");
+  fprintf(output, "/* autogenerated by generate-bytecode */\n");
+  fprintf(output, "\n");
+
+  if (output_header) {
+    fprintf(output, "#include <math.h>\n");
+    fprintf(output, "#include <orc/orc.h>\n");
+    if (include_file) {
+      fprintf(output, "#include <%s>\n", include_file);
+    }
+    fprintf(output, "\n");
+
+    fprintf(output, "typedef enum {\n");
+    fprintf(output, "  ORC_BC_END,\n");
+    fprintf(output, "  ORC_BC_BEGIN_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_END_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_SET_CONSTANT_N,\n");
+    fprintf(output, "  ORC_BC_SET_N_MULTIPLE,\n");
+    fprintf(output, "  ORC_BC_SET_N_MINIMUM,\n");
+    fprintf(output, "  ORC_BC_SET_N_MAXIMUM,\n");
+    fprintf(output, "  ORC_BC_SET_2D,\n");
+    fprintf(output, "  ORC_BC_SET_CONSTANT_M,\n");
+    fprintf(output, "  ORC_BC_SET_NAME,\n");
+    fprintf(output, "  ORC_BC_SET_BACKUP_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_ADD_DESTINATION,\n");
+    fprintf(output, "  ORC_BC_ADD_SOURCE,\n");
+    fprintf(output, "  ORC_BC_ADD_ACCUMULATOR,\n");
+    fprintf(output, "  ORC_BC_ADD_CONSTANT,\n");
+    fprintf(output, "  ORC_BC_ADD_CONSTANT_INT64,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_FLOAT,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_INT64,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_DOUBLE,\n");
+    fprintf(output, "  ORC_BC_ADD_TEMPORARY,\n");
+    for (i=21;i<32;i++){
+      fprintf(output, "  ORC_BC_RESERVED_%d,\n", i);
+    }
+    for(i=0;i<opcode_set->n_opcodes;i++){
+      OrcStaticOpcode *opcode = opcode_set->opcodes + i;
+
+      if ((i+32)%10 == 0) {
+        fprintf(output, "  /* %d */\n", i+32);
+      }
+      fprintf(output, "  ORC_BC_%s,\n", opcode->name);
+
+    }
+    fprintf(output, "  /* %d */\n", i+32);
+    fprintf(output, "  ORC_BC_LAST\n");
+    fprintf(output, "} OrcBytecodes;\n");
+  } else {
+    fprintf(output, "#ifdef HAVE_CONFIG_H\n");
+    fprintf(output, "#include \"config.h\"\n");
+    fprintf(output, "#endif\n");
+
+    fprintf(output, "  ORC_BC_END,\n");
+    fprintf(output, "  ORC_BC_BEGIN_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_END_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_SET_CONSTANT_N,\n");
+    fprintf(output, "  ORC_BC_SET_N_MULTIPLE,\n");
+    fprintf(output, "  ORC_BC_SET_N_MINIMUM,\n");
+    fprintf(output, "  ORC_BC_SET_N_MAXIMUM,\n");
+    fprintf(output, "  ORC_BC_SET_2D,\n");
+    fprintf(output, "  ORC_BC_SET_CONSTANT_M,\n");
+    fprintf(output, "  ORC_BC_SET_NAME,\n");
+    fprintf(output, "  ORC_BC_SET_BACKUP_FUNCTION,\n");
+    fprintf(output, "  ORC_BC_ADD_DESTINATION,\n");
+    fprintf(output, "  ORC_BC_ADD_SOURCE,\n");
+    fprintf(output, "  ORC_BC_ADD_ACCUMULATOR,\n");
+    fprintf(output, "  ORC_BC_ADD_CONSTANT,\n");
+    fprintf(output, "  ORC_BC_ADD_CONSTANT_INT64,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_FLOAT,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_INT64,\n");
+    fprintf(output, "  ORC_BC_ADD_PARAMETER_DOUBLE,\n");
+    fprintf(output, "  ORC_BC_ADD_TEMPORARY,\n");
+    for (i=21;i<32;i++){
+      fprintf(output, "  ORC_BC_RESERVED_%d,\n", i);
+    }
+
+    for(i=0;i<opcode_set->n_opcodes;i++){
+      OrcStaticOpcode *opcode = opcode_set->opcodes + i;
+
+      if ((i+32)%10 == 0) {
+        fprintf(output, "  /* %d */\n", i+32);
+      }
+      fprintf(output, "  { \"%s\" },\n", opcode->name);
+
+    }
+    fprintf(output, "  /* %d */\n", i+32);
+    fprintf(output, "  ORC_BC_LAST\n");
+    fprintf(output, "} OrcBytecodes;\n");
+  }
+
+  fclose (output);
+
+  if (error) exit(1);
+
+  return 0;
+}
+
+
diff --git a/orc/orcbytecode.c b/orc/orcbytecode.c
new file mode 100644 (file)
index 0000000..14a12dc
--- /dev/null
@@ -0,0 +1,294 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <orc/orc.h>
+#include <orc/orcbytecode.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+void bytecode_append_code (OrcBytecode *bytecode, int code);
+void bytecode_append_int (OrcBytecode *bytecode, int value);
+void bytecode_append_uint32 (OrcBytecode *bytecode, orc_uint32 value);
+void bytecode_append_uint64 (OrcBytecode *bytecode, orc_uint64 value);
+void bytecode_append_string (OrcBytecode *bytecode, char *s);
+
+
+OrcBytecode *
+orc_bytecode_new (void)
+{
+  OrcBytecode *bytecode;
+
+  bytecode = malloc (sizeof(OrcBytecode));
+  memset (bytecode, 0, sizeof(OrcBytecode));
+
+  bytecode->alloc_len = 256;
+  bytecode->bytecode = malloc(bytecode->alloc_len);
+
+  return bytecode;
+}
+
+void
+orc_bytecode_free (OrcBytecode *bytecode)
+{
+  free (bytecode->bytecode);
+  free (bytecode);
+}
+
+OrcBytecode *
+orc_bytecode_from_program (OrcProgram *p)
+{
+  OrcBytecode *bytecode = orc_bytecode_new ();
+  int i;
+  OrcVariable *var;
+  OrcOpcodeSet *opcode_set;
+
+  opcode_set = orc_opcode_set_get ("sys");
+
+  bytecode_append_code (bytecode, ORC_BC_BEGIN_FUNCTION);
+
+  if (p->constant_n != 0) {
+    bytecode_append_code (bytecode, ORC_BC_SET_CONSTANT_N);
+    bytecode_append_int (bytecode, p->constant_n);
+  }
+  if (p->n_multiple != 0) {
+    bytecode_append_code (bytecode, ORC_BC_SET_N_MULTIPLE);
+    bytecode_append_int (bytecode, p->n_multiple);
+  }
+  if (p->n_minimum != 0) {
+    bytecode_append_code (bytecode, ORC_BC_SET_N_MINIMUM);
+    bytecode_append_int (bytecode, p->n_minimum);
+  }
+  if (p->n_maximum != 0) {
+    bytecode_append_code (bytecode, ORC_BC_SET_N_MAXIMUM);
+    bytecode_append_int (bytecode, p->n_maximum);
+  }
+  if (p->is_2d) {
+    bytecode_append_code (bytecode, ORC_BC_SET_2D);
+    if (p->constant_m != 0) {
+      bytecode_append_code (bytecode, ORC_BC_SET_CONSTANT_M);
+      bytecode_append_int (bytecode, p->constant_m);
+    }
+  }
+  if (p->name) {
+    bytecode_append_code (bytecode, ORC_BC_SET_NAME);
+    bytecode_append_string (bytecode, p->name);
+  }
+#if 0
+  //if (!is_inline) {
+  if (p->backup_function) {
+    bytecode_append_code (bytecode, ORC_BC_SET_BACKUP_FUNCTION);
+    bytecode_pointer (bytecode, p->backup_function);
+  }
+#endif
+  for(i=0;i<4;i++){
+    var = &p->vars[ORC_VAR_D1 + i];
+    if (var->size) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_DESTINATION);
+      bytecode_append_int (bytecode, var->size);
+      bytecode_append_int (bytecode, var->alignment);
+    }
+  }
+  for(i=0;i<8;i++){
+    var = &p->vars[ORC_VAR_S1 + i];
+    if (var->size) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_SOURCE);
+      bytecode_append_int (bytecode, var->size);
+      bytecode_append_int (bytecode, var->alignment);
+    }
+  }
+  for(i=0;i<4;i++){
+    var = &p->vars[ORC_VAR_A1 + i];
+    if (var->size) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_ACCUMULATOR);
+      bytecode_append_int (bytecode, var->size);
+      //bytecode_append_int (bytecode, var->alignment);
+    }
+  }
+  for(i=0;i<8;i++){
+    var = &p->vars[ORC_VAR_C1 + i];
+    if (var->size == 0) continue;
+    if (var->size <= 4) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_CONSTANT);
+      bytecode_append_int (bytecode, var->size);
+      bytecode_append_uint32 (bytecode, (orc_uint32)var->value.i);
+    } else if (var->size > 4) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_CONSTANT_INT64);
+      bytecode_append_int (bytecode, var->size);
+      bytecode_append_uint64 (bytecode, (orc_uint64)var->value.i);
+    }
+  }
+  for(i=0;i<8;i++){
+    var = &p->vars[ORC_VAR_P1 + i];
+    if (var->size) {
+      switch (var->param_type) {
+        case ORC_PARAM_TYPE_INT:
+          bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER);
+          break;
+        case ORC_PARAM_TYPE_FLOAT:
+          bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_FLOAT);
+          break;
+        case ORC_PARAM_TYPE_INT64:
+          bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_INT64);
+          break;
+        case ORC_PARAM_TYPE_DOUBLE:
+          bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_INT64);
+          break;
+        default:
+          ORC_ASSERT(0);
+          break;
+      }
+      bytecode_append_int (bytecode, var->size);
+    }
+  }
+  for(i=0;i<16;i++){
+    var = &p->vars[ORC_VAR_T1 + i];
+    if (var->size) {
+      bytecode_append_code (bytecode, ORC_BC_ADD_TEMPORARY);
+      bytecode_append_int (bytecode, var->size);
+    }
+  }
+
+  for(i=0;i<p->n_insns;i++){
+    OrcInstruction *insn = p->insns + i;
+
+    bytecode_append_code (bytecode, (insn->opcode - opcode_set->opcodes) + 32);
+    if (insn->opcode->dest_size[0] != 0) {
+      bytecode_append_int (bytecode, insn->dest_args[0]);
+    }
+    if (insn->opcode->dest_size[1] != 0) {
+      bytecode_append_int (bytecode, insn->dest_args[1]);
+    }
+    if (insn->opcode->src_size[0] != 0) {
+      bytecode_append_int (bytecode, insn->src_args[0]);
+    }
+    if (insn->opcode->src_size[1] != 0) {
+      bytecode_append_int (bytecode, insn->src_args[1]);
+    }
+    if (insn->opcode->src_size[2] != 0) {
+      bytecode_append_int (bytecode, insn->src_args[2]);
+    }
+  }
+
+  bytecode_append_code (bytecode, ORC_BC_END_FUNCTION);
+  bytecode_append_code (bytecode, ORC_BC_END);
+
+  return bytecode;
+}
+
+void
+bytecode_append_byte (OrcBytecode *bytecode, int byte)
+{
+  if (bytecode->length >= bytecode->alloc_len) {
+    bytecode->alloc_len += 256;
+    bytecode->bytecode = realloc (bytecode->bytecode, bytecode->alloc_len);
+  }
+  bytecode->bytecode[bytecode->length] = byte;
+  bytecode->length++;
+}
+
+void
+bytecode_append_code (OrcBytecode *bytecode, int code)
+{
+  bytecode_append_byte (bytecode, code);
+#if 0
+  OrcOpcodeSet *opcode_set = orc_opcode_set_get ("sys");
+
+  fprintf(bytecode, "\n  ");
+  if (code >= 32) {
+    fprintf(bytecode, "ORC_BC_%s, ", opcode_set->opcodes[code-32].name);
+  } else {
+    static char *codes[32] = {
+      "END",
+      "BEGIN_FUNCTION",
+      "END_FUNCTION",
+      "SET_CONSTANT_N",
+      "SET_N_MULTIPLE",
+      "SET_N_MINIMUM",
+      "SET_N_MAXIMUM",
+      "SET_2D",
+      "SET_CONSTANT_M",
+      "SET_NAME",
+      "SET_BACKUP_FUNCTION",
+      "ADD_DESTINATION",
+      "ADD_SOURCE",
+      "ADD_ACCUMULATOR",
+      "ADD_CONSTANT",
+      "ADD_CONSTANT_INT64",
+      "ADD_PARAMETER",
+      "ADD_PARAMETER_FLOAT",
+      "ADD_PARAMETER_INT64",
+      "ADD_PARAMETER_DOUBLE",
+      "ADD_TEMPORARY",
+      "RESERVED_21",
+      "RESERVED_22",
+      "RESERVED_23",
+      "RESERVED_24",
+      "RESERVED_25",
+      "RESERVED_26",
+      "RESERVED_27",
+      "RESERVED_28",
+      "RESERVED_29",
+      "RESERVED_30",
+      "RESERVED_31"
+    };
+
+    fprintf(bytecode, "ORC_BC_%s, ", codes[code]);
+  }
+#endif
+}
+
+void
+bytecode_append_int (OrcBytecode *bytecode, int value)
+{
+  ORC_ASSERT(value >= 0);
+
+  if (value < 255) {
+    bytecode_append_byte (bytecode, value);
+  } else if (value < 65535) {
+    bytecode_append_byte (bytecode, 255);
+    bytecode_append_byte (bytecode, value & 0xff);
+    bytecode_append_byte (bytecode, value >> 8);
+  } else {
+    ORC_ASSERT(0);
+  }
+}
+
+void
+bytecode_append_uint32 (OrcBytecode *bytecode, orc_uint32 value)
+{
+  bytecode_append_byte (bytecode, value & 0xff);
+  bytecode_append_byte (bytecode, (value >> 8) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 16) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 24) & 0xff);
+
+}
+
+void
+bytecode_append_uint64 (OrcBytecode *bytecode, orc_uint64 value)
+{
+  bytecode_append_byte (bytecode, value & 0xff);
+  bytecode_append_byte (bytecode, (value >> 8) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 16) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 24) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 32) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 40) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 48) & 0xff);
+  bytecode_append_byte (bytecode, (value >> 56) & 0xff);
+
+}
+
+void
+bytecode_append_string (OrcBytecode *bytecode, char *s)
+{
+  int i;
+  int len = strlen(s);
+  bytecode_append_int (bytecode, len);
+  for(i=0;i<len;i++){
+    bytecode_append_byte (bytecode, s[i]);
+  }
+}
+
diff --git a/orc/orcbytecode.h b/orc/orcbytecode.h
new file mode 100644 (file)
index 0000000..23aae09
--- /dev/null
@@ -0,0 +1,258 @@
+
+/* autogenerated by generate-bytecode */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <math.h>
+#include <orc/orc.h>
+
+typedef enum {
+  ORC_BC_END,
+  ORC_BC_BEGIN_FUNCTION,
+  ORC_BC_END_FUNCTION,
+  ORC_BC_SET_CONSTANT_N,
+  ORC_BC_SET_N_MULTIPLE,
+  ORC_BC_SET_N_MINIMUM,
+  ORC_BC_SET_N_MAXIMUM,
+  ORC_BC_SET_2D,
+  ORC_BC_SET_CONSTANT_M,
+  ORC_BC_SET_NAME,
+  ORC_BC_SET_BACKUP_FUNCTION,
+  ORC_BC_ADD_DESTINATION,
+  ORC_BC_ADD_SOURCE,
+  ORC_BC_ADD_ACCUMULATOR,
+  ORC_BC_ADD_CONSTANT,
+  ORC_BC_ADD_CONSTANT_INT64,
+  ORC_BC_ADD_PARAMETER,
+  ORC_BC_ADD_PARAMETER_FLOAT,
+  ORC_BC_ADD_PARAMETER_INT64,
+  ORC_BC_ADD_PARAMETER_DOUBLE,
+  ORC_BC_ADD_TEMPORARY,
+  ORC_BC_RESERVED_21,
+  ORC_BC_RESERVED_22,
+  ORC_BC_RESERVED_23,
+  ORC_BC_RESERVED_24,
+  ORC_BC_RESERVED_25,
+  ORC_BC_RESERVED_26,
+  ORC_BC_RESERVED_27,
+  ORC_BC_RESERVED_28,
+  ORC_BC_RESERVED_29,
+  ORC_BC_RESERVED_30,
+  ORC_BC_RESERVED_31,
+  ORC_BC_absb,
+  ORC_BC_addb,
+  ORC_BC_addssb,
+  ORC_BC_addusb,
+  ORC_BC_andb,
+  ORC_BC_andnb,
+  ORC_BC_avgsb,
+  ORC_BC_avgub,
+  /* 40 */
+  ORC_BC_cmpeqb,
+  ORC_BC_cmpgtsb,
+  ORC_BC_copyb,
+  ORC_BC_loadb,
+  ORC_BC_loadoffb,
+  ORC_BC_loadupdb,
+  ORC_BC_loadupib,
+  ORC_BC_loadpb,
+  ORC_BC_ldresnearb,
+  ORC_BC_ldresnearl,
+  /* 50 */
+  ORC_BC_ldreslinb,
+  ORC_BC_ldreslinl,
+  ORC_BC_maxsb,
+  ORC_BC_maxub,
+  ORC_BC_minsb,
+  ORC_BC_minub,
+  ORC_BC_mullb,
+  ORC_BC_mulhsb,
+  ORC_BC_mulhub,
+  ORC_BC_orb,
+  /* 60 */
+  ORC_BC_shlb,
+  ORC_BC_shrsb,
+  ORC_BC_shrub,
+  ORC_BC_signb,
+  ORC_BC_storeb,
+  ORC_BC_subb,
+  ORC_BC_subssb,
+  ORC_BC_subusb,
+  ORC_BC_xorb,
+  ORC_BC_absw,
+  /* 70 */
+  ORC_BC_addw,
+  ORC_BC_addssw,
+  ORC_BC_addusw,
+  ORC_BC_andw,
+  ORC_BC_andnw,
+  ORC_BC_avgsw,
+  ORC_BC_avguw,
+  ORC_BC_cmpeqw,
+  ORC_BC_cmpgtsw,
+  ORC_BC_copyw,
+  /* 80 */
+  ORC_BC_div255w,
+  ORC_BC_divluw,
+  ORC_BC_loadw,
+  ORC_BC_loadoffw,
+  ORC_BC_loadpw,
+  ORC_BC_maxsw,
+  ORC_BC_maxuw,
+  ORC_BC_minsw,
+  ORC_BC_minuw,
+  ORC_BC_mullw,
+  /* 90 */
+  ORC_BC_mulhsw,
+  ORC_BC_mulhuw,
+  ORC_BC_orw,
+  ORC_BC_shlw,
+  ORC_BC_shrsw,
+  ORC_BC_shruw,
+  ORC_BC_signw,
+  ORC_BC_storew,
+  ORC_BC_subw,
+  ORC_BC_subssw,
+  /* 100 */
+  ORC_BC_subusw,
+  ORC_BC_xorw,
+  ORC_BC_absl,
+  ORC_BC_addl,
+  ORC_BC_addssl,
+  ORC_BC_addusl,
+  ORC_BC_andl,
+  ORC_BC_andnl,
+  ORC_BC_avgsl,
+  ORC_BC_avgul,
+  /* 110 */
+  ORC_BC_cmpeql,
+  ORC_BC_cmpgtsl,
+  ORC_BC_copyl,
+  ORC_BC_loadl,
+  ORC_BC_loadoffl,
+  ORC_BC_loadpl,
+  ORC_BC_maxsl,
+  ORC_BC_maxul,
+  ORC_BC_minsl,
+  ORC_BC_minul,
+  /* 120 */
+  ORC_BC_mulll,
+  ORC_BC_mulhsl,
+  ORC_BC_mulhul,
+  ORC_BC_orl,
+  ORC_BC_shll,
+  ORC_BC_shrsl,
+  ORC_BC_shrul,
+  ORC_BC_signl,
+  ORC_BC_storel,
+  ORC_BC_subl,
+  /* 130 */
+  ORC_BC_subssl,
+  ORC_BC_subusl,
+  ORC_BC_xorl,
+  ORC_BC_loadq,
+  ORC_BC_loadpq,
+  ORC_BC_storeq,
+  ORC_BC_splatw3q,
+  ORC_BC_copyq,
+  ORC_BC_cmpeqq,
+  ORC_BC_cmpgtsq,
+  /* 140 */
+  ORC_BC_andq,
+  ORC_BC_andnq,
+  ORC_BC_orq,
+  ORC_BC_xorq,
+  ORC_BC_addq,
+  ORC_BC_subq,
+  ORC_BC_shlq,
+  ORC_BC_shrsq,
+  ORC_BC_shruq,
+  ORC_BC_convsbw,
+  /* 150 */
+  ORC_BC_convubw,
+  ORC_BC_splatbw,
+  ORC_BC_splatbl,
+  ORC_BC_convswl,
+  ORC_BC_convuwl,
+  ORC_BC_convslq,
+  ORC_BC_convulq,
+  ORC_BC_convwb,
+  ORC_BC_convhwb,
+  ORC_BC_convssswb,
+  /* 160 */
+  ORC_BC_convsuswb,
+  ORC_BC_convusswb,
+  ORC_BC_convuuswb,
+  ORC_BC_convlw,
+  ORC_BC_convhlw,
+  ORC_BC_convssslw,
+  ORC_BC_convsuslw,
+  ORC_BC_convusslw,
+  ORC_BC_convuuslw,
+  ORC_BC_convql,
+  /* 170 */
+  ORC_BC_convsssql,
+  ORC_BC_convsusql,
+  ORC_BC_convussql,
+  ORC_BC_convuusql,
+  ORC_BC_mulsbw,
+  ORC_BC_mulubw,
+  ORC_BC_mulswl,
+  ORC_BC_muluwl,
+  ORC_BC_mulslq,
+  ORC_BC_mululq,
+  /* 180 */
+  ORC_BC_accw,
+  ORC_BC_accl,
+  ORC_BC_accsadubl,
+  ORC_BC_swapw,
+  ORC_BC_swapl,
+  ORC_BC_swapwl,
+  ORC_BC_swapq,
+  ORC_BC_swaplq,
+  ORC_BC_select0wb,
+  ORC_BC_select1wb,
+  /* 190 */
+  ORC_BC_select0lw,
+  ORC_BC_select1lw,
+  ORC_BC_select0ql,
+  ORC_BC_select1ql,
+  ORC_BC_mergelq,
+  ORC_BC_mergewl,
+  ORC_BC_mergebw,
+  ORC_BC_splitql,
+  ORC_BC_splitlw,
+  ORC_BC_splitwb,
+  /* 200 */
+  ORC_BC_addf,
+  ORC_BC_subf,
+  ORC_BC_mulf,
+  ORC_BC_divf,
+  ORC_BC_sqrtf,
+  ORC_BC_maxf,
+  ORC_BC_minf,
+  ORC_BC_cmpeqf,
+  ORC_BC_cmpltf,
+  ORC_BC_cmplef,
+  /* 210 */
+  ORC_BC_convfl,
+  ORC_BC_convlf,
+  ORC_BC_addd,
+  ORC_BC_subd,
+  ORC_BC_muld,
+  ORC_BC_divd,
+  ORC_BC_sqrtd,
+  ORC_BC_maxd,
+  ORC_BC_mind,
+  ORC_BC_cmpeqd,
+  /* 220 */
+  ORC_BC_cmpltd,
+  ORC_BC_cmpled,
+  ORC_BC_convdl,
+  ORC_BC_convld,
+  ORC_BC_convfd,
+  ORC_BC_convdf,
+  /* 226 */
+  ORC_BC_LAST
+} OrcBytecodes;
index 98af8f0..d34b039 100644 (file)
@@ -22,6 +22,7 @@ typedef struct _OrcFixup OrcFixup;
 typedef struct _OrcTarget OrcTarget;
 typedef struct _OrcCode OrcCode;
 typedef struct _OrcCodeChunk OrcCodeChunk;
+typedef struct _OrcBytecode OrcBytecode;
 
 typedef void (*OrcOpcodeEmulateFunc)(OrcOpcodeExecutor *ex, void *user);
 typedef void (*OrcOpcodeEmulateNFunc)(OrcOpcodeExecutor *ex, int index, int n);
@@ -631,6 +632,12 @@ struct _OrcTarget {
   void *_unused[5];
 };
 
+struct _OrcBytecode {
+  orc_uint8 *bytecode;
+  int length;
+  int alloc_len;
+};
+
 
 void orc_init (void);
 
@@ -779,7 +786,6 @@ const char * orc_get_cpu_name (void);
 OrcCode * orc_code_new (void);
 void orc_code_free (OrcCode *code);
 
-
 #ifdef ORC_ENABLE_UNSTABLE_API
 
 int orc_compiler_flag_check (const char *flag);
@@ -799,6 +805,11 @@ extern int _orc_compiler_flag_randomize;
 
 void orc_code_chunk_free (OrcCodeChunk *chunk);
 
+OrcBytecode * orc_bytecode_new (void);
+void orc_bytecode_free (OrcBytecode *bytecode);
+OrcBytecode * orc_bytecode_from_program (OrcProgram *p);
+
+
 #endif
 
 ORC_END_DECLS
index fdae171..4926454 100644 (file)
@@ -18,6 +18,7 @@ noinst_PROGRAMS = $(TESTS) generate_xml_table generate_xml_table2 \
        generate_opcodes_sys compile_parse compile_parse_c memcpy_speed \
        perf_opcodes_sys_compare perf_parse_compare \
        exec_parse \
+       bytecode_parse \
        compile_opcodes_sys_c \
        compile_opcodes_sys \
        show_parse
diff --git a/testsuite/bytecode_parse.c b/testsuite/bytecode_parse.c
new file mode 100644 (file)
index 0000000..fb1e587
--- /dev/null
@@ -0,0 +1,100 @@
+
+#define ORC_ENABLE_UNSTABLE_API
+#include <orc/orc.h>
+#include <orc-test/orctest.h>
+#include <orc/orcparse.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static char * read_file (const char *filename);
+void output_code (OrcProgram *p, FILE *output);
+void output_code_header (OrcProgram *p, FILE *output);
+void output_code_test (OrcProgram *p, FILE *output);
+
+int error = FALSE;
+
+int
+main (int argc, char *argv[])
+{
+  char *code;
+  int n;
+  int i;
+  int j;
+  OrcProgram **programs;
+  const char *filename = NULL;
+
+  orc_init ();
+  orc_test_init ();
+
+  if (argc >= 2) {
+    filename = argv[1];
+  }
+  if (filename == NULL) {
+    filename = getenv ("testfile");
+  }
+  if (filename == NULL) {
+    filename = "test.orc";
+  }
+  code = read_file (filename);
+  if (!code) {
+    printf("compile_parse_test <file.orc>\n");
+    exit(1);
+  }
+
+  n = orc_parse (code, &programs);
+
+  for(i=0;i<n;i++){
+    OrcBytecode *bytecode;
+
+    printf("%s:\n", programs[i]->name);
+    bytecode = orc_bytecode_from_program (programs[i]);
+
+    for(j=0;j<bytecode->length;j++) {
+      printf("%d, ", bytecode->bytecode[j]);
+    }
+    printf("\n");
+  }
+
+  if (error) return 1;
+  return 0;
+}
+
+
+static char *
+read_file (const char *filename)
+{
+  FILE *file = NULL;
+  char *contents = NULL;
+  long size;
+  int ret;
+
+  file = fopen (filename, "r");
+  if (file == NULL) return NULL;
+
+  ret = fseek (file, 0, SEEK_END);
+  if (ret < 0) goto bail;
+
+  size = ftell (file);
+  if (size < 0) goto bail;
+
+  ret = fseek (file, 0, SEEK_SET);
+  if (ret < 0) goto bail;
+
+  contents = malloc (size + 1);
+  if (contents == NULL) goto bail;
+
+  ret = fread (contents, size, 1, file);
+  if (ret < 0) goto bail;
+
+  contents[size] = 0;
+
+  return contents;
+bail:
+  /* something failed */
+  if (file) fclose (file);
+  if (contents) free (contents);
+
+  return NULL;
+}
+