├── .gitignore ├── LICENSE ├── Makefile ├── README ├── able.h ├── config.mk.def ├── edge.c ├── edge.h ├── link.c ├── link.h ├── mesg.c ├── mesg.h ├── misc ├── .gitignore ├── LICENSE ├── Makefile ├── README ├── config.mk.def ├── core.c ├── core.h ├── host.c ├── host.h └── misc.h ├── node.c ├── node.h ├── task.c └── task.h /.gitignore: -------------------------------------------------------------------------------- 1 | libable.a 2 | config.mk 3 | *.o 4 | *~ 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Mark Smith 2 | Copyright (c) 2015 Ryan Siddle 3 | Copyright (c) 2015 Merj Ltd 4 | 5 | Permission to use, copy, modify, and distribute this software for any purpose 6 | with or without fee is hereby granted, provided that the above copyright notice 7 | and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 13 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 15 | THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIB?=able 2 | SRCS=edge.c node.c link.c mesg.c task.c 3 | HDRS=edge.h node.h link.h mesg.h task.h able.h 4 | 5 | .include "config.mk" 6 | 7 | OBJS+=${SRCS:N*.h:R:S/$/.o/} 8 | 9 | .PHONY: build clean install uninstall 10 | 11 | build: lib${LIB}.a 12 | 13 | clean: 14 | -rm -vf ${OBJS} lib${LIB}.a 15 | 16 | install: lib${LIB}.a 17 | @mkdir -p ${LIBDIR} 18 | install -m 0644 lib${LIB}.a ${LIBDIR}/lib${LIB}.a 19 | @mkdir -p ${INCDIR}/${LIB} 20 | .for HDR in ${HDRS} 21 | cp ${HDR} ${INCDIR}/${LIB}/${HDR} 22 | .endfor 23 | 24 | uninstall: 25 | -rm -vf ${LIBDIR}/lib${LIB}.a 26 | -rm -vrf ${INCDIR}/${LIB} 27 | 28 | lib${LIB}.a: ${HDRS} ${OBJS} 29 | @rm -vf lib${LIB}.a 30 | ${AR} ${ARFLAGS} lib${LIB}.a ${OBJS} 31 | ${RANLIB} lib${LIB}.a 32 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | libable 2 | 3 | libable implements an efficient, portable and secure general-purpose virtual 4 | machine and virtual network as a library 5 | 6 | REQUIREMENTS 7 | 8 | BSD Make 9 | Clang 10 | 11 | GETTING STARTED 12 | 13 | Building and installing on OpenBSD 14 | 15 | $ cp config.mk.def config.mk 16 | $ make install 17 | ... 18 | $ 19 | 20 | Building and installing on Ubuntu 21 | 22 | # apt install bmake clang 23 | ... 24 | # exit 25 | $ cp config.mk.def config.mk 26 | $ bmake -DCOMPAT_LINUX install 27 | ... 28 | $ 29 | 30 | Building and installing on macOS 31 | 32 | # brew install bmake 33 | ... 34 | # exit 35 | $ cp config.mk.def config.mk 36 | $ bmake -DCOMPAT_MACOS install 37 | ... 38 | $ 39 | 40 | GETTING INVOLVED 41 | 42 | Contact Details 43 | 44 | Find us online at ablevm.org or email us at team@ablevm.org 45 | 46 | Code of Conduct 47 | 48 | Respect each other and please don't spam 49 | 50 | LICENSE 51 | 52 | ISC-style license 53 | 54 | DETAILS 55 | 56 | Virtual Network 57 | 58 | Messages 59 | 60 | -40 16 bits sent bytes 61 | -30 16 bits body bytes 62 | -20 32 bits mark 63 | 00 body 64 | 65 | 64 KiB - 8 byte header maximum single deliverable message 66 | -------------------------------------------------------------------------------- /able.h: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | #include "node.h" 3 | #include "link.h" 4 | #include "mesg.h" 5 | #include "task.h" 6 | -------------------------------------------------------------------------------- /config.mk.def: -------------------------------------------------------------------------------- 1 | PREFIX?=/usr/local 2 | BINDIR=${PREFIX}/bin 3 | INCDIR=${PREFIX}/include 4 | LIBDIR=${PREFIX}/lib 5 | MANDIR=${PREFIX}/man 6 | 7 | CC=clang 8 | CFLAGS=-I${INCDIR} -g -O2 -std=c11 -pedantic -Wall -Wno-zero-length-array -Wno-gnu-label-as-value -Wno-gnu-designator -Wno-gnu-empty-struct 9 | 10 | .ifdef DEBUG 11 | CFLAGS+=-DDEBUG=${DEBUG} 12 | .endif 13 | 14 | .ifdef COMPAT_LINUX 15 | CFLAGS+=-DABLE_COMPAT_LINUX -D_GNU_SOURCE 16 | .endif 17 | .ifdef COMPAT_MACOS 18 | CFLAGS+=-DABLE_COMPAT_MACOS 19 | .endif 20 | 21 | AR=ar 22 | ARFLAGS=rc 23 | 24 | RANLIB=ranlib 25 | -------------------------------------------------------------------------------- /edge.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "edge.h" 3 | #include 4 | 5 | int 6 | able_edge_clip(able_edge_t *edge, void *data, size_t size) { 7 | if (atomic_load(&edge->rc) > 0) 8 | return 1; 9 | int v; 10 | v = 0; 11 | while (!atomic_compare_exchange_weak(&edge->sl, &v, -1)) { 12 | if (v == 1) 13 | return -1; 14 | v = 0; 15 | } 16 | if (atomic_load(&edge->rc) > 0) { 17 | atomic_store(&edge->sl, 0); 18 | return 1; 19 | } 20 | edge->s = data; 21 | edge->sc = size; 22 | atomic_store(&edge->sl, 0); 23 | return 0; 24 | } 25 | 26 | size_t 27 | able_edge_recv(able_edge_t *edge) { 28 | return atomic_exchange(&edge->rc, 0); 29 | } 30 | 31 | int 32 | able_edge_send_long(able_edge_t *edge, size_t size, void **data) { 33 | if (size == 0) 34 | return 1; 35 | int v; 36 | v = 0; 37 | while (!atomic_compare_exchange_weak(&edge->sl, &v, -1)) { 38 | if (v == 1) 39 | return -1; 40 | v = 0; 41 | } 42 | if (edge->sc < size) { 43 | atomic_store(&edge->sl, 0); 44 | return -2; 45 | } 46 | atomic_store(&edge->sl, 1); 47 | edge->tc = size; 48 | *data = edge->s; 49 | return 0; 50 | } 51 | 52 | int 53 | able_edge_send_done(able_edge_t *edge, size_t size) { 54 | if (size == 0) { 55 | atomic_store(&edge->sl, 0); 56 | return 0; 57 | } 58 | if (size > edge->tc) { 59 | atomic_store(&edge->sl, 0); 60 | return 2; 61 | } 62 | edge->s += size; 63 | edge->sc -= size; 64 | atomic_fetch_add(&edge->rc, size); 65 | atomic_store(&edge->sl, 0); 66 | return 0; 67 | } 68 | 69 | int 70 | able_edge_send(able_edge_t *edge, const void *data, size_t size) { 71 | void *m; 72 | int y; 73 | y = able_edge_send_long(edge, size, &m); 74 | if (y != 0) 75 | return y; 76 | memcpy(m, data, size); 77 | return able_edge_send_done(edge, size); 78 | } 79 | -------------------------------------------------------------------------------- /edge.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | atomic_int sl; 3 | uint8_t *s; 4 | size_t sc; 5 | atomic_size_t rc; 6 | size_t tc; 7 | } able_edge_t; 8 | 9 | int 10 | able_edge_clip(able_edge_t *edge, void *data, size_t size); 11 | 12 | size_t 13 | able_edge_recv(able_edge_t *edge); 14 | 15 | int 16 | able_edge_send_long(able_edge_t *edge, size_t size, void **data); 17 | 18 | int 19 | able_edge_send_done(able_edge_t *edge, size_t size); 20 | 21 | int 22 | able_edge_send(able_edge_t *edge, const void *data, size_t size); 23 | -------------------------------------------------------------------------------- /link.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "edge.h" 3 | #include 4 | #include "node.h" 5 | #include "link.h" 6 | #include 7 | 8 | int 9 | able_link_join(able_link_t *link, able_edge_t *edge, uintptr_t mark, void *node) { 10 | int v; 11 | v = 0; 12 | while (!atomic_compare_exchange_weak(&link->sl, &v, -1)) { 13 | if (v == 1) 14 | return -1; 15 | v = 0; 16 | } 17 | link->e = edge; 18 | link->i = mark; 19 | link->n = node; 20 | atomic_store(&link->sl, 0); 21 | return 0; 22 | } 23 | 24 | int 25 | able_link_send_long(able_link_t *link, size_t size, void **data) { 26 | if (size == 0) 27 | return 1; 28 | int v; 29 | v = 0; 30 | while (!atomic_compare_exchange_weak(&link->sl, &v, -1)) { 31 | if (v == 1) 32 | return -3; 33 | v = 0; 34 | } 35 | if (link->e == NULL) { 36 | atomic_store(&link->sl, 0); 37 | return 3; 38 | } 39 | int y; 40 | y = able_edge_send_long(link->e, size, data); 41 | if (y != 0) { 42 | atomic_store(&link->sl, 0); 43 | return y; 44 | } 45 | atomic_store(&link->sl, 1); 46 | return 0; 47 | } 48 | 49 | int 50 | able_link_send_done(able_link_t *link, size_t size) { 51 | able_edge_t *e; 52 | e = link->e; 53 | int y; 54 | y = able_edge_send_done(e, size); 55 | if (y != 0) { 56 | atomic_store(&link->sl, 0); 57 | return y; 58 | } 59 | void *n; 60 | n = link->n; 61 | atomic_store(&link->sl, 0); 62 | return able_link_node_post_shim(n, e); 63 | } 64 | 65 | int 66 | able_link_send(able_link_t *link, const void *data, size_t size) { 67 | void *mb; 68 | int y; 69 | y = able_link_send_long(link, size, &mb); 70 | if (y != 0) 71 | return y; 72 | memcpy(mb, data, size); 73 | return able_link_send_done(link, size); 74 | } 75 | -------------------------------------------------------------------------------- /link.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | atomic_int sl; 3 | able_edge_t *e; 4 | uintptr_t i; 5 | void *n; 6 | } able_link_t; 7 | 8 | int 9 | able_link_join(able_link_t *link, able_edge_t *edge, uintptr_t mark, void *node); 10 | 11 | int 12 | able_link_send_long(able_link_t *link, size_t size, void **data); 13 | 14 | int 15 | able_link_send_done(able_link_t *link, size_t size); 16 | 17 | int 18 | able_link_send(able_link_t *link, const void *data, size_t size); 19 | 20 | int 21 | able_link_node_post_shim(void *node, const able_edge_t *edge); 22 | -------------------------------------------------------------------------------- /mesg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "edge.h" 3 | #include 4 | #include "node.h" 5 | #include "link.h" 6 | #include "mesg.h" 7 | #include 8 | 9 | int 10 | able_mesg_link_send_long(able_link_t *link, uint16_t size, void **data) { 11 | size_t sc; 12 | sc = ABLE_MESG_SIZE(able_mesg_t, size); 13 | if (sc > UINT16_MAX) 14 | return 4; 15 | able_mesg_t *m; 16 | int y; 17 | y = able_link_send_long(link, sc, (void **)&m); 18 | if (y != 0) 19 | return y; 20 | m->i = link->i; 21 | *data = m->b; 22 | return 0; 23 | } 24 | 25 | int 26 | able_mesg_link_send_done(able_link_t *link, uint16_t size) { 27 | size_t sc; 28 | sc = ABLE_MESG_SIZE(able_mesg_t, size); 29 | if (sc > UINT16_MAX) 30 | return 4; 31 | able_mesg_t *m; 32 | m = (able_mesg_t *)link->e->s; 33 | m->sc = sc; 34 | m->bc = size; 35 | return able_link_send_done(link, sc); 36 | } 37 | 38 | int 39 | able_mesg_link_send(able_link_t *link, const void *data, uint16_t size) { 40 | void *mb; 41 | int y; 42 | y = able_mesg_link_send_long(link, size, &mb); 43 | if (y != 0) 44 | return y; 45 | memcpy(mb, data, size); 46 | return able_mesg_link_send_done(link, size); 47 | } 48 | -------------------------------------------------------------------------------- /mesg.h: -------------------------------------------------------------------------------- 1 | #define ABLE_MESG_SIZE(H, B) \ 2 | (((sizeof(H) + (B)) + ((sizeof(uint64_t)) - 1)) & -(sizeof(uint64_t))) 3 | 4 | typedef struct { 5 | uint16_t sc; 6 | uint16_t bc; 7 | uint32_t i; 8 | uint8_t b[0]; 9 | } able_mesg_t; 10 | 11 | int 12 | able_mesg_link_send_long(able_link_t *link, uint16_t size, void **data); 13 | 14 | int 15 | able_mesg_link_send_done(able_link_t *link, uint16_t size); 16 | 17 | int 18 | able_mesg_link_send(able_link_t *link, const void *data, uint16_t size); 19 | -------------------------------------------------------------------------------- /misc/.gitignore: -------------------------------------------------------------------------------- 1 | libable_misc.a 2 | config.mk 3 | *.o 4 | *~ 5 | -------------------------------------------------------------------------------- /misc/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Mark Smith 2 | Copyright (c) 2015 Ryan Siddle 3 | Copyright (c) 2015 Merj Ltd 4 | 5 | Permission to use, copy, modify, and distribute this software for any purpose 6 | with or without fee is hereby granted, provided that the above copyright notice 7 | and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 13 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 15 | THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /misc/Makefile: -------------------------------------------------------------------------------- 1 | LIB?=able 2 | SUB?=misc 3 | SRCS=core.c host.c 4 | HDRS=core.h host.h misc.h 5 | 6 | .include "config.mk" 7 | 8 | OBJS+=${SRCS:N*.h:R:S/$/.o/} 9 | 10 | .PHONY: build clean install uninstall 11 | 12 | build: lib${LIB}_${SUB}.a 13 | 14 | clean: 15 | -rm -vf ${OBJS} lib${LIB}_${SUB}.a 16 | 17 | install: lib${LIB}_${SUB}.a 18 | @mkdir -p ${LIBDIR}/ 19 | install -m 0644 lib${LIB}_${SUB}.a ${LIBDIR}/lib${LIB}_${SUB}.a 20 | @mkdir -p ${INCDIR}/${LIB}/${SUB}/ 21 | install -m 0444 ${HDRS} ${INCDIR}/${LIB}/${SUB}/ 22 | 23 | uninstall: 24 | -rm -vf ${LIBDIR}/lib${LIB}_${SUB}.a 25 | -rm -vrf ${INCDIR}/${LIB}/${SUB}/ 26 | 27 | lib${LIB}_${SUB}.a: ${HDRS} ${OBJS} 28 | @rm -vf lib${PRO}_${LIB}.a 29 | ${AR} ${ARFLAGS} lib${LIB}_${SUB}.a ${OBJS} 30 | ${RANLIB} lib${LIB}_${SUB}.a 31 | -------------------------------------------------------------------------------- /misc/README: -------------------------------------------------------------------------------- 1 | libable_misc 2 | 3 | libable_misc implements a MISC-inspired virtual machine component as a library 4 | 5 | REQUIREMENTS 6 | 7 | BSD Make 8 | Clang 9 | libable 10 | 11 | GETTING STARTED 12 | 13 | Building and installing on OpenBSD 14 | 15 | $ cp config.mk.def config.mk 16 | $ make install 17 | ... 18 | $ 19 | 20 | Building and installing on Ubuntu 21 | 22 | # apt install bmake clang 23 | ... 24 | # exit 25 | $ cp config.mk.def config.mk 26 | $ bmake -DCOMPAT_LINUX install 27 | ... 28 | $ 29 | 30 | Building and installing on macOS 31 | 32 | # brew install bmake 33 | ... 34 | # exit 35 | $ cp config.mk.def config.mk 36 | $ bmake -DCOMPAT_MACOS install 37 | ... 38 | $ 39 | 40 | GETTING INVOLVED 41 | 42 | Contact Details 43 | 44 | Find us online at ablevm.org or email us at team@ablevm.org 45 | 46 | Code of Conduct 47 | 48 | Respect each other and please don't spam 49 | 50 | LICENSE 51 | 52 | ISC-style license 53 | 54 | DETAILS 55 | 56 | Virtual Machine 57 | 58 | i 59 | p 60 | c... 61 | ...d 62 | r... 63 | 64 | i 8 bits instruction 65 | p 64 bits program counter 66 | d 64 bits ... linear data-stack 67 | c 64 bits ... linear call-stack 68 | r 64 bits ... registers 69 | 70 | 8 bit unencoded instructions 71 | 72 | Byte addressed memory with auto-alignment and auto-framing 73 | 74 | General-purpose registers OR base+offset address registers 75 | 76 | Standard Instruction Set 77 | 78 | 00 ; 08* r! 10 push 18 + 79 | 01 ex 09* r@ 11 pop 19 - 80 | 02+ name ; 0A* @r 12 lshift 1A * 81 | 03+ name 0B* !r 13 ashift 1B /mod 82 | 83 | 04+ if 0C* @r+ 14 not 1C drop 84 | 05+ -if 0D* !r+ 15 and 1D dup 85 | 06+ next 0E* -@r 16 or 1E over 86 | 07+ lit 0F* -!r 17 xor 1F swap 87 | 88 | c20 ; c28* r! h30 ; h38* r! 89 | c21 ex c29* r@ h31 ex h39* r@ 90 | c22+ name ; c2A* @r h32+ name ; h3A* @r 91 | c23+ name c2B* !r h33+ name h3B* !r 92 | 93 | c24+ if c2C* @r+ h34+ if h3C* @r+ 94 | c25+ -if c2D* !r+ h35+ -if h3D* !r+ 95 | c26+ next c2E* -@r h36+ next h3E* -@r 96 | c27+ lit c2F* -!r h37+ lit h3F* -!r 97 | 98 | d40 ; d48* r! 50 i@ 58 rshift 99 | d41 ex d49* r@ 51 i! 59 u< 100 | d42+ name ; d4A* @r 52 = 5A u* 101 | d43+ name d4B* !r 53 < 5B u/mod 102 | 103 | d44+ if d4C* @r+ 54 negate 5C nip 104 | d45+ -if d4D* !r+ 55 abs 5D tuck 105 | d46+ next d4E* -@r 56 min 5E rot 106 | d47+ lit d4F* -!r 57 max 5F -rot 107 | 108 | 60 68 70 78 109 | 61 69 71 79 110 | 62 6A 72 7A 111 | 63 6B 73 7B 112 | 113 | 64 6C 74 7C 114 | 65 6D 75 7D 115 | 66 6E 76 7E 116 | 67 6F 77 7F 117 | 118 | Extended Instruction Set 119 | 120 | 80 wait 88 90 98 121 | 81 clip 89 91 99 122 | 82 recv 8A 92 9A 123 | 83 send 8B 93 9B 124 | 125 | 84 8C 94 9C 126 | 85 8D 95 9D 127 | 86 8E 96 9E 128 | 87 8F 97 9F 129 | 130 | w = 32 bit default 131 | c = 8 bit variant 132 | h = 16 bit variant 133 | d = 64 bit variant 134 | 135 | + followed by n bit immediate where n is w, c, h or d 136 | * followed by 8 bit register 137 | -------------------------------------------------------------------------------- /misc/config.mk.def: -------------------------------------------------------------------------------- 1 | PREFIX?=/usr/local 2 | BINDIR=${PREFIX}/bin 3 | INCDIR=${PREFIX}/include 4 | LIBDIR=${PREFIX}/lib 5 | MANDIR=${PREFIX}/man 6 | 7 | CC=clang 8 | CFLAGS=-I${INCDIR} -g -O2 -std=c11 -pedantic -Wall -Wno-zero-length-array -Wno-gnu-label-as-value -Wno-gnu-designator -Wno-gnu-empty-struct 9 | 10 | .ifdef DEBUG 11 | CFLAGS+=-DDEBUG=${DEBUG} 12 | .endif 13 | 14 | .ifdef COMPAT_LINUX 15 | CFLAGS+=-DABLE_COMPAT_LINUX -D_GNU_SOURCE 16 | .endif 17 | .ifdef COMPAT_MACOS 18 | CFLAGS+=-DABLE_COMPAT_MACOS 19 | .endif 20 | 21 | AR=ar 22 | ARFLAGS=rc 23 | 24 | RANLIB=ranlib 25 | -------------------------------------------------------------------------------- /misc/core.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "core.h" 4 | 5 | #define A ABLE_MISC_CORE_A 6 | #define F ABLE_MISC_CORE_F 7 | #define V ABLE_MISC_CORE_V 8 | #define G ABLE_MISC_CORE_G 9 | #define DSU ABLE_MISC_CORE_DSU 10 | #define DSO ABLE_MISC_CORE_DSO 11 | #define DSI ABLE_MISC_CORE_DSI 12 | #define DSD ABLE_MISC_CORE_DSD 13 | #define CSU ABLE_MISC_CORE_CSU 14 | #define CSO ABLE_MISC_CORE_CSO 15 | #define CSI ABLE_MISC_CORE_CSI 16 | #define CSD ABLE_MISC_CORE_CSD 17 | 18 | #define DS0 ABLE_MISC_CORE_DSV(core, 1) 19 | #define DS1 ABLE_MISC_CORE_DSV(core, 2) 20 | #define DS2 ABLE_MISC_CORE_DSV(core, 3) 21 | #define CS0 ABLE_MISC_CORE_CSV(core, 1) 22 | 23 | // ; 24 | #define INSTX0(S) \ 25 | if (CSU(core, 1)) \ 26 | return -6; \ 27 | core->p = F(UINT##S##_MAX, core->p, (uint##S##_t)CS0); \ 28 | CSD(core); 29 | 30 | // ex 31 | #define INSTX1(S) { \ 32 | if (CSU(core, 1)) \ 33 | return -6; \ 34 | uint##S##_t t; \ 35 | t = CS0; \ 36 | CS0 = core->p; \ 37 | core->p = F(UINT##S##_MAX, core->p, t); \ 38 | } 39 | 40 | // name ; 41 | #define INSTX2(S) { \ 42 | uint64_t p; \ 43 | p = A(sizeof(uint##S##_t), core->p); \ 44 | if (G(core->mc, p, sizeof(uint##S##_t))) \ 45 | return -2; \ 46 | uint##S##_t i; \ 47 | i = V(uint##S##_t, core->m, p); \ 48 | core->p = F(UINT##S##_MAX, p, i); \ 49 | } 50 | 51 | // name 52 | #define INSTX3(S) { \ 53 | if (CSO(core, 1)) \ 54 | return -7; \ 55 | uint64_t p; \ 56 | p = A(sizeof(uint##S##_t), core->p); \ 57 | if (G(core->mc, p, sizeof(uint##S##_t))) \ 58 | return -2; \ 59 | uint##S##_t i; \ 60 | i = V(uint##S##_t, core->m, p); \ 61 | CSI(core); \ 62 | CS0 = p + sizeof(uint##S##_t); \ 63 | core->p = F(UINT##S##_MAX, p, i); \ 64 | } 65 | 66 | // if 67 | #define INSTX4(S) \ 68 | if (DSU(core, 1)) \ 69 | return -6; \ 70 | if (DS0 == 0) { \ 71 | uint64_t p; \ 72 | p = A(sizeof(uint##S##_t), core->p); \ 73 | if (G(core->mc, p, sizeof(uint##S##_t))) \ 74 | return -2; \ 75 | uint##S##_t i; \ 76 | i = V(uint##S##_t, core->m, p); \ 77 | core->p = F(UINT##S##_MAX, p, i); \ 78 | } else \ 79 | core->p = A(sizeof(uint##S##_t), core->p) + sizeof(uint##S##_t); \ 80 | DSD(core); 81 | 82 | // -if 83 | #define INSTX5(S) \ 84 | if (DSU(core, 1)) \ 85 | return -6; \ 86 | if (DS0 < 0) { \ 87 | uint64_t p; \ 88 | p = A(sizeof(uint##S##_t), core->p); \ 89 | if (G(core->mc, p, sizeof(uint##S##_t))) \ 90 | return -2; \ 91 | uint##S##_t i; \ 92 | i = V(uint##S##_t, core->m, p); \ 93 | core->p = F(UINT##S##_MAX, p, i); \ 94 | } else \ 95 | core->p = A(sizeof(uint##S##_t), core->p) + sizeof(uint##S##_t); \ 96 | DSD(core); 97 | 98 | // next 99 | #define INSTX6(S) \ 100 | if (CSU(core, 1)) \ 101 | return -6; \ 102 | if (CS0 != 0) { \ 103 | uint64_t p; \ 104 | p = A(sizeof(uint##S##_t), core->p); \ 105 | if (G(core->mc, p, sizeof(uint##S##_t))) \ 106 | return -2; \ 107 | CS0--; \ 108 | uint##S##_t i; \ 109 | i = V(uint##S##_t, core->m, p); \ 110 | core->p = F(UINT##S##_MAX, p, i); \ 111 | } else { \ 112 | CSD(core); \ 113 | core->p = A(sizeof(uint##S##_t), core->p) + sizeof(uint##S##_t); \ 114 | } 115 | 116 | // lit 117 | #define INSTX7(S) { \ 118 | if (DSO(core, 1)) \ 119 | return -7; \ 120 | uint64_t p; \ 121 | p = A(sizeof(int##S##_t), core->p); \ 122 | if (G(core->mc, p, sizeof(int##S##_t))) \ 123 | return -2; \ 124 | DSI(core); \ 125 | DS0 = V(int##S##_t, core->m, p); \ 126 | core->p = p + sizeof(int##S##_t); \ 127 | } 128 | 129 | // r! 130 | #define INSTX8(S) { \ 131 | if (DSU(core, 1)) \ 132 | return -6; \ 133 | if (G(core->mc, core->p, sizeof(uint8_t))) \ 134 | return -2; \ 135 | uint8_t i; \ 136 | i = V(uint8_t, core->m, core->p); \ 137 | if (i >= core->rc) \ 138 | return -8; \ 139 | core->r[i] = F(UINT##S##_MAX, core->p, (uint##S##_t)DS0); \ 140 | core->p++; \ 141 | DSD(core); \ 142 | } 143 | 144 | // r@ 145 | #define INSTX9(S) { \ 146 | if (DSO(core, 1)) \ 147 | return -7; \ 148 | if (G(core->mc, core->p, sizeof(uint8_t))) \ 149 | return -2; \ 150 | uint8_t i; \ 151 | i = V(uint8_t, core->m, core->p); \ 152 | if (i >= core->rc) \ 153 | return -8; \ 154 | core->p++; \ 155 | DSI(core); \ 156 | DS0 = (int##S##_t)core->r[i]; \ 157 | } 158 | 159 | // @r 160 | #define INSTXA(S) { \ 161 | if (DSO(core, 1)) \ 162 | return -7; \ 163 | uint64_t p; \ 164 | p = core->p; \ 165 | if (G(core->mc, p, sizeof(uint8_t))) \ 166 | return -2; \ 167 | uint8_t i; \ 168 | i = V(uint8_t, core->m, p); \ 169 | if (i >= core->rc) \ 170 | return -8; \ 171 | p++; \ 172 | uint64_t b; \ 173 | b = A(sizeof(int##S##_t), core->r[i]); \ 174 | uint64_t a; \ 175 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 176 | if (G(core->mc, a, sizeof(int##S##_t))) \ 177 | return -2; \ 178 | DSI(core); \ 179 | DS0 = V(int##S##_t, core->m, a); \ 180 | core->r[i] = b; \ 181 | core->p = p; \ 182 | } 183 | 184 | // !r 185 | #define INSTXB(S) { \ 186 | if (DSU(core, 1)) \ 187 | return -6; \ 188 | uint64_t p; \ 189 | p = core->p; \ 190 | if (G(core->mc, p, sizeof(uint8_t))) \ 191 | return -2; \ 192 | uint8_t i; \ 193 | i = V(uint8_t, core->m, p); \ 194 | if (i >= core->rc) \ 195 | return -8; \ 196 | p++; \ 197 | uint64_t b; \ 198 | b = A(sizeof(int##S##_t), core->r[i]); \ 199 | uint64_t a; \ 200 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 201 | if (G(core->mc, a, sizeof(int##S##_t))) \ 202 | return -2; \ 203 | V(int##S##_t, core->m, a) = DS0; \ 204 | DSD(core); \ 205 | core->r[i] = b; \ 206 | core->p = p; \ 207 | } 208 | 209 | // @r+ 210 | #define INSTXC(S) { \ 211 | if (DSO(core, 1)) \ 212 | return -7; \ 213 | uint64_t p; \ 214 | p = core->p; \ 215 | if (G(core->mc, p, sizeof(uint8_t))) \ 216 | return -2; \ 217 | uint8_t i; \ 218 | i = V(uint8_t, core->m, p); \ 219 | if (i >= core->rc) \ 220 | return -8; \ 221 | p++; \ 222 | uint64_t b; \ 223 | b = A(sizeof(int##S##_t), core->r[i]); \ 224 | uint64_t a; \ 225 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 226 | if (G(core->mc, a, sizeof(int##S##_t))) \ 227 | return -2; \ 228 | DSI(core); \ 229 | DS0 = V(int##S##_t, core->m, a); \ 230 | core->r[i] = b + sizeof(int##S##_t); \ 231 | core->p = p; \ 232 | } 233 | 234 | // !r+ 235 | #define INSTXD(S) { \ 236 | if (DSU(core, 1)) \ 237 | return -6; \ 238 | uint64_t p; \ 239 | p = core->p; \ 240 | if (G(core->mc, p, sizeof(uint8_t))) \ 241 | return -2; \ 242 | uint8_t i; \ 243 | i = V(uint8_t, core->m, p); \ 244 | if (i >= core->rc) \ 245 | return -8; \ 246 | p++; \ 247 | uint64_t b; \ 248 | b = A(sizeof(int##S##_t), core->r[i]); \ 249 | uint64_t a; \ 250 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 251 | if (G(core->mc, a, sizeof(int##S##_t))) \ 252 | return -2; \ 253 | V(int##S##_t, core->m, a) = DS0; \ 254 | DSD(core); \ 255 | core->r[i] = b + sizeof(int##S##_t); \ 256 | core->p = p; \ 257 | } 258 | 259 | // -@r 260 | #define INSTXE(S) { \ 261 | if (DSO(core, 1)) \ 262 | return -7; \ 263 | uint64_t p; \ 264 | p = core->p; \ 265 | if (G(core->mc, p, sizeof(uint8_t))) \ 266 | return -2; \ 267 | uint8_t i; \ 268 | i = V(uint8_t, core->m, p); \ 269 | if (i >= core->rc) \ 270 | return -8; \ 271 | p++; \ 272 | uint64_t b; \ 273 | b = A(sizeof(int##S##_t), core->r[i]) - sizeof(int##S##_t); \ 274 | uint64_t a; \ 275 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 276 | if (G(core->mc, a, sizeof(int##S##_t))) \ 277 | return -2; \ 278 | DSI(core); \ 279 | DS0 = V(int##S##_t, core->m, a); \ 280 | core->r[i] = b; \ 281 | core->p = p; \ 282 | } 283 | 284 | // -!r 285 | #define INSTXF(S) { \ 286 | if (DSU(core, 1)) \ 287 | return -6; \ 288 | uint64_t p; \ 289 | p = core->p; \ 290 | if (G(core->mc, p, sizeof(uint8_t))) \ 291 | return -2; \ 292 | uint8_t i; \ 293 | i = V(uint8_t, core->m, p); \ 294 | if (i >= core->rc) \ 295 | return -8; \ 296 | p++; \ 297 | uint64_t b; \ 298 | b = A(sizeof(int##S##_t), core->r[i]) - sizeof(int##S##_t); \ 299 | uint64_t a; \ 300 | a = A(sizeof(int##S##_t), b + core->r[i ^ 1]); \ 301 | if (G(core->mc, a, sizeof(int##S##_t))) \ 302 | return -2; \ 303 | V(int##S##_t, core->m, a) = DS0; \ 304 | DSD(core); \ 305 | core->r[i] = b; \ 306 | core->p = p; \ 307 | } 308 | 309 | // ; 310 | #define INST00 INSTX0(32) 311 | // ex 312 | #define INST01 INSTX1(32) 313 | // name ; 314 | #define INST02 INSTX2(32) 315 | // name 316 | #define INST03 INSTX3(32) 317 | // if 318 | #define INST04 INSTX4(32) 319 | // -if 320 | #define INST05 INSTX5(32) 321 | // next 322 | #define INST06 INSTX6(32) 323 | // lit 324 | #define INST07 INSTX7(32) 325 | // r! 326 | #define INST08 INSTX8(32) 327 | // r@ 328 | #define INST09 INSTX9(32) 329 | // @r 330 | #define INST0A INSTXA(32) 331 | // !r 332 | #define INST0B INSTXB(32) 333 | // @r+ 334 | #define INST0C INSTXC(32) 335 | // !r+ 336 | #define INST0D INSTXD(32) 337 | // @r- 338 | #define INST0E INSTXE(32) 339 | // !r- 340 | #define INST0F INSTXF(32) 341 | 342 | // push 343 | #define INST10 \ 344 | if (DSU(core, 1)) \ 345 | return -6; \ 346 | if (CSO(core, 1)) \ 347 | return -7; \ 348 | CSI(core); \ 349 | CS0 = DS0; \ 350 | DSD(core); 351 | // pop 352 | #define INST11 \ 353 | if (CSU(core, 1)) \ 354 | return -6; \ 355 | if (DSO(core, 1)) \ 356 | return -7; \ 357 | DSI(core); \ 358 | DS0 = CS0; \ 359 | CSD(core); 360 | // lshift 361 | #define INST12 \ 362 | if (DSU(core, 2)) \ 363 | return -6; \ 364 | DS1 = DS1 << DS0; \ 365 | DSD(core); 366 | // ashift 367 | #define INST13 \ 368 | if (DSU(core, 2)) \ 369 | return -6; \ 370 | DS1 = DS1 >> DS0; \ 371 | DSD(core); 372 | // not 373 | #define INST14 \ 374 | if (DSU(core, 1)) \ 375 | return -6; \ 376 | DS0 = ~DS0; 377 | // and 378 | #define INST15 \ 379 | if (DSU(core, 2)) \ 380 | return -6; \ 381 | DS1 = DS1 & DS0; \ 382 | DSD(core); 383 | // or 384 | #define INST16 \ 385 | if (DSU(core, 2)) \ 386 | return -6; \ 387 | DS1 = DS1 | DS0; \ 388 | DSD(core); 389 | // xor 390 | #define INST17 \ 391 | if (DSU(core, 2)) \ 392 | return -6; \ 393 | DS1 = DS1 ^ DS0; \ 394 | DSD(core); 395 | // + 396 | #define INST18 \ 397 | if (DSU(core, 2)) \ 398 | return -6; \ 399 | DS1 = DS1 + DS0; \ 400 | DSD(core); 401 | // - 402 | #define INST19 \ 403 | if (DSU(core, 2)) \ 404 | return -6; \ 405 | DS1 = DS1 - DS0; \ 406 | DSD(core); 407 | // * 408 | #define INST1A \ 409 | if (DSU(core, 2)) \ 410 | return -6; \ 411 | DS1 = DS1 * DS0; \ 412 | DSD(core); 413 | // /mod 414 | #define INST1B { \ 415 | if (DSU(core, 2)) \ 416 | return -6; \ 417 | if (DS0 == 0) \ 418 | return -3; \ 419 | int64_t t0, t1; \ 420 | t0 = DS0; \ 421 | t1 = DS1; \ 422 | DS1 = t1 % t0; \ 423 | DS0 = t1 / t0; \ 424 | } 425 | // drop 426 | #define INST1C \ 427 | if (DSU(core, 1)) \ 428 | return -6; \ 429 | DSD(core); 430 | // dup 431 | #define INST1D \ 432 | if (DSU(core, 1)) \ 433 | return -6; \ 434 | if (DSO(core, 1)) \ 435 | return -7; \ 436 | DSI(core); \ 437 | DS0 = DS1; 438 | // over 439 | #define INST1E { \ 440 | if (DSU(core, 2)) \ 441 | return -6; \ 442 | if (DSO(core, 1)) \ 443 | return -7; \ 444 | int64_t t; \ 445 | t = DS1; \ 446 | DSI(core); \ 447 | DS0 = t; \ 448 | } 449 | // swap 450 | #define INST1F { \ 451 | if (DSU(core, 2)) \ 452 | return -6; \ 453 | int64_t t; \ 454 | t = DS0; \ 455 | DS0 = DS1; \ 456 | DS1 = t; \ 457 | } 458 | 459 | // ; 460 | #define INST20 INSTX0(8) 461 | // ex 462 | #define INST21 INSTX1(8) 463 | // name ; 464 | #define INST22 INSTX2(8) 465 | // name 466 | #define INST23 INSTX3(8) 467 | // if 468 | #define INST24 INSTX4(8) 469 | // -if 470 | #define INST25 INSTX5(8) 471 | // next 472 | #define INST26 INSTX6(8) 473 | // lit 474 | #define INST27 INSTX7(8) 475 | // r! 476 | #define INST28 INSTX8(8) 477 | // r@ 478 | #define INST29 INSTX9(8) 479 | // @r 480 | #define INST2A INSTXA(8) 481 | // !r 482 | #define INST2B INSTXB(8) 483 | // @r+ 484 | #define INST2C INSTXC(8) 485 | // !r+ 486 | #define INST2D INSTXD(8) 487 | // @r- 488 | #define INST2E INSTXE(8) 489 | // !r- 490 | #define INST2F INSTXF(8) 491 | 492 | // ; 493 | #define INST30 INSTX0(16) 494 | // ex 495 | #define INST31 INSTX1(16) 496 | // name ; 497 | #define INST32 INSTX6(16) 498 | // name 499 | #define INST33 INSTX3(16) 500 | // if 501 | #define INST34 INSTX4(16) 502 | // -if 503 | #define INST35 INSTX5(16) 504 | // next 505 | #define INST36 INSTX6(16) 506 | // lit 507 | #define INST37 INSTX7(16) 508 | // r! 509 | #define INST38 INSTX8(16) 510 | // r@ 511 | #define INST39 INSTX9(16) 512 | // @r 513 | #define INST3A INSTXA(16) 514 | // !r 515 | #define INST3B INSTXB(16) 516 | // @r+ 517 | #define INST3C INSTXC(16) 518 | // !r+ 519 | #define INST3D INSTXD(16) 520 | // @r- 521 | #define INST3E INSTXE(16) 522 | // !r- 523 | #define INST3F INSTXF(16) 524 | 525 | // ; 526 | #define INST40 INSTX0(64) 527 | // ex 528 | #define INST41 INSTX1(64) 529 | // name ; 530 | #define INST42 INSTX2(64) 531 | // name 532 | #define INST43 INSTX3(64) 533 | // if 534 | #define INST44 INSTX4(64) 535 | // -if 536 | #define INST45 INSTX5(64) 537 | // next 538 | #define INST46 INSTX6(64) 539 | // lit 540 | #define INST47 INSTX7(64) 541 | // r! 542 | #define INST48 INSTX8(64) 543 | // r@ 544 | #define INST49 INSTX9(64) 545 | // @r 546 | #define INST4A INSTXA(64) 547 | // !r 548 | #define INST4B INSTXB(64) 549 | // @r+ 550 | #define INST4C INSTXC(64) 551 | // !r+ 552 | #define INST4D INSTXD(64) 553 | // @r- 554 | #define INST4E INSTXE(64) 555 | // !r- 556 | #define INST4F INSTXF(64) 557 | 558 | // i@ 559 | #define INST50 \ 560 | if (CSU(core, 1)) \ 561 | return -6; \ 562 | if (DSO(core, 1)) \ 563 | return -7; \ 564 | DSI(core); \ 565 | DS0 = CS0; 566 | // i! 567 | #define INST51 \ 568 | if (DSU(core, 1)) \ 569 | return -6; \ 570 | if (CSU(core, 1)) \ 571 | return -6; \ 572 | CS0 = DS0; \ 573 | DSD(core); 574 | // = 575 | #define INST52 \ 576 | if (DSU(core, 2)) \ 577 | return -6; \ 578 | if (DS1 == DS0) \ 579 | DS1 = -1; \ 580 | else \ 581 | DS1 = 0; \ 582 | DSD(core); 583 | // < 584 | #define INST53 \ 585 | if (DSU(core, 2)) \ 586 | return -6; \ 587 | if (DS1 < DS0) \ 588 | DS1 = -1; \ 589 | else \ 590 | DS1 = 0; \ 591 | DSD(core); 592 | // negate 593 | #define INST54 \ 594 | if (DSU(core, 1)) \ 595 | return -6; \ 596 | DS0 = -DS0; 597 | // abs 598 | #define INST55 \ 599 | if (DSU(core, 1)) \ 600 | return -6; \ 601 | if (DS0 < 0) \ 602 | DS0 = -DS0; 603 | // min 604 | #define INST56 \ 605 | if (DSU(core, 2)) \ 606 | return -6; \ 607 | if (DS0 < DS1) \ 608 | DS1 = DS0; \ 609 | DSD(core); 610 | // max 611 | #define INST57 \ 612 | if (DSU(core, 2)) \ 613 | return -6; \ 614 | if (DS0 > DS1) \ 615 | DS1 = DS0; \ 616 | DSD(core); 617 | // rshift 618 | #define INST58 \ 619 | if (DSU(core, 2)) \ 620 | return -6; \ 621 | DS1 = (uint64_t)DS1 >> (uint64_t)DS0; \ 622 | DSD(core); 623 | // u< 624 | #define INST59 \ 625 | if (DSU(core, 2)) \ 626 | return -6; \ 627 | if ((uint64_t)DS1 < (uint64_t)DS0) \ 628 | DS1 = -1; \ 629 | else \ 630 | DS1 = 0; \ 631 | DSD(core); 632 | // u* 633 | #define INST5A \ 634 | if (DSU(core, 2)) \ 635 | return -6; \ 636 | DS1 = (uint64_t)DS1 * (uint64_t)DS0; \ 637 | DSD(core); 638 | // u/mod 639 | #define INST5B { \ 640 | if (DSU(core, 2)) \ 641 | return -6; \ 642 | if (DS0 == 0) \ 643 | return -3; \ 644 | uint64_t t0, t1; \ 645 | t0 = DS0; \ 646 | t1 = DS1; \ 647 | DS1 = t1 % t0; \ 648 | DS0 = t1 / t0; \ 649 | } 650 | // nip 651 | #define INST5C \ 652 | if (DSU(core, 2)) \ 653 | return -6; \ 654 | DS1 = DS0; \ 655 | DSD(core); 656 | // tuck 657 | #define INST5D \ 658 | if (DSU(core, 2)) \ 659 | return -6; \ 660 | if (DSO(core, 1)) \ 661 | return -7; \ 662 | DSI(core); \ 663 | DS0 = DS1; \ 664 | DS1 = DS2; \ 665 | DS2 = DS0; 666 | // rot 667 | #define INST5E { \ 668 | if (DSU(core, 3)) \ 669 | return -6; \ 670 | int64_t t; \ 671 | t = DS2; \ 672 | DS2 = DS1; \ 673 | DS1 = DS0; \ 674 | DS0 = t; \ 675 | } 676 | // -rot 677 | #define INST5F { \ 678 | if (DSU(core, 3)) \ 679 | return -6; \ 680 | int64_t t; \ 681 | t = DS0; \ 682 | DS0 = DS1; \ 683 | DS1 = DS2; \ 684 | DS2 = t; \ 685 | } 686 | 687 | #define NEXT \ 688 | if (core->ts == 0) \ 689 | return -1; \ 690 | core->ts--; \ 691 | if (G(core->mc, core->p, sizeof(uint8_t))) \ 692 | return -2; \ 693 | core->i = V(uint8_t, core->m, core->p); \ 694 | core->p++; \ 695 | goto *inst[core->i]; 696 | 697 | int 698 | able_misc_core_exec(able_misc_core_t *core) { 699 | static const void *inst[] = { 700 | [0x00] = &&inst00, 701 | &&inst01, 702 | &&inst02, 703 | &&inst03, 704 | &&inst04, 705 | &&inst05, 706 | &&inst06, 707 | &&inst07, 708 | &&inst08, 709 | &&inst09, 710 | &&inst0a, 711 | &&inst0b, 712 | &&inst0c, 713 | &&inst0d, 714 | &&inst0e, 715 | &&inst0f, 716 | &&inst10, 717 | &&inst11, 718 | &&inst12, 719 | &&inst13, 720 | &&inst14, 721 | &&inst15, 722 | &&inst16, 723 | &&inst17, 724 | &&inst18, 725 | &&inst19, 726 | &&inst1a, 727 | &&inst1b, 728 | &&inst1c, 729 | &&inst1d, 730 | &&inst1e, 731 | &&inst1f, 732 | &&inst20, 733 | &&inst21, 734 | &&inst22, 735 | &&inst23, 736 | &&inst24, 737 | &&inst25, 738 | &&inst26, 739 | &&inst27, 740 | &&inst28, 741 | &&inst29, 742 | &&inst2a, 743 | &&inst2b, 744 | &&inst2c, 745 | &&inst2d, 746 | &&inst2e, 747 | &&inst2f, 748 | &&inst30, 749 | &&inst31, 750 | &&inst32, 751 | &&inst33, 752 | &&inst34, 753 | &&inst35, 754 | &&inst36, 755 | &&inst37, 756 | &&inst38, 757 | &&inst39, 758 | &&inst3a, 759 | &&inst3b, 760 | &&inst3c, 761 | &&inst3d, 762 | &&inst3e, 763 | &&inst3f, 764 | &&inst40, 765 | &&inst41, 766 | &&inst42, 767 | &&inst43, 768 | &&inst44, 769 | &&inst45, 770 | &&inst46, 771 | &&inst47, 772 | &&inst48, 773 | &&inst49, 774 | &&inst4a, 775 | &&inst4b, 776 | &&inst4c, 777 | &&inst4d, 778 | &&inst4e, 779 | &&inst4f, 780 | &&inst50, 781 | &&inst51, 782 | &&inst52, 783 | &&inst53, 784 | &&inst54, 785 | &&inst55, 786 | &&inst56, 787 | &&inst57, 788 | &&inst58, 789 | &&inst59, 790 | &&inst5a, 791 | &&inst5b, 792 | &&inst5c, 793 | &&inst5d, 794 | &&inst5e, 795 | &&inst5f, 796 | [0x60 ... 0xff] = &&instxx, 797 | }; 798 | NEXT; 799 | inst00: 800 | INST00; 801 | NEXT; 802 | inst01: 803 | INST01; 804 | NEXT; 805 | inst02: 806 | INST02; 807 | NEXT; 808 | inst03: 809 | INST03; 810 | NEXT; 811 | inst04: 812 | INST04; 813 | NEXT; 814 | inst05: 815 | INST05; 816 | NEXT; 817 | inst06: 818 | INST06; 819 | NEXT; 820 | inst07: 821 | INST07; 822 | NEXT; 823 | inst08: 824 | INST08; 825 | NEXT; 826 | inst09: 827 | INST09; 828 | NEXT; 829 | inst0a: 830 | INST0A; 831 | NEXT; 832 | inst0b: 833 | INST0B; 834 | NEXT; 835 | inst0c: 836 | INST0C; 837 | NEXT; 838 | inst0d: 839 | INST0D; 840 | NEXT; 841 | inst0e: 842 | INST0E; 843 | NEXT; 844 | inst0f: 845 | INST0F; 846 | NEXT; 847 | inst10: 848 | INST10; 849 | NEXT; 850 | inst11: 851 | INST11; 852 | NEXT; 853 | inst12: 854 | INST12; 855 | NEXT; 856 | inst13: 857 | INST13; 858 | NEXT; 859 | inst14: 860 | INST14; 861 | NEXT; 862 | inst15: 863 | INST15; 864 | NEXT; 865 | inst16: 866 | INST16; 867 | NEXT; 868 | inst17: 869 | INST17; 870 | NEXT; 871 | inst18: 872 | INST18; 873 | NEXT; 874 | inst19: 875 | INST19; 876 | NEXT; 877 | inst1a: 878 | INST1A; 879 | NEXT; 880 | inst1b: 881 | INST1B; 882 | NEXT; 883 | inst1c: 884 | INST1C; 885 | NEXT; 886 | inst1d: 887 | INST1D; 888 | NEXT; 889 | inst1e: 890 | INST1E; 891 | NEXT; 892 | inst1f: 893 | INST1F; 894 | NEXT; 895 | inst20: 896 | INST20; 897 | NEXT; 898 | inst21: 899 | INST21; 900 | NEXT; 901 | inst22: 902 | INST22; 903 | NEXT; 904 | inst23: 905 | INST23; 906 | NEXT; 907 | inst24: 908 | INST24; 909 | NEXT; 910 | inst25: 911 | INST25; 912 | NEXT; 913 | inst26: 914 | INST26; 915 | NEXT; 916 | inst27: 917 | INST27; 918 | NEXT; 919 | inst28: 920 | INST28; 921 | NEXT; 922 | inst29: 923 | INST29; 924 | NEXT; 925 | inst2a: 926 | INST2A; 927 | NEXT; 928 | inst2b: 929 | INST2B; 930 | NEXT; 931 | inst2c: 932 | INST2C; 933 | NEXT; 934 | inst2d: 935 | INST2D; 936 | NEXT; 937 | inst2e: 938 | INST2E; 939 | NEXT; 940 | inst2f: 941 | INST2F; 942 | NEXT; 943 | inst30: 944 | INST30; 945 | NEXT; 946 | inst31: 947 | INST31; 948 | NEXT; 949 | inst32: 950 | INST32; 951 | NEXT; 952 | inst33: 953 | INST33; 954 | NEXT; 955 | inst34: 956 | INST34; 957 | NEXT; 958 | inst35: 959 | INST35; 960 | NEXT; 961 | inst36: 962 | INST36; 963 | NEXT; 964 | inst37: 965 | INST37; 966 | NEXT; 967 | inst38: 968 | INST38; 969 | NEXT; 970 | inst39: 971 | INST39; 972 | NEXT; 973 | inst3a: 974 | INST3A; 975 | NEXT; 976 | inst3b: 977 | INST3B; 978 | NEXT; 979 | inst3c: 980 | INST3C; 981 | NEXT; 982 | inst3d: 983 | INST3D; 984 | NEXT; 985 | inst3e: 986 | INST3E; 987 | NEXT; 988 | inst3f: 989 | INST3F; 990 | NEXT; 991 | inst40: 992 | INST40; 993 | NEXT; 994 | inst41: 995 | INST41; 996 | NEXT; 997 | inst42: 998 | INST42; 999 | NEXT; 1000 | inst43: 1001 | INST43; 1002 | NEXT; 1003 | inst44: 1004 | INST44; 1005 | NEXT; 1006 | inst45: 1007 | INST45; 1008 | NEXT; 1009 | inst46: 1010 | INST46; 1011 | NEXT; 1012 | inst47: 1013 | INST47; 1014 | NEXT; 1015 | inst48: 1016 | INST48; 1017 | NEXT; 1018 | inst49: 1019 | INST49; 1020 | NEXT; 1021 | inst4a: 1022 | INST4A; 1023 | NEXT; 1024 | inst4b: 1025 | INST4B; 1026 | NEXT; 1027 | inst4c: 1028 | INST4C; 1029 | NEXT; 1030 | inst4d: 1031 | INST4D; 1032 | NEXT; 1033 | inst4e: 1034 | INST4E; 1035 | NEXT; 1036 | inst4f: 1037 | INST4F; 1038 | NEXT; 1039 | inst50: 1040 | INST50; 1041 | NEXT; 1042 | inst51: 1043 | INST51; 1044 | NEXT; 1045 | inst52: 1046 | INST52; 1047 | NEXT; 1048 | inst53: 1049 | INST53; 1050 | NEXT; 1051 | inst54: 1052 | INST54; 1053 | NEXT; 1054 | inst55: 1055 | INST55; 1056 | NEXT; 1057 | inst56: 1058 | INST56; 1059 | NEXT; 1060 | inst57: 1061 | INST57; 1062 | NEXT; 1063 | inst58: 1064 | INST58; 1065 | NEXT; 1066 | inst59: 1067 | INST59; 1068 | NEXT; 1069 | inst5a: 1070 | INST5A; 1071 | NEXT; 1072 | inst5b: 1073 | INST5B; 1074 | NEXT; 1075 | inst5c: 1076 | INST5C; 1077 | NEXT; 1078 | inst5d: 1079 | INST5D; 1080 | NEXT; 1081 | inst5e: 1082 | INST5E; 1083 | NEXT; 1084 | inst5f: 1085 | INST5F; 1086 | NEXT; 1087 | instxx: 1088 | return -4; 1089 | } 1090 | -------------------------------------------------------------------------------- /misc/core.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | uint8_t *m; 3 | size_t mc; 4 | uint64_t p; 5 | uint8_t i; 6 | int64_t *d; 7 | uint16_t dc; 8 | uint16_t dp; 9 | uint64_t *c; 10 | uint16_t cc; 11 | uint16_t cp; 12 | uint64_t *r; 13 | uint8_t rc; 14 | uint64_t ts; 15 | } able_misc_core_t; 16 | 17 | int 18 | able_misc_core_exec(able_misc_core_t *core); 19 | 20 | #define ABLE_MISC_CORE_A(S, V) \ 21 | (((V) + ((S) - 1)) & -(S)) 22 | 23 | #define ABLE_MISC_CORE_F(M, A, B) \ 24 | (((A) & ~(M)) | (B)) 25 | 26 | #define ABLE_MISC_CORE_V(T, E, A) \ 27 | (*(T *)((E) + (A))) 28 | 29 | #define ABLE_MISC_CORE_G(M, E, S) \ 30 | ((E) > UINT64_MAX - (S) || (E) + (S) > (M)) 31 | 32 | #define ABLE_MISC_CORE_DSU(C, N) \ 33 | ((C)->dp < (N)) 34 | 35 | #define ABLE_MISC_CORE_DSO(C, N) \ 36 | ((C)->dp + (N) > (C)->dc) 37 | 38 | #define ABLE_MISC_CORE_DSI(C) \ 39 | (C)->dp++; 40 | 41 | #define ABLE_MISC_CORE_DSD(C) \ 42 | (C)->dp--; 43 | 44 | #define ABLE_MISC_CORE_DSV(C, N) \ 45 | (C)->d[(C)->dp - N] 46 | 47 | #define ABLE_MISC_CORE_CSU(C, N) \ 48 | ((C)->cp < (N)) 49 | 50 | #define ABLE_MISC_CORE_CSO(C, N) \ 51 | ((C)->cp + (N) > (C)->cc) 52 | 53 | #define ABLE_MISC_CORE_CSI(C) \ 54 | (C)->cp++; 55 | 56 | #define ABLE_MISC_CORE_CSD(C) \ 57 | (C)->cp--; 58 | 59 | #define ABLE_MISC_CORE_CSV(C, N) \ 60 | (C)->c[(C)->cp - N] 61 | -------------------------------------------------------------------------------- /misc/host.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "core.h" 5 | #include "host.h" 6 | 7 | #define DSU ABLE_MISC_CORE_DSU 8 | #define DSO ABLE_MISC_CORE_DSO 9 | #define DSI ABLE_MISC_CORE_DSI 10 | #define DSD ABLE_MISC_CORE_DSD 11 | 12 | #define DS0 ABLE_MISC_CORE_DSV(&host->c, 1) 13 | 14 | int 15 | able_misc_host_exec(able_misc_host_t *host) { 16 | host->c.ts = host->ts; 17 | for (;;) { 18 | int y; 19 | y = able_misc_core_exec(&host->c); 20 | if (y != -4) { 21 | return y; 22 | } 23 | switch (host->c.i) { 24 | case 0x80: { // wait ( t p - n) 25 | if (DSU(&host->c, 2)) 26 | return -6; 27 | uint32_t en; 28 | en = DS0; 29 | DSD(&host->c); 30 | if (en >= host->ec) { 31 | DS0 = 4; 32 | break; 33 | } 34 | struct timespec ts; 35 | struct timespec *tp; 36 | tp = NULL; 37 | uint64_t tv; 38 | tv = DS0; 39 | if (tv != -1) { 40 | ts.tv_sec = tv / 1000000000; 41 | ts.tv_nsec = tv % 1000000000; 42 | tp = &ts; 43 | } 44 | DS0 = able_misc_host_node_wait_shim(host->n, &host->e[en], tp); 45 | if (DS0 == 0) 46 | return -5; 47 | break; 48 | } 49 | case 0x81: { // clip ( a # p - n) 50 | if (DSU(&host->c, 3)) 51 | return -6; 52 | uint32_t en; 53 | en = DS0; 54 | DSD(&host->c); 55 | uint64_t u; 56 | u = DS0; 57 | DSD(&host->c); 58 | uint64_t a; 59 | a = DS0; 60 | if (en >= host->ec) { 61 | DS0 = 2; 62 | break; 63 | } 64 | if (a > UINT64_MAX - u) { 65 | DS0 = 3; 66 | break; 67 | } 68 | if (a >= host->c.mc || a + u > host->c.mc) { 69 | DS0 = 4; 70 | break; 71 | } 72 | able_misc_host_buff_t *b; 73 | b = &host->b[en]; 74 | if (b->rc > 0) { 75 | DS0 = 1; 76 | break; 77 | } 78 | uint8_t *s; 79 | s = host->c.m + a; 80 | int y; 81 | y = able_edge_clip(&host->e[en], s, u); 82 | if (y == 0) 83 | b->r = s; 84 | DS0 = y; 85 | break; 86 | } 87 | case 0x82: { // recv ( p - a # n) 88 | if (DSU(&host->c, 1)) 89 | return -6; 90 | if (DSO(&host->c, 2)) 91 | return -7; 92 | uint32_t en; 93 | en = DS0; 94 | if (en >= host->ec) { 95 | DS0 = 1; 96 | break; 97 | } 98 | able_misc_host_buff_t *b; 99 | b = &host->b[en]; 100 | if (b->rc == 0) 101 | b->rc += able_edge_recv(&host->e[en]); 102 | able_mesg_t *m; 103 | if (b->rc < sizeof(able_mesg_t)) { 104 | DS0 = 0; 105 | DSI(&host->c); 106 | DS0 = 0; 107 | DSI(&host->c); 108 | DS0 = -1; 109 | break; 110 | } 111 | m = (able_mesg_t *)b->r; 112 | b->r += m->sc; 113 | b->rc -= m->sc; 114 | DS0 = m->b - host->c.m; 115 | DSI(&host->c); 116 | DS0 = m->bc; 117 | DSI(&host->c); 118 | DS0 = 0; 119 | break; 120 | } 121 | case 0x83: { // send ( a # l - n) 122 | if (DSU(&host->c, 3)) 123 | return -6; 124 | uint32_t ln; 125 | ln = DS0; 126 | DSD(&host->c); 127 | uint16_t u; 128 | u = DS0; 129 | DSD(&host->c); 130 | uint64_t a; 131 | a = DS0; 132 | if (ln >= host->lc) { 133 | DS0 = 5; 134 | break; 135 | } 136 | if (a > UINT64_MAX - u) { 137 | DS0 = 6; 138 | break; 139 | } 140 | if (a >= host->c.mc || a + u > host->c.mc) { 141 | DS0 = 7; 142 | break; 143 | } 144 | DS0 = able_misc_host_link_send_shim(host->l[ln], host->c.m + a, u); 145 | break; 146 | } 147 | default: 148 | return y; 149 | } 150 | } 151 | 152 | // should not happen 153 | return 1; 154 | } 155 | -------------------------------------------------------------------------------- /misc/host.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | uint8_t *r; 3 | size_t rc; 4 | } able_misc_host_buff_t; 5 | 6 | typedef struct { 7 | void *n; 8 | able_edge_t *e; 9 | uint32_t ec; 10 | able_misc_host_buff_t *b; 11 | uint32_t bc; 12 | void **l; 13 | uint32_t lc; 14 | able_misc_core_t c; 15 | uint64_t ts; 16 | } able_misc_host_t; 17 | 18 | int 19 | able_misc_host_exec(able_misc_host_t *host); 20 | 21 | int 22 | able_misc_host_node_wait_shim(void *node, const able_edge_t *edge, const struct timespec *time); 23 | 24 | int 25 | able_misc_host_link_send_shim(void *link, const void *data, size_t size); 26 | -------------------------------------------------------------------------------- /misc/misc.h: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | #include "host.h" 3 | -------------------------------------------------------------------------------- /node.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "edge.h" 3 | #include 4 | #include "node.h" 5 | #include 6 | 7 | int 8 | able_node_init(able_node_t *node) { 9 | atomic_store(&node->sl, 0); 10 | pthread_mutex_init(&node->m, NULL); 11 | pthread_cond_init(&node->v, NULL); 12 | node->w = NULL; 13 | return 0; 14 | } 15 | 16 | int 17 | able_node_wait(able_node_t *node, const able_edge_t *edge, const struct timespec *time) { 18 | if (edge == NULL) 19 | return 0; 20 | if (atomic_load(&edge->rc) > 0) 21 | return 1; 22 | atomic_store(&node->sl, 1); 23 | pthread_mutex_lock(&node->m); 24 | node->w = edge; 25 | if (time == NULL) { 26 | while (atomic_load(&edge->rc) == 0) 27 | pthread_cond_wait(&node->v, &node->m); 28 | node->w = NULL; 29 | pthread_mutex_unlock(&node->m); 30 | atomic_store(&node->sl, 0); 31 | return 0; 32 | } else { 33 | int y; 34 | y = 0; 35 | while (atomic_load(&edge->rc) == 0 && y == 0) 36 | y = pthread_cond_timedwait(&node->v, &node->m, time); 37 | node->w = NULL; 38 | pthread_mutex_unlock(&node->m); 39 | atomic_store(&node->sl, 0); 40 | if (y == EINVAL) 41 | return 2; 42 | if (y == ETIMEDOUT) 43 | return 3; 44 | return 0; 45 | } 46 | } 47 | 48 | int 49 | able_node_post(able_node_t *node, const able_edge_t *edge) { 50 | if (atomic_load(&node->sl) == 0) 51 | return 0; 52 | pthread_mutex_lock(&node->m); 53 | if (node->w != edge) { 54 | pthread_mutex_unlock(&node->m); 55 | return 0; 56 | } 57 | pthread_cond_signal(&node->v); 58 | pthread_mutex_unlock(&node->m); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /node.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | atomic_bool sl; 3 | pthread_mutex_t m; 4 | pthread_cond_t v; 5 | const able_edge_t *w; 6 | } able_node_t; 7 | 8 | int 9 | able_node_init(able_node_t *node); 10 | 11 | int 12 | able_node_wait(able_node_t *node, const able_edge_t *edge, const struct timespec *time); 13 | 14 | int 15 | able_node_post(able_node_t *node, const able_edge_t *edge); 16 | -------------------------------------------------------------------------------- /task.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "task.h" 3 | 4 | int 5 | able_task_exec(able_task_t *task) { 6 | int y; 7 | while ((y = task->ef(task->t)) < 0); 8 | return y; 9 | } 10 | 11 | static void * 12 | task_exec_shim(void *task) { 13 | able_task_exec(task); 14 | return NULL; 15 | } 16 | 17 | int 18 | able_task_fork_exec(able_task_t *task) { 19 | pthread_attr_t thread_attr; 20 | pthread_attr_init(&thread_attr); 21 | pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 22 | pthread_create(&task->c, &thread_attr, task_exec_shim, task); 23 | pthread_attr_destroy(&thread_attr); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /task.h: -------------------------------------------------------------------------------- 1 | typedef int 2 | (*able_task_exec_t)(void *task); 3 | 4 | typedef struct { 5 | able_task_exec_t ef; 6 | void *t; 7 | pthread_t c; 8 | } able_task_t; 9 | 10 | int 11 | able_task_exec(able_task_t *task); 12 | 13 | int 14 | able_task_fork_exec(able_task_t *task); 15 | --------------------------------------------------------------------------------