Blame tools/orcc.c

Packit a43c12
Packit a43c12
#include "config.h"
Packit a43c12
Packit a43c12
#define ORC_ENABLE_UNSTABLE_API
Packit a43c12
Packit a43c12
#include <orc/orc.h>
Packit a43c12
#include <orc/orcparse.h>
Packit a43c12
#include <orc/orcbytecode.h>
Packit a43c12
Packit a43c12
#include <stdio.h>
Packit a43c12
#include <stdlib.h>
Packit a43c12
#include <string.h>
Packit a43c12
#include <ctype.h>
Packit a43c12
Packit a43c12
static char * read_file (const char *filename);
Packit a43c12
void output_code (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_header (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_test (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_backup (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_no_orc (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_assembly (OrcProgram *p, FILE *output);
Packit a43c12
void output_code_execute (OrcProgram *p, FILE *output, int is_inline);
Packit a43c12
void output_program_generation (OrcProgram *p, FILE *output, int is_inline);
Packit a43c12
void output_init_function (FILE *output);
Packit a43c12
static char * get_barrier (const char *s);
Packit a43c12
static const char * my_basename (const char *s);
Packit a43c12
Packit a43c12
int verbose = 0;
Packit a43c12
int error = 0;
Packit a43c12
int compat;
Packit a43c12
int n_programs;
Packit a43c12
OrcProgram **programs;
Packit a43c12
Packit a43c12
int use_inline = FALSE;
Packit a43c12
int use_code = FALSE;
Packit a43c12
int use_lazy_init = FALSE;
Packit a43c12
int use_backup = TRUE;
Packit a43c12
int use_internal = FALSE;
Packit a43c12
Packit a43c12
const char *init_function = NULL;
Packit a43c12
Packit a43c12
char *target = "sse";
Packit a43c12
Packit a43c12
#define ORC_VERSION(a,b,c,d) ((a)*1000000 + (b)*10000 + (c)*100 + (d))
Packit a43c12
#define REQUIRE(a,b,c,d) do { \
Packit a43c12
  if (ORC_VERSION((a),(b),(c),(d)) > compat) { \
Packit a43c12
    fprintf(stderr, "Feature used that is incompatible with --compat in program %s\n", p->name); \
Packit a43c12
    exit (1); \
Packit a43c12
  } \
Packit a43c12
} while (0)
Packit a43c12
Packit a43c12
typedef enum {
Packit a43c12
  MODE_IMPL,
Packit a43c12
  MODE_HEADER,
Packit a43c12
  MODE_TEST,
Packit a43c12
  MODE_ASSEMBLY
Packit a43c12
} OrcMode;
Packit a43c12
Packit a43c12
OrcMode mode = MODE_IMPL;
Packit a43c12
Packit a43c12
void help (void)
Packit a43c12
{
Packit a43c12
  printf("Usage:\n");
Packit a43c12
  printf("  orcc [OPTION...] INPUT_FILE\n");
Packit a43c12
  printf("\n");
Packit a43c12
  printf("Help Options:\n");
Packit a43c12
  printf("  -h, --help              Show help options\n");
Packit a43c12
  printf("\n");
Packit a43c12
  printf("Application Options:\n");
Packit a43c12
  printf("  -v, --verbose           Output more information\n");
Packit a43c12
  printf("  -o, --output FILE       Write output to FILE\n");
Packit a43c12
  printf("  --implementation        Produce C code implementing functions\n");
Packit a43c12
  printf("  --header                Produce C header for functions\n");
Packit a43c12
  printf("  --test                  Produce test code for functions\n");
Packit a43c12
  printf("  --assembly              Produce assembly code for functions\n");
Packit a43c12
  printf("  --include FILE          Add #include <FILE> to code\n");
Packit a43c12
  printf("  --target TARGET         Generate assembly for TARGET\n");
Packit a43c12
  printf("  --compat VERSION        Generate code compatible with Orc version VERSION\n");
Packit a43c12
  printf("  --inline                Generate inline functions in header\n");
Packit a43c12
  printf("  --no-inline             Do not generate inline functions in header\n");
Packit a43c12
  printf("  --internal              Mark functions in header for internal visibility\n");
Packit a43c12
  printf("  --no-internal           Do not mark functions in header for internal visibility\n");
Packit a43c12
  printf("  --init-function FUNCTION  Generate initialization function\n");
Packit a43c12
  printf("  --lazy-init             Do Orc compile at function execution\n");
Packit a43c12
  printf("  --no-backup             Do not generate backup functions\n");
Packit a43c12
  printf("\n");
Packit a43c12
Packit a43c12
  exit (0);
Packit a43c12
}
Packit a43c12
Packit a43c12
int
Packit a43c12
main (int argc, char *argv[])
Packit a43c12
{
Packit a43c12
  const char *orc_version;
Packit a43c12
  char *code;
Packit a43c12
  int n;
Packit a43c12
  int i;
Packit a43c12
  char *output_file = NULL;
Packit a43c12
  char *input_file = NULL;
Packit a43c12
  char *include_file = NULL;
Packit a43c12
  char *compat_version = VERSION;
Packit a43c12
  FILE *output;
Packit a43c12
  char *log = NULL;
Packit a43c12
Packit a43c12
  orc_init ();
Packit a43c12
Packit a43c12
  orc_version = orc_version_string ();
Packit a43c12
  if (strcmp (orc_version, VERSION) != 0) {
Packit a43c12
    fprintf (stderr, "WARNING: unexpected liborc library version %s is being "
Packit a43c12
        "picked up by %s, which is version %s. This might be because orc was "
Packit a43c12
        "installed from source and is also installed via packages, and liborc "
Packit a43c12
        "from the wrong prefix is used. Check your system setup.\n",
Packit a43c12
        orc_version, argv[0], VERSION);
Packit a43c12
    exit(1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  for(i=1;i
Packit a43c12
    if (strcmp(argv[i], "--header") == 0) {
Packit a43c12
      mode = MODE_HEADER;
Packit a43c12
    } else if (strcmp(argv[i], "--implementation") == 0) {
Packit a43c12
      mode = MODE_IMPL;
Packit a43c12
    } else if (strcmp(argv[i], "--test") == 0) {
Packit a43c12
      mode = MODE_TEST;
Packit a43c12
    } else if (strcmp(argv[i], "--assembly") == 0) {
Packit a43c12
      mode = MODE_ASSEMBLY;
Packit a43c12
    } else if (strcmp(argv[i], "--include") == 0) {
Packit a43c12
      if (i+1 < argc) {
Packit a43c12
        include_file = argv[i+1];
Packit a43c12
        i++;
Packit a43c12
      } else {
Packit a43c12
        help();
Packit a43c12
      }
Packit a43c12
    } else if (strcmp (argv[i], "--output") == 0 ||
Packit a43c12
        strcmp(argv[i], "-o") == 0) {
Packit a43c12
      if (i+1 < argc) {
Packit a43c12
        output_file = argv[i+1];
Packit a43c12
        i++;
Packit a43c12
      } else {
Packit a43c12
        help();
Packit a43c12
      }
Packit a43c12
    } else if (strcmp(argv[i], "--target") == 0 ||
Packit a43c12
        strcmp(argv[i], "-t") == 0) {
Packit a43c12
      if (i+1 < argc) {
Packit a43c12
        target = argv[i+1];
Packit a43c12
        i++;
Packit a43c12
      } else {
Packit a43c12
        help();
Packit a43c12
      }
Packit a43c12
    } else if (strcmp(argv[i], "--inline") == 0) {
Packit a43c12
      use_inline = TRUE;
Packit a43c12
    } else if (strcmp(argv[i], "--no-inline") == 0) {
Packit a43c12
      use_inline = FALSE;
Packit a43c12
    } else if (strcmp(argv[i], "--internal") == 0) {
Packit a43c12
      use_internal = TRUE;
Packit a43c12
    } else if (strcmp(argv[i], "--no-internal") == 0) {
Packit a43c12
      use_internal = FALSE;
Packit a43c12
    } else if (strcmp(argv[i], "--init-function") == 0) {
Packit a43c12
      if (i+1 < argc) {
Packit a43c12
        init_function = argv[i+1];
Packit a43c12
        i++;
Packit a43c12
      } else {
Packit a43c12
        help();
Packit a43c12
      }
Packit a43c12
    } else if (strcmp(argv[i], "--help") == 0 ||
Packit a43c12
        strcmp(argv[i], "-h") == 0) {
Packit a43c12
      help ();
Packit a43c12
    } else if (strcmp(argv[i], "--verbose") == 0 ||
Packit a43c12
        strcmp(argv[i], "-v") == 0) {
Packit a43c12
      verbose = 1;
Packit a43c12
    } else if (strcmp(argv[i], "--version") == 0) {
Packit a43c12
      printf("Orc Compiler " PACKAGE_VERSION "\n");
Packit a43c12
      exit (0);
Packit a43c12
    } else if (strcmp(argv[i], "--compat") == 0) {
Packit a43c12
      if (i+1 < argc) {
Packit a43c12
        compat_version = argv[i+1];
Packit a43c12
        i++;
Packit a43c12
      } else {
Packit a43c12
        help();
Packit a43c12
      }
Packit a43c12
    } else if (strcmp(argv[i], "--lazy-init") == 0) {
Packit a43c12
      use_lazy_init = TRUE;
Packit a43c12
    } else if (strcmp(argv[i], "--no-backup") == 0) {
Packit a43c12
      use_backup = FALSE;
Packit a43c12
    } else if (strncmp(argv[i], "-", 1) == 0) {
Packit a43c12
      printf("Unknown option: %s\n", argv[i]);
Packit a43c12
      exit (1);
Packit a43c12
    } else {
Packit a43c12
      if (input_file == NULL) {
Packit a43c12
        input_file = argv[i];
Packit a43c12
      } else {
Packit a43c12
        printf("More than one input file specified: %s\n", argv[i]);
Packit a43c12
        exit (1);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (input_file == NULL) {
Packit a43c12
    printf("No input file specified\n");
Packit a43c12
    exit (1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (mode == MODE_ASSEMBLY && orc_target_get_by_name (target) == NULL) {
Packit a43c12
    printf("Unknown target \"%s\"\n", target);
Packit a43c12
    exit (1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (compat_version) {
Packit a43c12
    int major, minor, micro, nano = 0;
Packit a43c12
    int n;
Packit a43c12
Packit a43c12
    n = sscanf (compat_version, "%d.%d.%d.%d", &major, &minor, &micro, &nano;;
Packit a43c12
Packit a43c12
    if (n < 3) {
Packit a43c12
      printf("Unknown version \"%s\"\n", compat_version);
Packit a43c12
      exit (1);
Packit a43c12
    }
Packit a43c12
Packit a43c12
    compat = ORC_VERSION(major,minor,micro,nano);
Packit a43c12
    if (compat < ORC_VERSION(0,4,5,0)) {
Packit a43c12
      printf("Compatibility version \"%s\" not supported.  Minimum 0.4.5\n",
Packit a43c12
          compat_version);
Packit a43c12
      exit (1);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  if (compat >= ORC_VERSION(0,4,11,1)) {
Packit a43c12
    use_code = TRUE;
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (output_file == NULL) {
Packit a43c12
    switch (mode) {
Packit a43c12
      case MODE_IMPL:
Packit a43c12
        output_file = "out.c";
Packit a43c12
        break;
Packit a43c12
      case MODE_HEADER:
Packit a43c12
        output_file = "out.h";
Packit a43c12
        break;
Packit a43c12
      case MODE_TEST:
Packit a43c12
        output_file = "out_test.c";
Packit a43c12
        break;
Packit a43c12
      case MODE_ASSEMBLY:
Packit a43c12
        output_file = "out.s";
Packit a43c12
        break;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
Packit a43c12
  code = read_file (input_file);
Packit a43c12
  if (!code) {
Packit a43c12
    printf("Could not read input file: %s\n", input_file);
Packit a43c12
    exit(1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  n = orc_parse_full (code, &programs, &log;;
Packit a43c12
  free(code);
Packit a43c12
  n_programs = n;
Packit a43c12
  printf("%s", log);
Packit a43c12
  free(log);
Packit a43c12
Packit a43c12
  if (programs == NULL) {
Packit a43c12
    printf("no programs\n");
Packit a43c12
    exit(1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (init_function == NULL) {
Packit a43c12
    init_function = orc_parse_get_init_function (programs[0]);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (init_function == NULL) {
Packit a43c12
    use_lazy_init = TRUE;
Packit a43c12
  }
Packit a43c12
Packit a43c12
  output = fopen (output_file, "w");
Packit a43c12
  if (!output) {
Packit a43c12
    printf("Could not write output file: %s\n", output_file);
Packit a43c12
    exit(1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  fprintf(output, "/* autogenerated from %s */\n", my_basename(input_file));
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
  if (mode == MODE_IMPL) {
Packit a43c12
    fprintf(output, "#ifdef HAVE_CONFIG_H\n");
Packit a43c12
    fprintf(output, "#include \"config.h\"\n");
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
    if (include_file) {
Packit a43c12
      fprintf(output, "#include <%s>\n", include_file);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "%s", orc_target_c_get_typedefs ());
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "#ifndef DISABLE_ORC\n");
Packit a43c12
    fprintf(output, "#include <orc/orc.h>\n");
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
    for(i=0;i
Packit a43c12
      output_code_header (programs[i], output);
Packit a43c12
    }
Packit a43c12
    if (init_function) {
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      fprintf(output, "void %s (void);\n", init_function);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "%s", orc_target_get_asm_preamble ("c"));
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    for(i=0;i
Packit a43c12
      output_code (programs[i], output);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (init_function) {
Packit a43c12
      output_init_function (output);
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
    }
Packit a43c12
  } else if (mode == MODE_HEADER) {
Packit a43c12
    char *barrier = get_barrier (output_file);
Packit a43c12
Packit a43c12
    fprintf(output, "#ifndef _%s_\n", barrier);
Packit a43c12
    fprintf(output, "#define _%s_\n", barrier);
Packit a43c12
    free (barrier);
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (include_file) {
Packit a43c12
      fprintf(output, "#include <%s>\n", include_file);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "#ifdef __cplusplus\n");
Packit a43c12
    fprintf(output, "extern \"C\" {\n");
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (init_function) {
Packit a43c12
      fprintf(output, "void %s (void);\n", init_function);
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (!use_inline) {
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      fprintf(output, "%s", orc_target_c_get_typedefs ());
Packit a43c12
      for(i=0;i
Packit a43c12
        output_code_header (programs[i], output);
Packit a43c12
      }
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      fprintf(output, "#include <orc/orc.h>\n");
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      for(i=0;i
Packit a43c12
        output_code_execute (programs[i], output, TRUE);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "#ifdef __cplusplus\n");
Packit a43c12
    fprintf(output, "}\n");
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
  } else if (mode == MODE_TEST) {
Packit a43c12
    fprintf(output, "#include <stdio.h>\n");
Packit a43c12
    fprintf(output, "#include <string.h>\n");
Packit a43c12
    fprintf(output, "#include <stdlib.h>\n");
Packit a43c12
    fprintf(output, "#include <math.h>\n");
Packit a43c12
    if (include_file) {
Packit a43c12
      fprintf(output, "#include <%s>\n", include_file);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "%s", orc_target_c_get_typedefs ());
Packit a43c12
    fprintf(output, "#include <orc/orc.h>\n");
Packit a43c12
    fprintf(output, "#include <orc-test/orctest.h>\n");
Packit a43c12
    fprintf(output, "%s", orc_target_get_asm_preamble ("c"));
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (use_backup) {
Packit a43c12
      for(i=0;i
Packit a43c12
        fprintf(output, "/* %s */\n", programs[i]->name);
Packit a43c12
        output_code_backup (programs[i], output);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "static int quiet = 0;\n");
Packit a43c12
    fprintf(output, "static int benchmark = 0;\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "static void help (const char *argv0)\n");
Packit a43c12
    fprintf(output, "{\n");
Packit a43c12
    fprintf(output, "  printf(\"Usage:\\n\");\n");
Packit a43c12
    fprintf(output, "  printf(\"  %%s [OPTION]\\n\", argv0);\n");
Packit a43c12
    fprintf(output, "  printf(\"Help Options:\\n\");\n");
Packit a43c12
    fprintf(output, "  printf(\"  -h, --help          Show help options\\n\");\n");
Packit a43c12
    fprintf(output, "  printf(\"Application Options:\\n\");\n");
Packit a43c12
    fprintf(output, "  printf(\"  -b, --benchmark     Run benchmark and show results\\n\");\n");
Packit a43c12
    fprintf(output, "  printf(\"  -q, --quiet         Don't output anything except on failures\\n\");\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "  exit(0);\n");
Packit a43c12
    fprintf(output, "}\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "int\n");
Packit a43c12
    fprintf(output, "main (int argc, char *argv[])\n");
Packit a43c12
    fprintf(output, "{\n");
Packit a43c12
    fprintf(output, "  int error = FALSE;\n");
Packit a43c12
    fprintf(output, "  int i;\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "  orc_test_init ();\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "  for(i=1;i
Packit a43c12
    fprintf(output, "    if (strcmp(argv[i], \"--help\") == 0 ||\n");
Packit a43c12
    fprintf(output, "      strcmp(argv[i], \"-h\") == 0) {\n");
Packit a43c12
    fprintf(output, "      help(argv[0]);\n");
Packit a43c12
    fprintf(output, "    } else if (strcmp(argv[i], \"--quiet\") == 0 ||\n");
Packit a43c12
    fprintf(output, "      strcmp(argv[i], \"-q\") == 0) {\n");
Packit a43c12
    fprintf(output, "      quiet = 1;\n");
Packit a43c12
    fprintf(output, "      benchmark = 0;\n");
Packit a43c12
    fprintf(output, "    } else if (strcmp(argv[i], \"--benchmark\") == 0 ||\n");
Packit a43c12
    fprintf(output, "      strcmp(argv[i], \"-b\") == 0) {\n");
Packit a43c12
    fprintf(output, "      benchmark = 1;\n");
Packit a43c12
    fprintf(output, "      quiet = 0;\n");
Packit a43c12
    fprintf(output, "    }\n");
Packit a43c12
    fprintf(output, "  }\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    for(i=0;i
Packit a43c12
      output_code_test (programs[i], output);
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "  if (error) {\n");
Packit a43c12
    fprintf(output, "    return 1;\n");
Packit a43c12
    fprintf(output, "  };\n");
Packit a43c12
    fprintf(output, "  return 0;\n");
Packit a43c12
    fprintf(output, "}\n");
Packit a43c12
  } else if (mode == MODE_ASSEMBLY) {
Packit a43c12
    fprintf(output, "%s", orc_target_get_asm_preamble (target));
Packit a43c12
    for(i=0;i
Packit a43c12
      output_code_assembly (programs[i], output);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
Packit a43c12
  for(i=0;i
Packit a43c12
    orc_program_free(programs[i]);
Packit a43c12
  }
Packit a43c12
  free(programs);
Packit a43c12
Packit a43c12
  fclose (output);
Packit a43c12
Packit a43c12
  if (error) {
Packit a43c12
    remove (output_file);
Packit a43c12
    exit(1);
Packit a43c12
  }
Packit a43c12
Packit a43c12
  return 0;
Packit a43c12
}
Packit a43c12
Packit a43c12
Packit a43c12
static char *
Packit a43c12
get_barrier (const char *s)
Packit a43c12
{
Packit a43c12
  char *barrier;
Packit a43c12
  int n;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  n = strlen(s);
Packit a43c12
  barrier = malloc (n + 1);
Packit a43c12
  for(i=0;i
Packit a43c12
    if (isalnum (s[i])) {
Packit a43c12
      barrier[i] = toupper(s[i]);
Packit a43c12
    } else {
Packit a43c12
      barrier[i] = '_';
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  barrier[n] = 0;
Packit a43c12
Packit a43c12
  return barrier;
Packit a43c12
}
Packit a43c12
Packit a43c12
static char *
Packit a43c12
read_file (const char *filename)
Packit a43c12
{
Packit a43c12
  FILE *file = NULL;
Packit a43c12
  char *contents = NULL;
Packit a43c12
  long size;
Packit a43c12
  int ret;
Packit a43c12
Packit a43c12
  file = fopen (filename, "rb");
Packit a43c12
  if (file == NULL) return NULL;
Packit a43c12
Packit a43c12
  ret = fseek (file, 0, SEEK_END);
Packit a43c12
  if (ret < 0) goto bail;
Packit a43c12
Packit a43c12
  size = ftell (file);
Packit a43c12
  if (size < 0) goto bail;
Packit a43c12
Packit a43c12
  ret = fseek (file, 0, SEEK_SET);
Packit a43c12
  if (ret < 0) goto bail;
Packit a43c12
Packit a43c12
  contents = malloc (size + 1);
Packit a43c12
  if (contents == NULL) goto bail;
Packit a43c12
Packit a43c12
  ret = fread (contents, size, 1, file);
Packit a43c12
  if (ret < 0) goto bail;
Packit a43c12
Packit a43c12
  contents[size] = 0;
Packit a43c12
Packit a43c12
  fclose (file);
Packit a43c12
Packit a43c12
  return contents;
Packit a43c12
bail:
Packit a43c12
  /* something failed */
Packit a43c12
  if (file) fclose (file);
Packit a43c12
  if (contents) free (contents);
Packit a43c12
Packit a43c12
  return NULL;
Packit a43c12
}
Packit a43c12
Packit a43c12
const char *varnames[] = {
Packit a43c12
  "d1", "d2", "d3", "d4",
Packit a43c12
  "s1", "s2", "s3", "s4",
Packit a43c12
  "s5", "s6", "s7", "s8",
Packit a43c12
  "a1", "a2", "a3", "d4",
Packit a43c12
  "c1", "c2", "c3", "c4",
Packit a43c12
  "c5", "c6", "c7", "c8",
Packit a43c12
  "p1", "p2", "p3", "p4",
Packit a43c12
  "p5", "p6", "p7", "p8",
Packit a43c12
  "t1", "t2", "t3", "t4",
Packit a43c12
  "t5", "t6", "t7", "t8",
Packit a43c12
  "t9", "t10", "t11", "t12",
Packit a43c12
  "t13", "t14", "t15", "t16"
Packit a43c12
};
Packit a43c12
Packit a43c12
const char *enumnames[] = {
Packit a43c12
  "ORC_VAR_D1", "ORC_VAR_D2", "ORC_VAR_D3", "ORC_VAR_D4",
Packit a43c12
  "ORC_VAR_S1", "ORC_VAR_S2", "ORC_VAR_S3", "ORC_VAR_S4",
Packit a43c12
  "ORC_VAR_S5", "ORC_VAR_S6", "ORC_VAR_S7", "ORC_VAR_S8",
Packit a43c12
  "ORC_VAR_A1", "ORC_VAR_A2", "ORC_VAR_A3", "ORC_VAR_A4",
Packit a43c12
  "ORC_VAR_C1", "ORC_VAR_C2", "ORC_VAR_C3", "ORC_VAR_C4",
Packit a43c12
  "ORC_VAR_C5", "ORC_VAR_C6", "ORC_VAR_C7", "ORC_VAR_C8",
Packit a43c12
  "ORC_VAR_P1", "ORC_VAR_P2", "ORC_VAR_P3", "ORC_VAR_P4",
Packit a43c12
  "ORC_VAR_P5", "ORC_VAR_P6", "ORC_VAR_P7", "ORC_VAR_P8",
Packit a43c12
  "ORC_VAR_T1", "ORC_VAR_T2", "ORC_VAR_T3", "ORC_VAR_T4",
Packit a43c12
  "ORC_VAR_T5", "ORC_VAR_T6", "ORC_VAR_T7", "ORC_VAR_T8",
Packit a43c12
  "ORC_VAR_T9", "ORC_VAR_T10", "ORC_VAR_T11", "ORC_VAR_T12",
Packit a43c12
  "ORC_VAR_T13", "ORC_VAR_T14", "ORC_VAR_T15",
Packit a43c12
  /* ORC_VAR_T16 is a special case because it didn't exist in
Packit a43c12
     the API until 0.4.8 */
Packit a43c12
  "47"
Packit a43c12
};
Packit a43c12
Packit a43c12
static const char *orcify_typename (const char *s)
Packit a43c12
{
Packit a43c12
  if (strcmp (s, "int8_t") == 0) return "orc_int8";
Packit a43c12
  if (strcmp (s, "int16_t") == 0) return "orc_int16";
Packit a43c12
  if (strcmp (s, "int32_t") == 0) return "orc_int32";
Packit a43c12
  if (strcmp (s, "int64_t") == 0) return "orc_int64";
Packit a43c12
  if (strcmp (s, "uint8_t") == 0) return "orc_uint8";
Packit a43c12
  if (strcmp (s, "uint16_t") == 0) return "orc_uint16";
Packit a43c12
  if (strcmp (s, "uint32_t") == 0) return "orc_uint32";
Packit a43c12
  if (strcmp (s, "uint64_t") == 0) return "orc_uint64";
Packit a43c12
  return s;
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_prototype (OrcProgram *p, FILE *output, int backup)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
  int need_comma;
Packit a43c12
Packit a43c12
  fprintf(output, "%s (", backup ? p->backup_name : p->name);
Packit a43c12
  need_comma = FALSE;
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (need_comma) fprintf(output, ", ");
Packit a43c12
      if (var->type_name) {
Packit a43c12
        fprintf(output, "%s * ORC_RESTRICT %s", orcify_typename(var->type_name),
Packit a43c12
            varnames[ORC_VAR_D1 + i]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "orc_uint%d * ORC_RESTRICT %s", var->size*8,
Packit a43c12
            varnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, ", int %s_stride", varnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
      need_comma = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_A1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (need_comma) fprintf(output, ", ");
Packit a43c12
      if (var->type_name) {
Packit a43c12
        fprintf(output, "%s * ORC_RESTRICT %s", orcify_typename(var->type_name),
Packit a43c12
            varnames[ORC_VAR_A1 + i]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "orc_uint%d * ORC_RESTRICT %s", var->size*8,
Packit a43c12
            varnames[ORC_VAR_A1 + i]);
Packit a43c12
      }
Packit a43c12
      need_comma = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (need_comma) fprintf(output, ", ");
Packit a43c12
      if (var->type_name) {
Packit a43c12
        fprintf(output, "const %s * ORC_RESTRICT %s",
Packit a43c12
            orcify_typename(var->type_name),
Packit a43c12
            varnames[ORC_VAR_S1 + i]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "const orc_uint%d * ORC_RESTRICT %s", var->size*8,
Packit a43c12
            varnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, ", int %s_stride", varnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
      need_comma = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (need_comma) fprintf(output, ", ");
Packit a43c12
      switch (var->param_type) {
Packit a43c12
        case ORC_PARAM_TYPE_INT:
Packit a43c12
          fprintf(output, "int %s", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_FLOAT:
Packit a43c12
          REQUIRE(0,4,5,1);
Packit a43c12
          fprintf(output, "float %s", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_INT64:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          fprintf(output, "orc_int64 %s", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_DOUBLE:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          fprintf(output, "double %s", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        default:
Packit a43c12
          ORC_ASSERT(0);
Packit a43c12
      }
Packit a43c12
      need_comma = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  if (p->constant_n == 0) {
Packit a43c12
    if (need_comma) fprintf(output, ", ");
Packit a43c12
    fprintf(output, "int n");
Packit a43c12
    need_comma = TRUE;
Packit a43c12
  }
Packit a43c12
  if (p->is_2d && p->constant_m == 0) {
Packit a43c12
    if (need_comma) fprintf(output, ", ");
Packit a43c12
    fprintf(output, "int m");
Packit a43c12
  }
Packit a43c12
  fprintf(output, ")");
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_executor_backup_call (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  fprintf(output, "  %s (", p->backup_name);
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "ex->arrays[%s], ", enumnames[ORC_VAR_D1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "ex->params[%s], ", enumnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "ex->arrays[%s], ", enumnames[ORC_VAR_S1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "  ex->params[%s], ", enumnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      switch (var->param_type) {
Packit a43c12
        case ORC_PARAM_TYPE_INT:
Packit a43c12
          fprintf(output, "ex->params[%s],", enumnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_FLOAT:
Packit a43c12
          fprintf(output, "((orc_union32 * )&ex->params[%s])->f, ",
Packit a43c12
              enumnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_INT64:
Packit a43c12
          fprintf(output, "(ex->params[%s] & 0xffffffff) | ((orc_uint64)(ex->params[%s]) << 32), ", enumnames[ORC_VAR_P1 + i], enumnames[ORC_VAR_T1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_DOUBLE:
Packit a43c12
          /* FIXME */
Packit a43c12
          break;
Packit a43c12
        default:
Packit a43c12
          ORC_ASSERT(0);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  if (p->constant_n) {
Packit a43c12
    fprintf(output, "%d", p->constant_n);
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "ex->n");
Packit a43c12
  }
Packit a43c12
  if (p->is_2d) {
Packit a43c12
    if (p->constant_m) {
Packit a43c12
      fprintf(output, ",  %d", p->constant_m);
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, ", ORC_EXECUTOR_M(ex)");
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, ");\n");
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_backup_call (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  fprintf(output, "  %s (", p->backup_name);
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "%s, ", varnames[ORC_VAR_D1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "%s_stride, ", varnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "%s, ", varnames[ORC_VAR_S1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "%s_stride, ", varnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
        fprintf(output, "%s, ", varnames[ORC_VAR_P1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  if (p->constant_n) {
Packit a43c12
    fprintf(output, "%d", p->constant_n);
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "n");
Packit a43c12
  }
Packit a43c12
  if (p->is_2d) {
Packit a43c12
    if (p->constant_m) {
Packit a43c12
      fprintf(output, ", %d", p->constant_m);
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, ", m");
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, ");\n");
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_header (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
  if(use_internal) {
Packit a43c12
    fprintf(output, "ORC_INTERNAL void ");
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "void ");
Packit a43c12
  }
Packit a43c12
  output_prototype (p, output, 0);
Packit a43c12
  fprintf(output, ";\n");
Packit a43c12
  if (p->backup_name && mode != MODE_TEST) {
Packit a43c12
    fprintf(output, "void ");
Packit a43c12
    output_prototype (p, output, 1);
Packit a43c12
    fprintf(output, ";\n");
Packit a43c12
  }
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_backup (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
Packit a43c12
  fprintf(output, "static void\n");
Packit a43c12
  if (compat < ORC_VERSION(0,4,7,1)) {
Packit a43c12
    fprintf(output, "_backup_%s (OrcExecutor * ex)\n", p->name);
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "_backup_%s (OrcExecutor * ORC_RESTRICT ex)\n", p->name);
Packit a43c12
  }
Packit a43c12
  fprintf(output, "{\n");
Packit a43c12
  if (p->backup_name && mode != MODE_TEST) {
Packit a43c12
    output_executor_backup_call (p, output);
Packit a43c12
  } else {
Packit a43c12
    OrcCompileResult result;
Packit a43c12
Packit a43c12
    result = orc_program_compile_full (p, orc_target_get_by_name("c"),
Packit a43c12
        ORC_TARGET_C_BARE);
Packit a43c12
    if (ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
Packit a43c12
      fprintf(output, "%s\n", orc_program_get_asm_code (p));
Packit a43c12
    } else {
Packit a43c12
      printf("Failed to compile backup code for '%s'\n", p->name);
Packit a43c12
      error = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "}\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_no_orc (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
Packit a43c12
  fprintf(output, "void\n");
Packit a43c12
  output_prototype (p, output, 0);
Packit a43c12
  fprintf(output, "{\n");
Packit a43c12
  if (p->backup_name && mode != MODE_TEST) {
Packit a43c12
    output_backup_call (p, output);
Packit a43c12
  } else {
Packit a43c12
    OrcCompileResult result;
Packit a43c12
Packit a43c12
    result = orc_program_compile_full (p, orc_target_get_by_name("c"),
Packit a43c12
        ORC_TARGET_C_BARE | ORC_TARGET_C_NOEXEC);
Packit a43c12
    if (ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
Packit a43c12
      fprintf(output, "%s\n", orc_program_get_asm_code (p));
Packit a43c12
    } else {
Packit a43c12
      printf("Failed to compile no orc for '%s'\n", p->name);
Packit a43c12
      error = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "}\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  fprintf(output, "/* %s */\n", p->name);
Packit a43c12
  fprintf(output, "#ifdef DISABLE_ORC\n");
Packit a43c12
  output_code_no_orc (p, output);
Packit a43c12
  fprintf(output, "#else\n");
Packit a43c12
  if (use_backup) {
Packit a43c12
    output_code_backup (p, output);
Packit a43c12
  }
Packit a43c12
  output_code_execute (p, output, FALSE);
Packit a43c12
  fprintf(output, "#endif\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_execute (OrcProgram *p, FILE *output, int is_inline)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  if (!use_lazy_init) {
Packit a43c12
    const char *storage;
Packit a43c12
    if (is_inline) {
Packit a43c12
      storage = "extern ";
Packit a43c12
    } else {
Packit a43c12
      if (use_inline) {
Packit a43c12
        storage = "";
Packit a43c12
      } else {
Packit a43c12
        storage = "static ";
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
    if (use_code) {
Packit a43c12
      fprintf(output, "%sOrcCode *_orc_code_%s;\n", storage, p->name);
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, "%sOrcProgram *_orc_program_%s;\n", storage, p->name);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  if (is_inline) {
Packit a43c12
    fprintf(output, "static inline void\n");
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "void\n");
Packit a43c12
  }
Packit a43c12
  output_prototype (p, output, 0);
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  fprintf(output, "{\n");
Packit a43c12
  fprintf(output, "  OrcExecutor _ex, *ex = &_ex;\n");
Packit a43c12
  if (!use_lazy_init) {
Packit a43c12
    if (use_code) {
Packit a43c12
      fprintf(output, "  OrcCode *c = _orc_code_%s;\n", p->name);
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, "  OrcProgram *p = _orc_program_%s;\n", p->name);
Packit a43c12
    }
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "  static volatile int p_inited = 0;\n");
Packit a43c12
    if (use_code) {
Packit a43c12
      fprintf(output, "  static OrcCode *c = 0;\n");
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, "  static OrcProgram *p = 0;\n");
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "  void (*func) (OrcExecutor *);\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  if (use_lazy_init) {
Packit a43c12
    fprintf(output, "  if (!p_inited) {\n");
Packit a43c12
    fprintf(output, "    orc_once_mutex_lock ();\n");
Packit a43c12
    fprintf(output, "    if (!p_inited) {\n");
Packit a43c12
    if (use_code) {
Packit a43c12
      fprintf(output, "      OrcProgram *p;\n");
Packit a43c12
    }
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    output_program_generation (p, output, is_inline);
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    fprintf(output, "      orc_program_compile (p);\n");
Packit a43c12
    if (use_code) {
Packit a43c12
      fprintf(output, "      c = orc_program_take_code (p);\n");
Packit a43c12
      fprintf(output, "      orc_program_free (p);\n");
Packit a43c12
    }
Packit a43c12
    fprintf(output, "    }\n");
Packit a43c12
    fprintf(output, "    p_inited = TRUE;\n");
Packit a43c12
    fprintf(output, "    orc_once_mutex_unlock ();\n");
Packit a43c12
    fprintf(output, "  }\n");
Packit a43c12
  }
Packit a43c12
  if (use_code) {
Packit a43c12
    fprintf(output, "  ex->arrays[ORC_VAR_A2] = c;\n");
Packit a43c12
    fprintf(output, "  ex->program = 0;\n");
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "  ex->program = p;\n");
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  if (p->constant_n) {
Packit a43c12
    fprintf(output, "  ex->n = %d;\n", p->constant_n);
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "  ex->n = n;\n");
Packit a43c12
  }
Packit a43c12
  if (p->is_2d) {
Packit a43c12
    if (p->constant_m) {
Packit a43c12
      fprintf(output, "  ORC_EXECUTOR_M(ex) = %d;\n", p->constant_m);
Packit a43c12
    } else {
Packit a43c12
      fprintf(output, "  ORC_EXECUTOR_M(ex) = m;\n");
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "  ex->arrays[%s] = %s;\n",
Packit a43c12
          enumnames[ORC_VAR_D1 + i], varnames[ORC_VAR_D1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "  ex->params[%s] = %s_stride;\n",
Packit a43c12
            enumnames[ORC_VAR_D1 + i], varnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "  ex->arrays[%s] = (void *)%s;\n",
Packit a43c12
          enumnames[ORC_VAR_S1 + i], varnames[ORC_VAR_S1 + i]);
Packit a43c12
      if (p->is_2d) {
Packit a43c12
        fprintf(output, "  ex->params[%s] = %s_stride;\n",
Packit a43c12
            enumnames[ORC_VAR_S1 + i], varnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      switch (var->param_type) {
Packit a43c12
        case ORC_PARAM_TYPE_INT:
Packit a43c12
          fprintf(output, "  ex->params[%s] = %s;\n",
Packit a43c12
              enumnames[ORC_VAR_P1 + i], varnames[ORC_VAR_P1 + i]);
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_FLOAT:
Packit a43c12
          REQUIRE(0,4,5,1);
Packit a43c12
          fprintf(output, "  {\n");
Packit a43c12
          fprintf(output, "    orc_union32 tmp;\n");
Packit a43c12
          fprintf(output, "    tmp.f = %s;\n", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "    ex->params[%s] = tmp.i;\n",
Packit a43c12
              enumnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "  }\n");
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_INT64:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          fprintf(output, "  {\n");
Packit a43c12
          fprintf(output, "    orc_union64 tmp;\n");
Packit a43c12
          fprintf(output, "    tmp.i = %s;\n", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) & 0xffffffff;\n",
Packit a43c12
              enumnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) >> 32;\n",
Packit a43c12
              enumnames[ORC_VAR_T1 + i]);
Packit a43c12
          fprintf(output, "  }\n");
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_DOUBLE:
Packit a43c12
          REQUIRE(0,4,5,1);
Packit a43c12
          fprintf(output, "  {\n");
Packit a43c12
          fprintf(output, "    orc_union64 tmp;\n");
Packit a43c12
          fprintf(output, "    tmp.f = %s;\n", varnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) & 0xffffffff;\n",
Packit a43c12
              enumnames[ORC_VAR_P1 + i]);
Packit a43c12
          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) >> 32;\n",
Packit a43c12
              enumnames[ORC_VAR_T1 + i]);
Packit a43c12
          fprintf(output, "  }\n");
Packit a43c12
          break;
Packit a43c12
        default:
Packit a43c12
          ORC_ASSERT(0);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  if (use_code) {
Packit a43c12
    fprintf(output, "  func = c->exec;\n");
Packit a43c12
  } else {
Packit a43c12
    fprintf(output, "  func = p->code_exec;\n");
Packit a43c12
  }
Packit a43c12
  fprintf(output, "  func (ex);\n");
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_A1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "  *%s = orc_executor_get_accumulator (ex, %s);\n",
Packit a43c12
          varnames[ORC_VAR_A1 + i], enumnames[ORC_VAR_A1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "}\n");
Packit a43c12
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_program_generation (OrcProgram *p, FILE *output, int is_inline)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  if (ORC_VERSION(0,4,16,1) <= compat) {
Packit a43c12
    OrcBytecode *bytecode;
Packit a43c12
    int i;
Packit a43c12
Packit a43c12
    bytecode = orc_bytecode_from_program (p);
Packit a43c12
Packit a43c12
    fprintf(output, "#if 1\n");
Packit a43c12
    /* fprintf(output, "#ifdef bytecode\n"); */
Packit a43c12
    fprintf(output, "      static const orc_uint8 bc[] = {\n");
Packit a43c12
    for(i=0;i<bytecode->length;i++) {
Packit a43c12
      if ((i&0xf) == 0) {
Packit a43c12
        fprintf(output, "        ");
Packit a43c12
      }
Packit a43c12
      fprintf(output, "%d, ", bytecode->bytecode[i]);
Packit a43c12
      if ((i&0xf) == 15) {
Packit a43c12
        fprintf(output, "\n");
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
    if ((i&0xf) != 15) {
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
    }
Packit a43c12
    fprintf(output, "      };\n");
Packit a43c12
    fprintf(output, "      p = orc_program_new_from_static_bytecode (bc);\n");
Packit a43c12
    /* fprintf(output, "     orc_program_set_name (p, \"%s\");\n", p->name); */
Packit a43c12
    if (use_backup && !is_inline) {
Packit a43c12
      fprintf(output, "      orc_program_set_backup_function (p, _backup_%s);\n",
Packit a43c12
          p->name);
Packit a43c12
    }
Packit a43c12
Packit a43c12
#if 0
Packit a43c12
    /* CHECK */
Packit a43c12
    {
Packit a43c12
      OrcProgram *p2 = orc_program_new_from_static_bytecode (bytecode->bytecode);
Packit a43c12
      OrcBytecode *bytecode2 = bytecode2 = orc_bytecode_from_program (p2);
Packit a43c12
Packit a43c12
      fprintf(output, "#ifdef badbytecode\n");
Packit a43c12
      fprintf(output, "    static const orc_uint8 bc[] = {\n");
Packit a43c12
      for(i=0;i<bytecode2->length;i++) {
Packit a43c12
        if ((i&0xf) == 0) {
Packit a43c12
          fprintf(output, "      ");
Packit a43c12
        }
Packit a43c12
        fprintf(output, "%s%d, ",
Packit a43c12
            (bytecode->bytecode[i] == bytecode2->bytecode[i]) ? "" : "/* */",
Packit a43c12
            bytecode2->bytecode[i]);
Packit a43c12
        if ((i&0xf) == 15) {
Packit a43c12
          fprintf(output, "\n");
Packit a43c12
        }
Packit a43c12
      }
Packit a43c12
      if ((i&0xf) != 15) {
Packit a43c12
        fprintf(output, "\n");
Packit a43c12
      }
Packit a43c12
      fprintf(output, "    };\n");
Packit a43c12
      fprintf(output, "#endif\n");
Packit a43c12
    }
Packit a43c12
#endif
Packit a43c12
Packit a43c12
    orc_bytecode_free (bytecode);
Packit a43c12
Packit a43c12
    fprintf(output, "#else\n");
Packit a43c12
  }
Packit a43c12
Packit a43c12
  fprintf(output, "      p = orc_program_new ();\n");
Packit a43c12
  if (p->constant_n != 0) {
Packit a43c12
    fprintf(output, "      orc_program_set_constant_n (p, %d);\n",
Packit a43c12
        p->constant_n);
Packit a43c12
  }
Packit a43c12
  if (p->n_multiple != 0) {
Packit a43c12
    REQUIRE(0,4,14,1);
Packit a43c12
    fprintf(output, "      orc_program_set_n_multiple (p, %d);\n",
Packit a43c12
        p->n_multiple);
Packit a43c12
  }
Packit a43c12
  if (p->n_minimum != 0) {
Packit a43c12
    REQUIRE(0,4,14,1);
Packit a43c12
    fprintf(output, "      orc_program_set_n_minimum (p, %d);\n",
Packit a43c12
        p->n_minimum);
Packit a43c12
  }
Packit a43c12
  if (p->n_maximum != 0) {
Packit a43c12
    REQUIRE(0,4,14,1);
Packit a43c12
    fprintf(output, "      orc_program_set_n_maximum (p, %d);\n",
Packit a43c12
        p->n_maximum);
Packit a43c12
  }
Packit a43c12
  if (p->is_2d) {
Packit a43c12
    fprintf(output, "      orc_program_set_2d (p);\n");
Packit a43c12
    if (p->constant_m != 0) {
Packit a43c12
      fprintf(output, "      orc_program_set_constant_m (p, %d);\n",
Packit a43c12
          p->constant_m);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "      orc_program_set_name (p, \"%s\");\n", p->name);
Packit a43c12
  if (use_backup && !is_inline) {
Packit a43c12
    fprintf(output, "      orc_program_set_backup_function (p, _backup_%s);\n",
Packit a43c12
        p->name);
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (var->alignment != var->size) {
Packit a43c12
        REQUIRE(0,4,14,1);
Packit a43c12
        fprintf(output, "      orc_program_add_destination_full (p, %d, \"%s\", 0, %d);\n",
Packit a43c12
            var->size, varnames[ORC_VAR_D1 + i], var->alignment);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "      orc_program_add_destination (p, %d, \"%s\");\n",
Packit a43c12
            var->size, varnames[ORC_VAR_D1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (var->alignment != var->size) {
Packit a43c12
        REQUIRE(0,4,14,1);
Packit a43c12
        fprintf(output, "      orc_program_add_source_full (p, %d, \"%s\", 0, %d);\n",
Packit a43c12
            var->size, varnames[ORC_VAR_S1 + i],
Packit a43c12
            var->alignment);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "      orc_program_add_source (p, %d, \"%s\");\n",
Packit a43c12
            var->size, varnames[ORC_VAR_S1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_A1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "      orc_program_add_accumulator (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_A1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_C1 + i];
Packit a43c12
    if (var->size == 0) continue;
Packit a43c12
    if (var->size <= 4) {
Packit a43c12
      fprintf(output, "      orc_program_add_constant (p, %d, 0x%08x, \"%s\");\n",
Packit a43c12
          var->size, (int)var->value.i, varnames[ORC_VAR_C1 + i]);
Packit a43c12
    } else if (var->size > 4) {
Packit a43c12
      REQUIRE(0,4,8,1);
Packit a43c12
      fprintf(output, "      orc_program_add_constant_int64 (p, %d, 0x%08x%08xULL, \"%s\");\n",
Packit a43c12
          var->size, (orc_uint32)(((orc_uint64)var->value.i)>>32),
Packit a43c12
          (orc_uint32)(var->value.i), varnames[ORC_VAR_C1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      const char *suffix = NULL;
Packit a43c12
      switch (var->param_type) {
Packit a43c12
        case ORC_PARAM_TYPE_INT:
Packit a43c12
          suffix="";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_FLOAT:
Packit a43c12
          REQUIRE(0,4,5,1);
Packit a43c12
          suffix="_float";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_INT64:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          suffix="_int64";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_DOUBLE:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          suffix="_double";
Packit a43c12
          break;
Packit a43c12
        default:
Packit a43c12
          ORC_ASSERT(0);
Packit a43c12
      }
Packit a43c12
      fprintf(output, "      orc_program_add_parameter%s (p, %d, \"%s\");\n",
Packit a43c12
          suffix, var->size, varnames[ORC_VAR_P1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<16;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_T1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "      orc_program_add_temporary (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_T1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
  for(i=0;i<p->n_insns;i++){
Packit a43c12
    OrcInstruction *insn = p->insns + i;
Packit a43c12
Packit a43c12
    if (compat < ORC_VERSION(0,4,6,1)) {
Packit a43c12
      if (insn->flags) {
Packit a43c12
        REQUIRE(0,4,6,1);
Packit a43c12
      }
Packit a43c12
Packit a43c12
      if (p->vars[insn->src_args[1]].size != 0) {
Packit a43c12
        fprintf(output, "      orc_program_append (p, \"%s\", %s, %s, %s);\n",
Packit a43c12
            insn->opcode->name, enumnames[insn->dest_args[0]],
Packit a43c12
            enumnames[insn->src_args[0]], enumnames[insn->src_args[1]]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "      orc_program_append_ds (p, \"%s\", %s, %s);\n",
Packit a43c12
            insn->opcode->name, enumnames[insn->dest_args[0]],
Packit a43c12
            enumnames[insn->src_args[0]]);
Packit a43c12
      }
Packit a43c12
    } else {
Packit a43c12
      int args[4] = { 0, 0, 0, 0 };
Packit a43c12
      int n_args = 0;
Packit a43c12
Packit a43c12
      if (insn->opcode->dest_size[0] != 0) {
Packit a43c12
        args[n_args++] = insn->dest_args[0];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->dest_size[1] != 0) {
Packit a43c12
        args[n_args++] = insn->dest_args[1];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[0] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[0];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[1] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[1];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[2] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[2];
Packit a43c12
      }
Packit a43c12
Packit a43c12
      fprintf(output, "      orc_program_append_2 (p, \"%s\", %d, %s, %s, %s, %s);\n",
Packit a43c12
          insn->opcode->name, insn->flags, enumnames[args[0]],
Packit a43c12
          enumnames[args[1]], enumnames[args[2]],
Packit a43c12
          enumnames[args[3]]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
Packit a43c12
  if (ORC_VERSION(0,4,16,1) <= compat) {
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
  }
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_init_function (FILE *output)
Packit a43c12
{
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  fprintf(output, "void\n");
Packit a43c12
  fprintf(output, "%s (void)\n", init_function);
Packit a43c12
  fprintf(output, "{\n");
Packit a43c12
  if (!use_lazy_init) {
Packit a43c12
    fprintf(output, "#ifndef DISABLE_ORC\n");
Packit a43c12
    for(i=0;i
Packit a43c12
      fprintf(output, "  {\n");
Packit a43c12
      fprintf(output, "    /* %s */\n", programs[i]->name);
Packit a43c12
      fprintf(output, "    OrcProgram *p;\n");
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      output_program_generation (programs[i], output, FALSE);
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      fprintf(output, "    orc_program_compile (p);\n");
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
      if (use_code) {
Packit a43c12
        fprintf(output, "    _orc_code_%s = orc_program_take_code (p);\n",
Packit a43c12
            programs[i]->name);
Packit a43c12
        fprintf(output, "    orc_program_free (p);\n");
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "    _orc_program_%s = p;\n", programs[i]->name);
Packit a43c12
      }
Packit a43c12
      fprintf(output, "  }\n");
Packit a43c12
    }
Packit a43c12
    fprintf(output, "#endif\n");
Packit a43c12
  }
Packit a43c12
  fprintf(output, "}\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_test (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
  OrcVariable *var;
Packit a43c12
  int i;
Packit a43c12
Packit a43c12
  fprintf(output, "  /* %s */\n", p->name);
Packit a43c12
  fprintf(output, "  {\n");
Packit a43c12
  fprintf(output, "    OrcProgram *p = NULL;\n");
Packit a43c12
  fprintf(output, "    int ret;\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  fprintf(output, "    if (!quiet)");
Packit a43c12
  fprintf(output, "      printf (\"%s:\\n\");\n", p->name);
Packit a43c12
  fprintf(output, "    p = orc_program_new ();\n");
Packit a43c12
  if (p->constant_n != 0) {
Packit a43c12
    fprintf(output, "      orc_program_set_constant_n (p, %d);\n",
Packit a43c12
        p->constant_n);
Packit a43c12
  }
Packit a43c12
  if (p->is_2d) {
Packit a43c12
    fprintf(output, "      orc_program_set_2d (p);\n");
Packit a43c12
    if (p->constant_m != 0) {
Packit a43c12
      fprintf(output, "      orc_program_set_constant_m (p, %d);\n",
Packit a43c12
          p->constant_m);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "    orc_program_set_name (p, \"%s\");\n", p->name);
Packit a43c12
  if (use_backup) {
Packit a43c12
    fprintf(output, "    orc_program_set_backup_function (p, _backup_%s);\n",
Packit a43c12
        p->name);
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_D1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "    orc_program_add_destination (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_D1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_S1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "    orc_program_add_source (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_S1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<4;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_A1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "    orc_program_add_accumulator (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_A1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_C1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      if (var->size < 8) {
Packit a43c12
	fprintf(output, "      orc_program_add_constant (p, %d, 0x%08x, \"%s\");\n",
Packit a43c12
	    var->size, (int)var->value.i, varnames[ORC_VAR_C1 + i]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "      orc_program_add_constant_int64 (p, %d, "
Packit a43c12
            "0x%08x%08xULL, \"%s\");\n",
Packit a43c12
            var->size, (orc_uint32)(((orc_uint64)var->value.i)>>32),
Packit a43c12
            (orc_uint32)(var->value.i), varnames[ORC_VAR_C1 + i]);
Packit a43c12
      }
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<8;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_P1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      const char *suffix = NULL;
Packit a43c12
      switch (var->param_type) {
Packit a43c12
        case ORC_PARAM_TYPE_INT:
Packit a43c12
          suffix="";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_FLOAT:
Packit a43c12
          REQUIRE(0,4,5,1);
Packit a43c12
          suffix="_float";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_INT64:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          suffix="_int64";
Packit a43c12
          break;
Packit a43c12
        case ORC_PARAM_TYPE_DOUBLE:
Packit a43c12
          REQUIRE(0,4,7,1);
Packit a43c12
          suffix="_double";
Packit a43c12
          break;
Packit a43c12
        default:
Packit a43c12
          ORC_ASSERT(0);
Packit a43c12
      }
Packit a43c12
      fprintf(output, "    orc_program_add_parameter%s (p, %d, \"%s\");\n",
Packit a43c12
          suffix, var->size, varnames[ORC_VAR_P1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  for(i=0;i<16;i++){
Packit a43c12
    var = &p->vars[ORC_VAR_T1 + i];
Packit a43c12
    if (var->size) {
Packit a43c12
      fprintf(output, "    orc_program_add_temporary (p, %d, \"%s\");\n",
Packit a43c12
          var->size, varnames[ORC_VAR_T1 + i]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
  for(i=0;i<p->n_insns;i++){
Packit a43c12
    OrcInstruction *insn = p->insns + i;
Packit a43c12
    if (compat < ORC_VERSION(0,4,6,1)) {
Packit a43c12
      if (insn->flags) {
Packit a43c12
        REQUIRE(0,4,6,1);
Packit a43c12
      }
Packit a43c12
Packit a43c12
      if (p->vars[insn->src_args[1]].size != 0) {
Packit a43c12
        fprintf(output, "      orc_program_append (p, \"%s\", %s, %s, %s);\n",
Packit a43c12
            insn->opcode->name, enumnames[insn->dest_args[0]],
Packit a43c12
            enumnames[insn->src_args[0]], enumnames[insn->src_args[1]]);
Packit a43c12
      } else {
Packit a43c12
        fprintf(output, "      orc_program_append_ds (p, \"%s\", %s, %s);\n",
Packit a43c12
            insn->opcode->name, enumnames[insn->dest_args[0]],
Packit a43c12
            enumnames[insn->src_args[0]]);
Packit a43c12
      }
Packit a43c12
    } else {
Packit a43c12
      int args[4] = { 0, 0, 0, 0 };
Packit a43c12
      int n_args = 0;
Packit a43c12
Packit a43c12
      if (insn->opcode->dest_size[0] != 0) {
Packit a43c12
        args[n_args++] = insn->dest_args[0];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->dest_size[1] != 0) {
Packit a43c12
        args[n_args++] = insn->dest_args[1];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[0] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[0];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[1] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[1];
Packit a43c12
      }
Packit a43c12
      if (insn->opcode->src_size[2] != 0) {
Packit a43c12
        args[n_args++] = insn->src_args[2];
Packit a43c12
      }
Packit a43c12
Packit a43c12
      fprintf(output, "      orc_program_append_2 (p, \"%s\", %d, %s, %s, %s, %s);\n",
Packit a43c12
          insn->opcode->name, insn->flags, enumnames[args[0]],
Packit a43c12
          enumnames[args[1]], enumnames[args[2]],
Packit a43c12
          enumnames[args[3]]);
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  if (compat >= ORC_VERSION(0,4,7,1)) {
Packit a43c12
    fprintf(output, "    if (benchmark) {\n");
Packit a43c12
    fprintf(output, "      printf (\"    cycles (emulate) :   %%g\\n\",\n");
Packit a43c12
    fprintf(output, "          orc_test_performance_full (p, ORC_TEST_FLAGS_EMULATE, NULL));\n");
Packit a43c12
    fprintf(output, "    }\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
  }
Packit a43c12
  if (use_backup) {
Packit a43c12
    fprintf(output, "    ret = orc_test_compare_output_backup (p);\n");
Packit a43c12
    fprintf(output, "    if (!ret) {\n");
Packit a43c12
    fprintf(output, "      error = TRUE;\n");
Packit a43c12
    fprintf(output, "    } else if (!quiet) {\n");
Packit a43c12
    fprintf(output, "      printf (\"    backup function  :   PASSED\\n\");\n");
Packit a43c12
    fprintf(output, "    }\n");
Packit a43c12
    fprintf(output, "\n");
Packit a43c12
    if (compat >= ORC_VERSION(0,4,7,1)) {
Packit a43c12
      fprintf(output, "    if (benchmark) {\n");
Packit a43c12
      fprintf(output, "      printf (\"    cycles (backup)  :   %%g\\n\",\n");
Packit a43c12
      fprintf(output, "          orc_test_performance_full (p, ORC_TEST_FLAGS_BACKUP, NULL));\n");
Packit a43c12
      fprintf(output, "    }\n");
Packit a43c12
      fprintf(output, "\n");
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "    ret = orc_test_compare_output (p);\n");
Packit a43c12
  fprintf(output, "    if (ret == ORC_TEST_INDETERMINATE && !quiet) {\n");
Packit a43c12
  fprintf(output, "      printf (\"    compiled function:   COMPILE FAILED\\n\");\n");
Packit a43c12
  fprintf(output, "    } else if (!ret) {\n");
Packit a43c12
  fprintf(output, "      error = TRUE;\n");
Packit a43c12
  fprintf(output, "    } else if (!quiet) {\n");
Packit a43c12
  fprintf(output, "      printf (\"    compiled function:   PASSED\\n\");\n");
Packit a43c12
  fprintf(output, "    }\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  if (compat >= ORC_VERSION(0,4,7,1)) {
Packit a43c12
    fprintf(output, "    if (benchmark) {\n");
Packit a43c12
    fprintf(output, "      printf (\"    cycles (compiled):   %%g\\n\",\n");
Packit a43c12
    fprintf(output, "          orc_test_performance_full (p, 0, NULL));\n");
Packit a43c12
    fprintf(output, "    }\n");
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
  fprintf(output, "    orc_program_free (p);\n");
Packit a43c12
  fprintf(output, "  }\n");
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
}
Packit a43c12
Packit a43c12
void
Packit a43c12
output_code_assembly (OrcProgram *p, FILE *output)
Packit a43c12
{
Packit a43c12
Packit a43c12
  fprintf(output, "/* %s */\n", p->name);
Packit a43c12
  /* output_prototype (p, output); */
Packit a43c12
  {
Packit a43c12
    OrcCompileResult result;
Packit a43c12
    OrcTarget *t = orc_target_get_by_name(target);
Packit a43c12
Packit a43c12
    result = orc_program_compile_full (p, t,
Packit a43c12
        orc_target_get_default_flags (t));
Packit a43c12
    if (ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
Packit a43c12
      fprintf(output, "%s\n", orc_program_get_asm_code (p));
Packit a43c12
    } else {
Packit a43c12
      printf("Failed to compile assembly for '%s'\n", p->name);
Packit a43c12
      error = TRUE;
Packit a43c12
    }
Packit a43c12
  }
Packit a43c12
  fprintf(output, "\n");
Packit a43c12
Packit a43c12
}
Packit a43c12
Packit a43c12
static const char *
Packit a43c12
my_basename (const char *s)
Packit a43c12
{
Packit a43c12
  const char *ret = s;
Packit a43c12
  const char *t;
Packit a43c12
Packit a43c12
  t = s;
Packit a43c12
  while (t[0] != 0) {
Packit a43c12
    if (t[0] == '/') ret = t+1;
Packit a43c12
    t++;
Packit a43c12
  }
Packit a43c12
Packit a43c12
  return ret;
Packit a43c12
}
Packit a43c12