First task version + ovmjit
This commit is contained in:
parent
42c8f3baf7
commit
39b3ab9a0b
2
ovm/.gitignore
vendored
Normal file
2
ovm/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
kdebuild
|
||||||
|
ovm.kdev4
|
62
ovm/CMakeLists.txt
Normal file
62
ovm/CMakeLists.txt
Normal 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
26
ovm/base.h
Normal 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
1
ovm/bin1.c
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../task/bin1.c
|
1
ovm/bin2.c
Symbolic link
1
ovm/bin2.c
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../task/bin2.c
|
1
ovm/bin3.c
Symbolic link
1
ovm/bin3.c
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../task/bin3.c
|
168
ovm/ovm.c
Normal file
168
ovm/ovm.c
Normal 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
66
ovm/ovm.h
Normal 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
17
ovm/ovmjit.c
Normal 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
19
ovm/task.c
Normal 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
28
ovm/task.h
Normal 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
6
ovm/task1.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
1
task/.gitignore
vendored
Normal file
1
task/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.c
|
20
task/Makefile
Normal file
20
task/Makefile
Normal 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
BIN
task/bin1.obf
Normal file
Binary file not shown.
BIN
task/bin2.obf
Normal file
BIN
task/bin2.obf
Normal file
Binary file not shown.
BIN
task/bin3.obf
Normal file
BIN
task/bin3.obf
Normal file
Binary file not shown.
BIN
task/task.pdf
Normal file
BIN
task/task.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user