Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
Peter McGoron | 52279a9afc | |
Peter McGoron | 448b70cc97 | |
Peter McGoron @ planck | 73c5beb90e | |
Peter McGoron | 56c6523e15 | |
Peter McGoron @ planck | 0ead095044 | |
Peter McGoron @ planck | c7fc965fcf | |
Peter McGoron | dc1abae13a | |
Peter McGoron | 13c67aba9a | |
Peter McGoron | c18db4be57 | |
Peter McGoron | 22674528da | |
Peter McGoron | 6d30be57f7 | |
Peter McGoron | 8335395dec | |
Peter McGoron | 945bcd68a5 |
7
Makefile
7
Makefile
|
@ -1,13 +1,14 @@
|
||||||
test: test_asm c_test/encode_decode c_test/creole
|
test: test_asm c_test/encode_decode c_test/creole
|
||||||
|
CFLAGS=-DCREOLE_TEST
|
||||||
asm/libcreole.so: creole.c creole.h
|
asm/libcreole.so: creole.c creole.h
|
||||||
$(CC) -Wall -fPIC -c creole.c -o c_test/creole.o
|
$(CC) $(CFLAGS) -Wall -fPIC -c creole.c -o c_test/creole.o
|
||||||
$(CC) -shared -o asm/libcreole.so c_test/creole.o
|
$(CC) -shared -o asm/libcreole.so c_test/creole.o
|
||||||
|
|
||||||
test_asm: asm/libcreole.so
|
test_asm: asm/libcreole.so
|
||||||
cd asm && python3 test.py -f
|
cd asm && python3 test.py -f
|
||||||
c_test/encode_decode: c_test/encode_decode.c creole.c creole.h
|
c_test/encode_decode: c_test/encode_decode.c creole.c creole.h
|
||||||
$(CC) creole.c c_test/encode_decode.c -Wall -pedantic -std=c89 -g -fopenmp -o c_test/encode_decode
|
$(CC) $(CFLAGS) creole.c c_test/encode_decode.c -Wall -pedantic -std=c99 -g -fopenmp -o c_test/encode_decode
|
||||||
# c_test/encode_decode
|
# c_test/encode_decode
|
||||||
c_test/creole: c_test/creole.c creole.c creole.h c_test/greatest.h
|
c_test/creole: c_test/creole.c creole.c creole.h c_test/greatest.h
|
||||||
$(CC) -g c_test/creole.c -Wall -pedantic -std=c89 -o c_test/creole
|
$(CC) $(CFLAGS) -g c_test/creole.c -Wall -pedantic -std=c99 -o c_test/creole
|
||||||
c_test/creole
|
c_test/creole
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
from creole import *
|
||||||
|
import socket
|
||||||
|
|
||||||
|
def connect(ip, port):
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.connect((ip, port))
|
||||||
|
return s
|
||||||
|
|
||||||
|
def execute(creole_instance, socket):
|
||||||
|
code = creole_instance()
|
||||||
|
l = len(code)
|
||||||
|
assert l <= 0xFFFF
|
||||||
|
socket.sendall(bytes([l & 0xFF, l >> 8]) + code)
|
||||||
|
|
||||||
|
def connect_exec(cr, ip="192.168.1.50", port=6626):
|
||||||
|
s = connect(ip, port)
|
||||||
|
execute(cr, s)
|
||||||
|
return s.recv(1024)
|
|
@ -75,7 +75,7 @@ class StringArgument(Argument):
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
b = bytes()
|
b = bytes()
|
||||||
for v in self.val:
|
for v in self.val:
|
||||||
b = b + Argument(ArgType.IMM, int(v, base=16))()
|
b = b + Argument(ArgType.IMM, int(v, base=10))()
|
||||||
return b
|
return b
|
||||||
|
|
||||||
class LabelArgument(Argument):
|
class LabelArgument(Argument):
|
||||||
|
@ -210,6 +210,25 @@ class Instruction(Enum):
|
||||||
J = "JE", "_render_j", ArgType.LAB
|
J = "JE", "_render_j", ArgType.LAB
|
||||||
JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL
|
JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL
|
||||||
DB = 11, "_render_default", ArgType.DAT, ArgType.STR
|
DB = 11, "_render_default", ArgType.DAT, ArgType.STR
|
||||||
|
READ_ADC = 12, "_render_default", ArgType.VAL, ArgType.REG
|
||||||
|
READ_DAC = 13, "_render_default", ArgType.VAL, ArgType.REG
|
||||||
|
WRITE_DAC = 14, "_render_default", ArgType.VAL, ArgType.VAL
|
||||||
|
SLEEP = 15, "_render_default", ArgType.VAL
|
||||||
|
CLOOP_READ = 16, "_render_default", ArgType.VAL, ArgType.REG, ArgType.REG
|
||||||
|
CLOOP_WRITE = 17, "_render_default", ArgType.VAL, ArgType.VAL, ArgType.VAL
|
||||||
|
WF_LOAD = 18, "_render_default", ArgType.VAL, ArgType.DAT
|
||||||
|
WF_ARM = 19, "_render_default", ArgType.VAL, ArgType.VAL, ArgType.VAL
|
||||||
|
SENDVAL = 20, "_render_default", ArgType.VAL
|
||||||
|
SENDDAT = 21, "_render_default", ArgType.DAT
|
||||||
|
WF_DISARM = 22, "_render_default", ArgType.VAL
|
||||||
|
TAKE_ADC = 23, "_render_default", ArgType.VAL, ArgType.VAL
|
||||||
|
RELEASE_ADC = 24, "_render_default", ArgType.VAL
|
||||||
|
TAKE_DAC = 25, "_render_default", ArgType.VAL, ArgType.VAL
|
||||||
|
RELEASE_DAC = 26, "_render_default", ArgType.VAL
|
||||||
|
TAKE_WF = 27, "_render_default", ArgType.VAL, ArgType.VAL
|
||||||
|
RELEASE_WF = 28, "_render_default", ArgType.VAL
|
||||||
|
TAKE_CLOOP = 29, "_render_default", ArgType.VAL
|
||||||
|
RELEASE_CLOOP = 30, "_render_default"
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
""" Returns the opcode associated with the Instruction.
|
""" Returns the opcode associated with the Instruction.
|
||||||
|
@ -459,7 +478,7 @@ class Program:
|
||||||
assert len(b) < encoding_types[lablen][0]
|
assert len(b) < encoding_types[lablen][0]
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def __init__(self, reglen=16, datlen=16):
|
def __init__(self, reglen=32, datlen=64):
|
||||||
self.asm = []
|
self.asm = []
|
||||||
self.reglen = reglen
|
self.reglen = reglen
|
||||||
self.datlen = datlen
|
self.datlen = datlen
|
||||||
|
|
15
asm/ffi.py
15
asm/ffi.py
|
@ -60,7 +60,7 @@ class Reader:
|
||||||
|
|
||||||
class CEnv(Structure):
|
class CEnv(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("dats", POINTER(POINTER(c_ubyte))),
|
("dats", POINTER(CReader)),
|
||||||
("datlen", c_size_t),
|
("datlen", c_size_t),
|
||||||
("reg", POINTER(c_uint)),
|
("reg", POINTER(c_uint)),
|
||||||
("reglen", c_size_t),
|
("reglen", c_size_t),
|
||||||
|
@ -68,7 +68,8 @@ class CEnv(Structure):
|
||||||
("stkptr", c_size_t),
|
("stkptr", c_size_t),
|
||||||
("stklen", c_size_t),
|
("stklen", c_size_t),
|
||||||
("r_current", CReader),
|
("r_current", CReader),
|
||||||
("r_start", CReader)
|
("r_start", CReader),
|
||||||
|
("fd", c_int)
|
||||||
]
|
]
|
||||||
|
|
||||||
class RegisterOverflowError(Exception):
|
class RegisterOverflowError(Exception):
|
||||||
|
@ -116,13 +117,7 @@ class Environment:
|
||||||
def getdat(self, n):
|
def getdat(self, n):
|
||||||
if n >= self.cenv.datlen or n < 0:
|
if n >= self.cenv.datlen or n < 0:
|
||||||
raise DataOverflowError(n)
|
raise DataOverflowError(n)
|
||||||
rdr = CReader()
|
rdr = self.cenv.dats[n]
|
||||||
rdr.p = self.cenv.dats[n]
|
|
||||||
# Python does not allow for direct pointer arithmetic
|
|
||||||
rdr_p_v = addressof(rdr.p.contents)
|
|
||||||
r_start_p_v = addressof(self.cenv.r_start.p)
|
|
||||||
|
|
||||||
rdr.left = self.cenv.r_start.left - (rdr_p_v - r_start_p_v)
|
|
||||||
|
|
||||||
l = []
|
l = []
|
||||||
w = CWord()
|
w = CWord()
|
||||||
|
@ -143,7 +138,7 @@ class Environment:
|
||||||
|
|
||||||
def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096):
|
def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096):
|
||||||
cenv = CEnv()
|
cenv = CEnv()
|
||||||
cenv.dats = (POINTER(c_ubyte) * datlen)()
|
cenv.dats = (CReader * datlen)()
|
||||||
cenv.datlen = datlen
|
cenv.datlen = datlen
|
||||||
|
|
||||||
cenv.reglen = reglen
|
cenv.reglen = reglen
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
from comm import *
|
||||||
|
|
||||||
|
# These require a connection!
|
||||||
|
def test_print_char():
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line(f"SENDVAL 100")
|
||||||
|
assert connect_exec(p) == b'100'
|
||||||
|
|
||||||
|
def test_print_string():
|
||||||
|
p = Program()
|
||||||
|
p.parse_lines([
|
||||||
|
"j .l",
|
||||||
|
f"db d0 {[ord(x) for x in 'hello world']}",
|
||||||
|
".l",
|
||||||
|
"senddat d0"
|
||||||
|
])
|
||||||
|
return connect_exec(p).decode()
|
||||||
|
|
||||||
|
def test_run_adc():
|
||||||
|
p = Program()
|
||||||
|
p.parse_lines([
|
||||||
|
"read_adc 0 r0",
|
||||||
|
"sendval r0"
|
||||||
|
])
|
||||||
|
return connect_exec(p).decode()
|
260
creole.c
260
creole.c
|
@ -12,8 +12,17 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||||
|
|
||||||
#include "creole.h"
|
#ifndef CREOLE_TEST
|
||||||
|
# include <zephyr/kernel.h>
|
||||||
|
# include <zephyr/logging/log.h>
|
||||||
|
# include <zephyr/sys_clock.h>
|
||||||
|
# include "access.h"
|
||||||
|
# include "control_loop_cmds.h"
|
||||||
|
# include "sock.h"
|
||||||
|
LOG_MODULE_REGISTER(creole, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "creole.h"
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Static information
|
* Static information
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
@ -37,7 +46,7 @@ enum creole_arg_type {
|
||||||
[i] = v,
|
[i] = v,
|
||||||
* in C89 indicies are implicit from 0 to the maximum filled-in value.
|
* in C89 indicies are implicit from 0 to the maximum filled-in value.
|
||||||
*/
|
*/
|
||||||
#define defop(s, n, a1, a2, a3) {n, {a1, a2, a3}}
|
#define defop(s, n, a1, a2, a3) [CREOLE_##s] = {n, {a1, a2, a3}}
|
||||||
static const struct {
|
static const struct {
|
||||||
int arglen;
|
int arglen;
|
||||||
enum creole_arg_type argtype[CREOLE_MAX_ARG];
|
enum creole_arg_type argtype[CREOLE_MAX_ARG];
|
||||||
|
@ -53,7 +62,28 @@ static const struct {
|
||||||
defop(JLE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
defop(JLE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
||||||
defop(JE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
defop(JE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
||||||
defop(JNE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
defop(JNE, 3, TYPE_IMM, TYPE_VAL, TYPE_VAL),
|
||||||
defop(DB, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE)
|
defop(DB, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(READ_ADC, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
|
||||||
|
defop(READ_DAC, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
|
||||||
|
defop(WRITE_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(SLEEP, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(CLOOP_READ, 2, TYPE_VAL, TYPE_REG, TYPE_NONE),
|
||||||
|
defop(CLOOP_WRITE, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(WF_LOAD, 2, TYPE_VAL, TYPE_IMM, TYPE_NONE),
|
||||||
|
defop(WF_ARM, 3, TYPE_VAL, TYPE_VAL, TYPE_VAL),
|
||||||
|
defop(SENDVAL, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(SENDDAT, 1, TYPE_IMM, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(WF_DISARM, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(TAKE_ADC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(RELEASE_ADC, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(TAKE_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(RELEASE_DAC, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(TAKE_WF, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(RELEASE_WF, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(TAKE_CLOOP, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(RELEASE_CLOOP, 0, TYPE_NONE, TYPE_NONE, TYPE_NONE),
|
||||||
|
defop(SWITCH_ADC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE),
|
||||||
|
defop(SWITCH_DAC, 2, TYPE_VAL, TYPE_VAL, TYPE_NONE)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -327,6 +357,7 @@ int creole_encode(creole_word i, unsigned encode_to, unsigned high_bits,
|
||||||
struct ins {
|
struct ins {
|
||||||
unsigned char *start;
|
unsigned char *start;
|
||||||
unsigned char *datapt;
|
unsigned char *datapt;
|
||||||
|
size_t dataptlen;
|
||||||
enum creole_opcode opcode;
|
enum creole_opcode opcode;
|
||||||
creole_word w[CREOLE_MAX_ARG];
|
creole_word w[CREOLE_MAX_ARG];
|
||||||
creole_word w_flags[CREOLE_MAX_ARG];
|
creole_word w_flags[CREOLE_MAX_ARG];
|
||||||
|
@ -393,10 +424,12 @@ parse_line(struct creole_env *env, struct ins *ins, struct creole_reader *r)
|
||||||
|
|
||||||
if (ins->opcode == CREOLE_DB) {
|
if (ins->opcode == CREOLE_DB) {
|
||||||
ins->datapt = r->p;
|
ins->datapt = r->p;
|
||||||
|
ins->dataptlen = 0;
|
||||||
do {
|
do {
|
||||||
if (!creole_decode(r, &w))
|
if (!creole_decode(r, &w))
|
||||||
return CREOLE_ARG_READ_ERROR;
|
return CREOLE_ARG_READ_ERROR;
|
||||||
} while (w.len != 1);
|
} while (w.len != 1);
|
||||||
|
ins->dataptlen = r->p - ins->datapt - 1;
|
||||||
if (w.word != 0)
|
if (w.word != 0)
|
||||||
return CREOLE_LAST_READ_ERROR;
|
return CREOLE_LAST_READ_ERROR;
|
||||||
return CREOLE_COMPILE_OK;
|
return CREOLE_COMPILE_OK;
|
||||||
|
@ -419,7 +452,8 @@ add_to_env(struct creole_env *env, struct ins *ins)
|
||||||
{
|
{
|
||||||
switch (ins->opcode) {
|
switch (ins->opcode) {
|
||||||
case CREOLE_DB:
|
case CREOLE_DB:
|
||||||
env->dats[ins->w[0]] = ins->datapt;
|
env->dats[ins->w[0]].p = ins->datapt;
|
||||||
|
env->dats[ins->w[0]].left = ins->dataptlen;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
@ -526,6 +560,67 @@ int creole_jump(struct creole_env *env, creole_word off)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CREOLE_TEST
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
load_into_array(const struct creole_reader *start, creole_word *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
struct creole_word w;
|
||||||
|
struct creole_reader r = *start;
|
||||||
|
|
||||||
|
while (creole_decode(&r, &w) && i < buflen) {
|
||||||
|
buf[i++] = w.word;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static creole_word
|
||||||
|
upsilon_load_waveform(struct creole_env *env, creole_word slot,
|
||||||
|
creole_word db)
|
||||||
|
{
|
||||||
|
creole_word buf[MAX_WL_SIZE];
|
||||||
|
size_t len = load_into_array(env->dats + db, buf, ARRAY_SIZE(buf));
|
||||||
|
if (len < MAX_WL_SIZE)
|
||||||
|
return 0;
|
||||||
|
return waveform_load(buf, slot, K_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static creole_word
|
||||||
|
upsilon_sendval(struct creole_env *env, creole_word num)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
struct bufptr bp = {buf, sizeof(buf)};
|
||||||
|
|
||||||
|
return sock_printf(env->fd, &bp, "%u", num) == BUF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static creole_word
|
||||||
|
upsilon_senddat(struct creole_env *env, creole_word db)
|
||||||
|
{
|
||||||
|
#define SENDDAT_BUFLEN 1024
|
||||||
|
char buf[SENDDAT_BUFLEN];
|
||||||
|
struct bufptr bp = {buf, 0};
|
||||||
|
struct creole_word w;
|
||||||
|
struct creole_reader r = env->dats[db];
|
||||||
|
|
||||||
|
while (creole_decode(&r, &w) && bp.left < SENDDAT_BUFLEN) {
|
||||||
|
if (w.word > 0xFF)
|
||||||
|
return -EINVAL;
|
||||||
|
buf[bp.left++] = w.word;
|
||||||
|
}
|
||||||
|
if (r.left != 0) {
|
||||||
|
return -E2BIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock_write_buf(env->fd, &bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CREOLE_TEST */
|
||||||
|
|
||||||
|
/* Upsilon interface */
|
||||||
|
|
||||||
#define chk_sign_op(OPER) do { \
|
#define chk_sign_op(OPER) do { \
|
||||||
switch (check_sign_bits(ins.w_flags[1], ins.w_flags[2])) { \
|
switch (check_sign_bits(ins.w_flags[1], ins.w_flags[2])) { \
|
||||||
case ALL_UNSIGNED: \
|
case ALL_UNSIGNED: \
|
||||||
|
@ -559,25 +654,32 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
|
|
||||||
switch (ins.opcode) {
|
switch (ins.opcode) {
|
||||||
case CREOLE_DB:
|
case CREOLE_DB:
|
||||||
env->dats[ins.w[0]] = ins.datapt;
|
env->dats[ins.w[0]].p = ins.datapt;
|
||||||
|
env->dats[ins.w[0]].left = ins.dataptlen;
|
||||||
|
break;
|
||||||
|
|
||||||
case CREOLE_PUSH:
|
case CREOLE_PUSH:
|
||||||
check(read_val(env, &ins, 0, &a1));
|
check(read_val(env, &ins, 0, &a1));
|
||||||
check(creole_push(env, a1));
|
check(creole_push(env, a1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_POP:
|
case CREOLE_POP:
|
||||||
check(creole_pop(env, &a1));
|
check(creole_pop(env, &a1));
|
||||||
check(creole_reg_write(env, ins.w[0], a1));
|
check(creole_reg_write(env, ins.w[0], a1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_ADD:
|
case CREOLE_ADD:
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
check(read_val(env, &ins, 2, &a2));
|
check(read_val(env, &ins, 2, &a2));
|
||||||
check(creole_reg_write(env, ins.w[0], a1 + a2));
|
check(creole_reg_write(env, ins.w[0], a1 + a2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_MUL:
|
case CREOLE_MUL:
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
check(read_val(env, &ins, 2, &a2));
|
check(read_val(env, &ins, 2, &a2));
|
||||||
check(creole_reg_write(env, ins.w[0], a1 * a2));
|
check(creole_reg_write(env, ins.w[0], a1 * a2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_DIV:
|
case CREOLE_DIV:
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
check(read_val(env, &ins, 2, &a2));
|
check(read_val(env, &ins, 2, &a2));
|
||||||
|
@ -587,10 +689,12 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
chk_sign_op(/);
|
chk_sign_op(/);
|
||||||
check(creole_reg_write(env, ins.w[0], a1));
|
check(creole_reg_write(env, ins.w[0], a1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_SYS:
|
case CREOLE_SYS:
|
||||||
check(read_val(env, &ins, 0, sc));
|
check(read_val(env, &ins, 0, sc));
|
||||||
rcode = CREOLE_STEP_SYSCALL;
|
rcode = CREOLE_STEP_SYSCALL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_JL:
|
case CREOLE_JL:
|
||||||
check(read_val(env, &ins, 0, &a0));
|
check(read_val(env, &ins, 0, &a0));
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
@ -599,6 +703,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
if (a1 && !creole_jump(env, a0))
|
if (a1 && !creole_jump(env, a0))
|
||||||
return CREOLE_JUMP_OVERFLOW;
|
return CREOLE_JUMP_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_JLE:
|
case CREOLE_JLE:
|
||||||
check(read_val(env, &ins, 0, &a0));
|
check(read_val(env, &ins, 0, &a0));
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
@ -607,6 +712,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
if (a1 && !creole_jump(env, a0))
|
if (a1 && !creole_jump(env, a0))
|
||||||
return CREOLE_JUMP_OVERFLOW;
|
return CREOLE_JUMP_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_JE:
|
case CREOLE_JE:
|
||||||
check(read_val(env, &ins, 0, &a0));
|
check(read_val(env, &ins, 0, &a0));
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
@ -614,6 +720,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
if (a1 == a2 && !creole_jump(env, a0))
|
if (a1 == a2 && !creole_jump(env, a0))
|
||||||
return CREOLE_JUMP_OVERFLOW;
|
return CREOLE_JUMP_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREOLE_JNE:
|
case CREOLE_JNE:
|
||||||
check(read_val(env, &ins, 0, &a0));
|
check(read_val(env, &ins, 0, &a0));
|
||||||
check(read_val(env, &ins, 1, &a1));
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
@ -621,8 +728,151 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
if (a1 != a2 && !creole_jump(env, a0))
|
if (a1 != a2 && !creole_jump(env, a0))
|
||||||
return CREOLE_JUMP_OVERFLOW;
|
return CREOLE_JUMP_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef CREOLE_TEST
|
||||||
|
|
||||||
|
case CREOLE_READ_ADC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
a1 = adc_read(a0, K_FOREVER, &a2);
|
||||||
|
check(creole_reg_write(env, ins.w[1], a2));
|
||||||
|
check(creole_push(env, a1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_READ_DAC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
a1 = dac_read_write(a0, 0x1 << 23 | 0x1 << 20, K_FOREVER, NULL);
|
||||||
|
if (a1 == 0) {
|
||||||
|
a1 = dac_read_write(a0, 0, K_FOREVER, &a2);
|
||||||
|
check(creole_reg_write(env, ins.w[1], a2));
|
||||||
|
}
|
||||||
|
check(creole_push(env, a1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_WRITE_DAC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
|
||||||
|
a2 = dac_read_write(a0, 0x1 << 20 | a1, K_FOREVER, NULL);
|
||||||
|
check(creole_push(env, a2));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_SLEEP:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
k_sleep(K_USEC(a0));
|
||||||
|
check(creole_push(env, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_CLOOP_READ:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 0, &a1));
|
||||||
|
check(read_val(env, &ins, 0, &a2));
|
||||||
|
|
||||||
|
if (valid_register(env, a1) && valid_register(env, a2)) {
|
||||||
|
a0 = cloop_read(a0, env->reg + a1, env->reg + a2, K_FOREVER);
|
||||||
|
check(creole_push(env, a0));
|
||||||
|
} else {
|
||||||
|
check(creole_push(env, -EINVAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_CLOOP_WRITE:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 0, &a1));
|
||||||
|
check(read_val(env, &ins, 0, &a2));
|
||||||
|
|
||||||
|
a0 = cloop_write(a0, a1, a2, K_FOREVER);
|
||||||
|
check(creole_push(env, a0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_WF_LOAD:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
check(creole_push(env, upsilon_load_waveform(env, a0, a1)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_WF_ARM:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
check(read_val(env, &ins, 2, &a2));
|
||||||
|
|
||||||
|
check(creole_push(env, waveform_arm(a0, a1, a2, K_FOREVER)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_WF_DISARM:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, waveform_disarm(a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_SENDVAL:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, upsilon_sendval(env, a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_SENDDAT:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, upsilon_senddat(env, a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_TAKE_ADC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 0, &a1));
|
||||||
|
check(creole_push(env, adc_take(a0, K_USEC(a1))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_RELEASE_ADC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, adc_release(a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_TAKE_DAC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 0, &a1));
|
||||||
|
check(creole_push(env, dac_take(a0, K_USEC(a1))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_RELEASE_DAC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, dac_release(a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_TAKE_WF:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 0, &a1));
|
||||||
|
check(creole_push(env, waveform_take(a0, K_USEC(a1))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_RELEASE_WF:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, waveform_release(a0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_TAKE_CLOOP:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(creole_push(env, cloop_take(K_USEC(a0))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_RELEASE_CLOOP:
|
||||||
|
check(creole_push(env, cloop_release()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_SWITCH_ADC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
check(creole_push(env, adc_switch(a0, a1, K_FOREVER)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREOLE_SWITCH_DAC:
|
||||||
|
check(read_val(env, &ins, 0, &a0));
|
||||||
|
check(read_val(env, &ins, 1, &a1));
|
||||||
|
check(creole_push(env, dac_switch(a0, a1, K_FOREVER)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif /* CREOLE_TEST */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rcode = CREOLE_STEP_UNKNOWN_OPCODE;
|
rcode = CREOLE_STEP_UNKNOWN_OPCODE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
49
creole.h
49
creole.h
|
@ -34,18 +34,39 @@ typedef CREOLE_WORD creole_word;
|
||||||
typedef CREOLE_SIGNED_WORD creole_signed;
|
typedef CREOLE_SIGNED_WORD creole_signed;
|
||||||
|
|
||||||
enum creole_opcode {
|
enum creole_opcode {
|
||||||
CREOLE_NOOP,
|
CREOLE_NOOP = 0,
|
||||||
CREOLE_PUSH,
|
CREOLE_PUSH = 1,
|
||||||
CREOLE_POP,
|
CREOLE_POP = 2,
|
||||||
CREOLE_ADD,
|
CREOLE_ADD = 3,
|
||||||
CREOLE_MUL,
|
CREOLE_MUL = 4,
|
||||||
CREOLE_DIV,
|
CREOLE_DIV = 5,
|
||||||
CREOLE_SYS,
|
CREOLE_SYS = 6,
|
||||||
CREOLE_JL,
|
CREOLE_JL = 7,
|
||||||
CREOLE_JLE,
|
CREOLE_JLE = 8,
|
||||||
CREOLE_JE,
|
CREOLE_JE = 9,
|
||||||
CREOLE_JNE,
|
CREOLE_JNE = 10,
|
||||||
CREOLE_DB,
|
CREOLE_DB = 11,
|
||||||
|
CREOLE_READ_ADC = 12,
|
||||||
|
CREOLE_READ_DAC = 13,
|
||||||
|
CREOLE_WRITE_DAC = 14,
|
||||||
|
CREOLE_SLEEP = 15,
|
||||||
|
CREOLE_CLOOP_READ = 16,
|
||||||
|
CREOLE_CLOOP_WRITE = 17,
|
||||||
|
CREOLE_WF_LOAD = 18,
|
||||||
|
CREOLE_WF_ARM = 19,
|
||||||
|
CREOLE_SENDVAL = 20,
|
||||||
|
CREOLE_SENDDAT = 21,
|
||||||
|
CREOLE_WF_DISARM = 22,
|
||||||
|
CREOLE_TAKE_ADC = 23,
|
||||||
|
CREOLE_RELEASE_ADC = 24,
|
||||||
|
CREOLE_TAKE_DAC = 25,
|
||||||
|
CREOLE_RELEASE_DAC = 26,
|
||||||
|
CREOLE_TAKE_WF = 27,
|
||||||
|
CREOLE_RELEASE_WF = 28,
|
||||||
|
CREOLE_TAKE_CLOOP = 29,
|
||||||
|
CREOLE_RELEASE_CLOOP = 30,
|
||||||
|
CREOLE_SWITCH_ADC = 31,
|
||||||
|
CREOLE_SWITCH_DAC = 32,
|
||||||
CREOLE_OPCODE_LEN
|
CREOLE_OPCODE_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,7 +117,7 @@ struct creole_reader {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct creole_env {
|
struct creole_env {
|
||||||
unsigned char **dats;
|
struct creole_reader *dats;
|
||||||
size_t datlen;
|
size_t datlen;
|
||||||
|
|
||||||
creole_word *reg;
|
creole_word *reg;
|
||||||
|
@ -107,6 +128,8 @@ struct creole_env {
|
||||||
|
|
||||||
struct creole_reader r_current;
|
struct creole_reader r_current;
|
||||||
struct creole_reader r_start;
|
struct creole_reader r_start;
|
||||||
|
|
||||||
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
int creole_decode(struct creole_reader *r, struct creole_word *w);
|
int creole_decode(struct creole_reader *r, struct creole_word *w);
|
||||||
|
|
Loading…
Reference in New Issue