|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
a43c12 |
#include "config.h"
|
|
Packit |
a43c12 |
#endif
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
#include <orc/orc.h>
|
|
Packit |
a43c12 |
#include <orc/orcbytecode.h>
|
|
Packit |
a43c12 |
#include <stdio.h>
|
|
Packit |
a43c12 |
#include <stdlib.h>
|
|
Packit |
a43c12 |
#include <string.h>
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void bytecode_append_code (OrcBytecode *bytecode, int code);
|
|
Packit |
a43c12 |
void bytecode_append_int (OrcBytecode *bytecode, int value);
|
|
Packit |
a43c12 |
void bytecode_append_uint32 (OrcBytecode *bytecode, orc_uint32 value);
|
|
Packit |
a43c12 |
void bytecode_append_uint64 (OrcBytecode *bytecode, orc_uint64 value);
|
|
Packit |
a43c12 |
void bytecode_append_string (OrcBytecode *bytecode, char *s);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
OrcBytecode *
|
|
Packit |
a43c12 |
orc_bytecode_new (void)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
OrcBytecode *bytecode;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
bytecode = malloc (sizeof(OrcBytecode));
|
|
Packit |
a43c12 |
memset (bytecode, 0, sizeof(OrcBytecode));
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
bytecode->alloc_len = 256;
|
|
Packit |
a43c12 |
bytecode->bytecode = malloc(bytecode->alloc_len);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
return bytecode;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
orc_bytecode_free (OrcBytecode *bytecode)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
free (bytecode->bytecode);
|
|
Packit |
a43c12 |
free (bytecode);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
OrcBytecode *
|
|
Packit |
a43c12 |
orc_bytecode_from_program (OrcProgram *p)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
OrcBytecode *bytecode = orc_bytecode_new ();
|
|
Packit |
a43c12 |
int i;
|
|
Packit |
a43c12 |
OrcVariable *var;
|
|
Packit |
a43c12 |
OrcOpcodeSet *opcode_set;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
opcode_set = orc_opcode_set_get ("sys");
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_BEGIN_FUNCTION);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
if (p->constant_n != 0) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_CONSTANT_N);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, p->constant_n);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (p->n_multiple != 0) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_N_MULTIPLE);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, p->n_multiple);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (p->n_minimum != 0) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_N_MINIMUM);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, p->n_minimum);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (p->n_maximum != 0) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_N_MAXIMUM);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, p->n_maximum);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (p->is_2d) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_2D);
|
|
Packit |
a43c12 |
if (p->constant_m != 0) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_CONSTANT_M);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, p->constant_m);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (p->name) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_NAME);
|
|
Packit |
a43c12 |
bytecode_append_string (bytecode, p->name);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
#if 0
|
|
Packit |
a43c12 |
/* if (!is_inline) { */
|
|
Packit |
a43c12 |
if (p->backup_function) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_SET_BACKUP_FUNCTION);
|
|
Packit |
a43c12 |
bytecode_pointer (bytecode, p->backup_function);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
#endif
|
|
Packit |
a43c12 |
for(i=0;i<4;i++){
|
|
Packit |
a43c12 |
var = &p->vars[ORC_VAR_D1 + i];
|
|
Packit |
a43c12 |
if (var->size) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_DESTINATION);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->alignment);
|
|
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 |
bytecode_append_code (bytecode, ORC_BC_ADD_SOURCE);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->alignment);
|
|
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 |
bytecode_append_code (bytecode, ORC_BC_ADD_ACCUMULATOR);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
/* bytecode_append_int (bytecode, var->alignment); */
|
|
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 |
bytecode_append_code (bytecode, ORC_BC_ADD_CONSTANT);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
bytecode_append_uint32 (bytecode, (orc_uint32)var->value.i);
|
|
Packit |
a43c12 |
} else if (var->size > 4) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_CONSTANT_INT64);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
bytecode_append_uint64 (bytecode, (orc_uint64)var->value.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 |
switch (var->param_type) {
|
|
Packit |
a43c12 |
case ORC_PARAM_TYPE_INT:
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_PARAM_TYPE_FLOAT:
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_FLOAT);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_PARAM_TYPE_INT64:
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_INT64);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_PARAM_TYPE_DOUBLE:
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_ADD_PARAMETER_INT64);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
default:
|
|
Packit |
a43c12 |
ORC_ASSERT(0);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
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 |
bytecode_append_code (bytecode, ORC_BC_ADD_TEMPORARY);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, var->size);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
for(i=0;i<p->n_insns;i++){
|
|
Packit |
a43c12 |
OrcInstruction *insn = p->insns + i;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
if (insn->flags) {
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_INSTRUCTION_FLAGS);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->flags);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, (insn->opcode - opcode_set->opcodes) + 32);
|
|
Packit |
a43c12 |
if (insn->opcode->dest_size[0] != 0) {
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->dest_args[0]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->dest_size[1] != 0) {
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->dest_args[1]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[0] != 0) {
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->src_args[0]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[1] != 0) {
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->src_args[1]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[2] != 0) {
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, insn->src_args[2]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_END_FUNCTION);
|
|
Packit |
a43c12 |
bytecode_append_code (bytecode, ORC_BC_END);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
return bytecode;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_byte (OrcBytecode *bytecode, int byte)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
if (bytecode->length >= bytecode->alloc_len) {
|
|
Packit |
a43c12 |
bytecode->alloc_len += 256;
|
|
Packit |
a43c12 |
bytecode->bytecode = realloc (bytecode->bytecode, bytecode->alloc_len);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
bytecode->bytecode[bytecode->length] = byte;
|
|
Packit |
a43c12 |
bytecode->length++;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_code (OrcBytecode *bytecode, int code)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, code);
|
|
Packit |
a43c12 |
#if 0
|
|
Packit |
a43c12 |
OrcOpcodeSet *opcode_set = orc_opcode_set_get ("sys");
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
fprintf(bytecode, "\n ");
|
|
Packit |
a43c12 |
if (code >= 32) {
|
|
Packit |
a43c12 |
fprintf(bytecode, "ORC_BC_%s, ", opcode_set->opcodes[code-32].name);
|
|
Packit |
a43c12 |
} else {
|
|
Packit |
a43c12 |
static char *codes[32] = {
|
|
Packit |
a43c12 |
"END",
|
|
Packit |
a43c12 |
"BEGIN_FUNCTION",
|
|
Packit |
a43c12 |
"END_FUNCTION",
|
|
Packit |
a43c12 |
"SET_CONSTANT_N",
|
|
Packit |
a43c12 |
"SET_N_MULTIPLE",
|
|
Packit |
a43c12 |
"SET_N_MINIMUM",
|
|
Packit |
a43c12 |
"SET_N_MAXIMUM",
|
|
Packit |
a43c12 |
"SET_2D",
|
|
Packit |
a43c12 |
"SET_CONSTANT_M",
|
|
Packit |
a43c12 |
"SET_NAME",
|
|
Packit |
a43c12 |
"SET_BACKUP_FUNCTION",
|
|
Packit |
a43c12 |
"ADD_DESTINATION",
|
|
Packit |
a43c12 |
"ADD_SOURCE",
|
|
Packit |
a43c12 |
"ADD_ACCUMULATOR",
|
|
Packit |
a43c12 |
"ADD_CONSTANT",
|
|
Packit |
a43c12 |
"ADD_CONSTANT_INT64",
|
|
Packit |
a43c12 |
"ADD_PARAMETER",
|
|
Packit |
a43c12 |
"ADD_PARAMETER_FLOAT",
|
|
Packit |
a43c12 |
"ADD_PARAMETER_INT64",
|
|
Packit |
a43c12 |
"ADD_PARAMETER_DOUBLE",
|
|
Packit |
a43c12 |
"ADD_TEMPORARY",
|
|
Packit |
a43c12 |
"RESERVED_21",
|
|
Packit |
a43c12 |
"RESERVED_22",
|
|
Packit |
a43c12 |
"RESERVED_23",
|
|
Packit |
a43c12 |
"RESERVED_24",
|
|
Packit |
a43c12 |
"RESERVED_25",
|
|
Packit |
a43c12 |
"RESERVED_26",
|
|
Packit |
a43c12 |
"RESERVED_27",
|
|
Packit |
a43c12 |
"RESERVED_28",
|
|
Packit |
a43c12 |
"RESERVED_29",
|
|
Packit |
a43c12 |
"RESERVED_30",
|
|
Packit |
a43c12 |
"RESERVED_31"
|
|
Packit |
a43c12 |
};
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
fprintf(bytecode, "ORC_BC_%s, ", codes[code]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
#endif
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_int (OrcBytecode *bytecode, int value)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
ORC_ASSERT(value >= 0);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
if (value < 255) {
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, value);
|
|
Packit |
a43c12 |
} else if (value < 65535) {
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, 255);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, value & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, value >> 8);
|
|
Packit |
a43c12 |
} else {
|
|
Packit |
a43c12 |
ORC_ASSERT(0);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_uint32 (OrcBytecode *bytecode, orc_uint32 value)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, value & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 8) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 16) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 24) & 0xff);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_uint64 (OrcBytecode *bytecode, orc_uint64 value)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, value & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 8) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 16) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 24) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 32) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 40) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 48) & 0xff);
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, (value >> 56) & 0xff);
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
void
|
|
Packit |
a43c12 |
bytecode_append_string (OrcBytecode *bytecode, char *s)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
int i;
|
|
Packit |
a43c12 |
int len = strlen(s);
|
|
Packit |
a43c12 |
bytecode_append_int (bytecode, len);
|
|
Packit |
a43c12 |
for(i=0;i
|
|
Packit |
a43c12 |
bytecode_append_byte (bytecode, s[i]);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
typedef struct _OrcBytecodeParse OrcBytecodeParse;
|
|
Packit |
a43c12 |
struct _OrcBytecodeParse {
|
|
Packit |
a43c12 |
const orc_uint8 *bytecode;
|
|
Packit |
a43c12 |
int parse_offset;
|
|
Packit |
a43c12 |
int function_start;
|
|
Packit |
a43c12 |
int code_start;
|
|
Packit |
a43c12 |
};
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
int
|
|
Packit |
a43c12 |
orc_bytecode_parse_get_byte (OrcBytecodeParse *parse)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
int value;
|
|
Packit |
a43c12 |
value = parse->bytecode[parse->parse_offset];
|
|
Packit |
a43c12 |
parse->parse_offset++;
|
|
Packit |
a43c12 |
return value;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
int
|
|
Packit |
a43c12 |
orc_bytecode_parse_get_int (OrcBytecodeParse *parse)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
int value;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
value = orc_bytecode_parse_get_byte(parse);
|
|
Packit |
a43c12 |
if (value == 255) {
|
|
Packit |
a43c12 |
value = orc_bytecode_parse_get_byte(parse);
|
|
Packit |
a43c12 |
value |= orc_bytecode_parse_get_byte(parse) << 8;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
return value;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
char *
|
|
Packit |
a43c12 |
orc_bytecode_parse_get_string (OrcBytecodeParse *parse)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
int len;
|
|
Packit |
a43c12 |
int i;
|
|
Packit |
a43c12 |
char *s;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
len = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
s = malloc (len + 1);
|
|
Packit |
a43c12 |
for(i=0;i
|
|
Packit |
a43c12 |
s[i] = orc_bytecode_parse_get_byte (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
s[i] = 0;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
return s;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
orc_uint32
|
|
Packit |
a43c12 |
orc_bytecode_parse_get_uint32 (OrcBytecodeParse *parse)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
orc_uint32 value;
|
|
Packit |
a43c12 |
value = orc_bytecode_parse_get_byte (parse);
|
|
Packit |
a43c12 |
value |= ((orc_uint32)orc_bytecode_parse_get_byte (parse)) << 8;
|
|
Packit |
a43c12 |
value |= ((orc_uint32)orc_bytecode_parse_get_byte (parse)) << 16;
|
|
Packit |
a43c12 |
value |= ((orc_uint32)orc_bytecode_parse_get_byte (parse)) << 24;
|
|
Packit |
a43c12 |
return value;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
orc_uint64
|
|
Packit |
a43c12 |
orc_bytecode_parse_get_uint64 (OrcBytecodeParse *parse)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
orc_uint64 value;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
value = ((orc_uint64)orc_bytecode_parse_get_byte (parse));
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 8;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 16;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 24;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 32;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 40;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 48;
|
|
Packit |
a43c12 |
value |= ((orc_uint64)orc_bytecode_parse_get_byte (parse)) << 56;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
return value;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
int
|
|
Packit |
a43c12 |
orc_bytecode_parse_function (OrcProgram *program, const orc_uint8 *bytecode)
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
OrcBytecodeParse _parse;
|
|
Packit |
a43c12 |
OrcBytecodeParse *parse = &_parse;
|
|
Packit |
a43c12 |
/* int in_function = FALSE; */
|
|
Packit |
a43c12 |
int bc;
|
|
Packit |
a43c12 |
int size;
|
|
Packit |
a43c12 |
int alignment;
|
|
Packit |
a43c12 |
OrcOpcodeSet *opcode_set;
|
|
Packit |
a43c12 |
int instruction_flags = 0;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
memset (parse, 0, sizeof(*parse));
|
|
Packit |
a43c12 |
parse->bytecode = bytecode;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
opcode_set = orc_opcode_set_get ("sys");
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
while (1) {
|
|
Packit |
a43c12 |
bc = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
if (bc < ORC_BC_absb) {
|
|
Packit |
a43c12 |
switch (bc) {
|
|
Packit |
a43c12 |
case ORC_BC_END:
|
|
Packit |
a43c12 |
/* FIXME this is technically an error */
|
|
Packit |
a43c12 |
return 0;
|
|
Packit |
a43c12 |
case ORC_BC_BEGIN_FUNCTION:
|
|
Packit |
a43c12 |
/* in_function = TRUE; */
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_END_FUNCTION:
|
|
Packit |
a43c12 |
return 0;
|
|
Packit |
a43c12 |
case ORC_BC_SET_CONSTANT_N:
|
|
Packit |
a43c12 |
program->constant_n = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_N_MULTIPLE:
|
|
Packit |
a43c12 |
program->n_multiple = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_N_MINIMUM:
|
|
Packit |
a43c12 |
program->n_minimum = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_N_MAXIMUM:
|
|
Packit |
a43c12 |
program->n_maximum = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_2D:
|
|
Packit |
a43c12 |
program->is_2d = TRUE;
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_CONSTANT_M:
|
|
Packit |
a43c12 |
program->constant_m = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_NAME:
|
|
Packit |
a43c12 |
if (program->name) {
|
|
Packit |
a43c12 |
free (program->name);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
program->name = orc_bytecode_parse_get_string (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_SET_BACKUP_FUNCTION:
|
|
Packit |
a43c12 |
/* FIXME error */
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_DESTINATION:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
alignment = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_destination_full (program, size, "d", "unknown",
|
|
Packit |
a43c12 |
alignment);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_SOURCE:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
alignment = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_source_full (program, size, "s", "unknown",
|
|
Packit |
a43c12 |
alignment);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_ACCUMULATOR:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_accumulator (program, size, "a");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_CONSTANT:
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
orc_uint32 value;
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
value = orc_bytecode_parse_get_uint32 (parse);
|
|
Packit |
a43c12 |
orc_program_add_constant (program, size, value, "c");
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_CONSTANT_INT64:
|
|
Packit |
a43c12 |
{
|
|
Packit |
a43c12 |
orc_uint64 value;
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
value = orc_bytecode_parse_get_uint64 (parse);
|
|
Packit |
a43c12 |
orc_program_add_constant_int64 (program, size, value, "c");
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_PARAMETER:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_parameter (program, size, "p");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_PARAMETER_FLOAT:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_parameter_float (program, size, "p");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_PARAMETER_INT64:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_parameter_int64 (program, size, "p");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_PARAMETER_DOUBLE:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_parameter_double (program, size, "p");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_ADD_TEMPORARY:
|
|
Packit |
a43c12 |
size = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
orc_program_add_temporary (program, size, "t");
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
case ORC_BC_INSTRUCTION_FLAGS:
|
|
Packit |
a43c12 |
instruction_flags = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
default:
|
|
Packit |
a43c12 |
break;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
} else {
|
|
Packit |
a43c12 |
OrcInstruction *insn;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
insn = program->insns + program->n_insns;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
insn->opcode = opcode_set->opcodes + (bc - 32);
|
|
Packit |
a43c12 |
if (insn->opcode->dest_size[0] != 0) {
|
|
Packit |
a43c12 |
insn->dest_args[0] = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->dest_size[1] != 0) {
|
|
Packit |
a43c12 |
insn->dest_args[1] = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[0] != 0) {
|
|
Packit |
a43c12 |
insn->src_args[0] = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[1] != 0) {
|
|
Packit |
a43c12 |
insn->src_args[1] = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
if (insn->opcode->src_size[2] != 0) {
|
|
Packit |
a43c12 |
insn->src_args[2] = orc_bytecode_parse_get_int (parse);
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
insn->flags = instruction_flags;
|
|
Packit |
a43c12 |
instruction_flags = 0;
|
|
Packit |
a43c12 |
|
|
Packit |
a43c12 |
program->n_insns++;
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
}
|
|
Packit |
a43c12 |
|