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