First task version + ovmjit

This commit is contained in:
Stefan Bühler 2009-06-26 23:13:17 +02:00
parent 42c8f3baf7
commit 39b3ab9a0b
18 changed files with 418 additions and 0 deletions

2
ovm/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
kdebuild
ovm.kdev4

62
ovm/CMakeLists.txt Normal file
View File

@ -0,0 +1,62 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
PROJECT(ovm C)
MACRO(ADD_TARGET_PROPERTIES _target _name)
SET(_properties)
FOREACH(_prop ${ARGN})
SET(_properties "${_properties} ${_prop}")
ENDFOREACH(_prop)
GET_TARGET_PROPERTY(_old_properties ${_target} ${_name})
MESSAGE("adding property to ${_target} ${_name}:" ${_properties})
IF(NOT _old_properties)
# in case it's NOTFOUND
SET(_old_properties)
ENDIF(NOT _old_properties)
SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties} ${_properties}")
ENDMACRO(ADD_TARGET_PROPERTIES)
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckVariableExists)
INCLUDE(CheckTypeSize)
INCLUDE(CheckLibraryExists)
INCLUDE(CMakeDetermineCCompiler)
INCLUDE(FindThreads)
INCLUDE(FindPkgConfig)
# glib/gthread
pkg_check_modules(GTHREAD REQUIRED gthread-2.0)
# pkg_check_modules(GMODULE REQUIRED gmodule-2.0)
ADD_EXECUTABLE(ovmjit
ovmjit.c
ovm.c
)
ADD_EXECUTABLE(task1
bin1.c
task.c
task1.c
)
SET(WARN_FLAGS "-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed")
# -Werror -Wbad-function-cast -Wmissing-prototypes
SET(COMMON_LDFLAGS "${GTHREAD_LDFLAGS} ${WARN_FLAGS}")
SET(COMMON_CFLAGS "${GTHREAD_CFLAGS} ${WARN_FLAGS}")
ADD_TARGET_PROPERTIES(ovmjit LINK_FLAGS ${COMMON_LDFLAGS})
ADD_TARGET_PROPERTIES(ovmjit COMPILE_FLAGS ${COMMON_CFLAGS})
ADD_TARGET_PROPERTIES(task1 LINK_FLAGS -lm ${COMMON_LDFLAGS})
ADD_TARGET_PROPERTIES(task1 COMPILE_FLAGS ${COMMON_CFLAGS})
IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -g -Wshadow -W -pedantic")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_WITHDEBINFO} -O2")
ADD_DEFINITIONS(-D_GNU_SOURCE)
ENDIF(CMAKE_COMPILER_IS_GNUCC)

26
ovm/base.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef OVM_BASE_H
#define OVM_BASE_H
#define L_GOFFSET_FORMAT G_GINT64_FORMAT
#define L_GOFFSET_MODIFIER G_GINT64_MODIFIER
#define CONST_STR_LEN(x) (x), sizeof(x) - 1
#define GSTR_LEN(x) (x) ? (x)->str : "", (x) ? (x)->len : 0
#define GSTR_SAFE_STR(x) ((x && x->str) ? x->str : "(null)")
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stddef.h>
#include <inttypes.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#endif

1
ovm/bin1.c Symbolic link
View File

@ -0,0 +1 @@
../task/bin1.c

1
ovm/bin2.c Symbolic link
View File

@ -0,0 +1 @@
../task/bin2.c

1
ovm/bin3.c Symbolic link
View File

@ -0,0 +1 @@
../task/bin3.c

168
ovm/ovm.c Normal file
View File

@ -0,0 +1,168 @@
#include "ovm.h"
#include <glib/gstdio.h>
void ovm_free(ovm_t *ovm) {
if (!ovm) return;
g_slice_free1(ovm->limit * sizeof(instruction_t), ovm->instructions);
g_slice_free1(ovm->limit * sizeof(gdouble), ovm->values);
g_slice_free(ovm_t, ovm);
}
ovm_t* ovm_load(const gchar *filename) {
GError *err = NULL;
gchar *buf = NULL, *cur;
gsize len = 0, i;
instruction_t *oi;
gdouble *vi;
ovm_t *ovm = g_slice_new(ovm_t);
ovm->limit = 0x4000;
ovm->instructions = g_slice_alloc0(ovm->limit * sizeof(instruction_t));
ovm->values = g_slice_alloc0(ovm->limit * sizeof(gdouble));
if (!g_file_get_contents(filename, &buf, &len, &err)) {
fprintf (stderr, "Unable to read file: %s\n", err->message);
g_error_free (err);
exit(1);
}
oi = ovm->instructions;
vi = ovm->values;
for (cur = buf, i = 0; i < len; i++) {
*vi++ = *(gdouble*)buf;
buf += sizeof(gdouble);
*oi++ = *(guint32*)buf;
buf += sizeof(guint32);
if (++i < len) {
*oi++ = *(guint32*)buf;
buf += sizeof(guint32);
*vi++ = *(gdouble*)buf;
buf += sizeof(gdouble);
} else {
break;
}
}
ovm->used = i;
return ovm;
}
static const gchar* cmp_op_strings[] = {
"<", "<=", "==", ">=", ">"
};
void ovm_print_c(ovm_t *ovm, const gchar *filename) {
guint i;
instruction_t *oi = ovm->instructions;
gdouble *vi = ovm->values;
guint64 *uvi = (guint64*) ovm->values;
guchar *usedv = g_slice_alloc0(ovm->used*sizeof(guchar));
GString *str = g_string_sized_new(0), *buf = g_string_sized_new(0);
int f = g_open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (-1 == f) {
fprintf(stderr, "Couldn't open file %s: %s\n", filename, g_strerror(errno));
exit(2);
}
g_string_append_len(buf, CONST_STR_LEN(
"void ovm_step(gdouble scenario, gdouble *in, gdouble *out) {\n"
));
#define USED(i) (usedv[i] = TRUE, i)
for (i = 0; i < ovm->used; i++) {
g_string_printf(str, "\t/* Invalid command: 0x%X */\n", (guint) oi[i]);
switch (instr_dop(oi[i])) {
case OP_STYPE:
switch (instr_sop(oi[i])) {
case SOP_NOOP:
g_string_printf(str, "/* NOOP */\n");
g_string_truncate(str, 0);
break;
case SOP_CMPZ:
g_string_printf(str, "\tovm_status = (v%u.d %s 0.0);\n", USED(instr_sop_r1(oi[i])), cmp_op_strings[instr_sop_cmp(oi[i])]);
break;
case SOP_SQRT:
g_string_printf(str, "\tv%u.d = sqrt(v%u.d);\n", USED(i), USED(instr_sop_r1(oi[i])));
break;
case SOP_COPY:
g_string_printf(str, "\tv%u.d = v%u.d;\n", USED(i), USED(instr_sop_r1(oi[i])));
break;
case SOP_IN:
if (0x3e80 == instr_sop_r1(oi[i])) {
g_string_printf(str, "\tv%u.d = scenario;\n", USED(i));
} else {
g_string_printf(str, "\tv%u.d = in[%u];\n", USED(i), instr_sop_r1(oi[i]));
}
break;
}
break;
case OP_ADD:
g_string_printf(str, "\tv%u.d = v%u.d + v%u.d;\n", USED(i), USED(instr_dop_r1(oi[i])), USED(instr_dop_r2(oi[i])));
break;
case OP_SUB:
g_string_printf(str, "\tv%u.d = v%u.d - v%u.d;\n", USED(i), USED(instr_dop_r1(oi[i])), USED(instr_dop_r2(oi[i])));
break;
case OP_MULT:
g_string_printf(str, "\tv%u.d = v%u.d * v%u.d;\n", USED(i), USED(instr_dop_r1(oi[i])), USED(instr_dop_r2(oi[i])));
break;
case OP_DIV:
g_string_printf(str, "\tv%u.d = (v%u.d == 0.0) ? 0.0 : v%u.d / v%u.d;\n", USED(i), USED(instr_dop_r2(oi[i])), USED(instr_dop_r1(oi[i])), instr_dop_r2(oi[i]));
break;
case OP_OUT:
g_string_printf(str, "\tout[%u] = v%u.d;\n", instr_dop_r1(oi[i]), USED(instr_dop_r2(oi[i])));
break;
case OP_PHI:
g_string_printf(str, "\tv%u.d = ovm_status ? v%u.d : v%u.d;\n", USED(i), USED(instr_dop_r1(oi[i])), USED(instr_dop_r2(oi[i])));
break;
}
g_string_append_len(buf, GSTR_LEN(str));
}
#undef USED
g_string_append_len(buf, CONST_STR_LEN(
"}\n"
"\n"
));
write(f, CONST_STR_LEN(
"#include \"task.h\"\n"
"#include <math.h>\n"
"\n"
"typedef union { gdouble d; guint64 i; } double_int;\n"
"\n"
"static gboolean ovm_status = FALSE;\n"
"\n"
"static double_int v0"
));
for (i = 1; i < ovm->used; i++) {
if (!usedv[i]) continue;
g_string_printf(str, ", v%u", i);
write(f, GSTR_LEN(str));
}
write(f, CONST_STR_LEN(
";\n"
"\n"
"void ovm_init() {\n"
"\tovm_status = FALSE;\n"
"\n"
));
for (i = 0; i < ovm->used; i++) {
if (!usedv[i]) continue;
g_string_printf(str, "\tv%u.i = G_GUINT64_CONSTANT(%" G_GUINT64_FORMAT "); /* %f */ \n", i, uvi[i], vi[i]);
write(f, GSTR_LEN(str));
}
write(f, CONST_STR_LEN(
"}\n"
"\n"
));
write(f, GSTR_LEN(buf));
close(f);
g_string_free(str, TRUE);
g_string_free(buf, TRUE);
}

66
ovm/ovm.h Normal file
View File

@ -0,0 +1,66 @@
#ifndef OVM_OVM_H
#define OVM_OVM_H
#include "base.h"
typedef guint32 instruction_t;
typedef enum {
OP_STYPE = 0x0,
OP_ADD = 0x1,
OP_SUB = 0x2,
OP_MULT = 0x3,
OP_DIV = 0x4,
OP_OUT = 0x5,
OP_PHI = 0x6
} dop_t;
typedef enum {
SOP_NOOP = 0x0,
SOP_CMPZ = 0x1,
SOP_SQRT = 0x2,
SOP_COPY = 0x3,
SOP_IN = 0x4
} sop_t;
typedef enum {
CMP_LTZ = 0x0, /* < */
CMP_LEZ = 0x1, /* <= */
CMP_EQZ = 0x2, /* == */
CMP_GEZ = 0x3, /* >= */
CMP_GTZ = 0x4 /* > */
} cmp_t;
static inline dop_t instr_dop(instruction_t i) {
return i >> 28;
}
static inline sop_t instr_sop(instruction_t i) {
return i >> 24; /* upper bits are 0 */
}
static inline guint instr_dop_r1(instruction_t i) {
return (i >> 14) & 0x3FFF;
}
static inline guint instr_dop_r2(instruction_t i) {
return i & 0x3FFF;
}
static inline cmp_t instr_sop_cmp(instruction_t i) {
return (i >> 20) & 0xF;
}
static inline guint instr_sop_r1(instruction_t i) {
return i & 0x3FFF;
}
typedef struct {
gsize limit, used;
instruction_t *instructions;
gdouble *values;
guint32 pc;
} ovm_t;
void ovm_free(ovm_t *ovm);
ovm_t* ovm_load(const gchar *filename);
void ovm_print_c(ovm_t *ovm, const gchar *filename);
#endif

17
ovm/ovmjit.c Normal file
View File

@ -0,0 +1,17 @@
#include "ovm.h"
int main(int argc, char** argv) {
ovm_t *ovm;
if (argc < 3) {
fprintf(stderr, "Wrong syntax. %s in out\n", argv[0]);
exit(1);
}
ovm = ovm_load(argv[1]);
ovm_print_c(ovm, argv[2]);
ovm_free(ovm);
return 0;
}

19
ovm/task.c Normal file
View File

@ -0,0 +1,19 @@
#include "task.h"
void task_free(task_t *task) {
if (!task) return;
g_slice_free1(task->in_size * sizeof(gdouble), task->in);
g_slice_free1(task->out_size * sizeof(gdouble), task->out);
g_slice_free(task_t, task);
}
task_t* task_new(gdouble scenario, guint in_size, guint out_size) {
task_t *task = g_slice_new(task_t);
task->scenario = scenario;
task->in_size = in_size;
task->out_size = out_size;
task->in = g_slice_alloc0(task->in_size * sizeof(gdouble));
task->out = g_slice_alloc0(task->out_size * sizeof(gdouble));
return task;
}

28
ovm/task.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef OVM_TASK_H
#define OVM_TASK_H
#include "base.h"
typedef struct {
gdouble scenario;
guint in_size, out_size;
gdouble *in, *out;
} task_t;
typedef void (*task_app_t)(task_t *task);
task_t* task_new(gdouble scenario, guint in_size, guint out_size);
void task_free(task_t *task);
void ovm_init();
void ovm_step(gdouble scenario, gdouble *in, gdouble *out);
static inline void task_run(task_t *task, task_app_t app) {
ovm_init();
while (task->out[0] == 0.0) {
app(task);
ovm_step(task->scenario, task->in, task->out);
}
}
#endif

6
ovm/task1.c Normal file
View File

@ -0,0 +1,6 @@
#include "base.h"
int main(int argc, char **argv) {
return 0;
}

1
task/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.c

20
task/Makefile Normal file
View File

@ -0,0 +1,20 @@
OVMJIT=../ovm/kdebuild/ovmjit
.SUFFIXES: .c .obf .o
FILES_OBF=bin1.obf bin2.obf bin3.obf
FILES_C=$(FILES_OBF:.obf=.c)
.PHONY: all sources clean
all: sources
%.c: %.obf $(OVMJIT)
@echo Creatin $@ from $<
@$(OVMJIT) $< $@
sources: $(FILES_C)
clean:
rm -f $(FILES_C)

BIN
task/bin1.obf Normal file

Binary file not shown.

BIN
task/bin2.obf Normal file

Binary file not shown.

BIN
task/bin3.obf Normal file

Binary file not shown.

BIN
task/task.pdf Normal file

Binary file not shown.