vm: remove old JIT
diff --git a/vm/Makefile b/vm/Makefile
index 3e180b9..a7b3f48 100644
--- a/vm/Makefile
+++ b/vm/Makefile
@@ -12,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-DYNASM := ../dynasm
-
-CFLAGS := -Wall -Werror -Iinc -I$(DYNASM) -O2 -g
+CFLAGS := -Wall -Werror -Iinc -O2 -g
 LDLIBS := -lm
 
 ifeq ($(COVERAGE),1)
@@ -29,9 +27,6 @@
 
 all: libubpf.a test
 
-%.c: %.dasm minilua
-	LUA_PATH=$(DYNASM)/?.lua ./minilua $(DYNASM)/dynasm.lua -o $@ $<
-
 ubpf_jit_x86_64.o: ubpf_jit_x86_64.c ubpf_jit_x86_64.h
 
 libubpf.a: ubpf_vm.o ubpf_jit_x86_64.o ubpf_loader.o
@@ -39,8 +34,5 @@
 
 test: test.o libubpf.a
 
-minilua: ../luajit-2.0/src/host/minilua.c
-	$(CC) -o $@ $< -lm
-
 clean:
-	rm -f test libubpf.a *.o ubpf_jit.c
+	rm -f test libubpf.a *.o
diff --git a/vm/ubpf_jit.dasm b/vm/ubpf_jit.dasm
deleted file mode 100644
index 4dcaa71..0000000
--- a/vm/ubpf_jit.dasm
+++ /dev/null
@@ -1,636 +0,0 @@
-// vi: ft=c
-/*
- * Copyright 2015 Big Switch Networks, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <assert.h>
-#include "ubpf_int.h"
-
-#define DASM_CHECKS
-#include <dasm_proto.h>
-#include <dasm_x86.h>
-
-|.arch x64
-
-/* The hardcoded dasm_State variable name is confusing given our use of 'dst' */
-#define dasm Dst
-
-#define STACK_SIZE 128
-
-/*
- * Register mapping:
- *
- * eBPF -> x86
- * 0 -> rax
- * 1 -> rdi
- * 2 -> rsi
- * 3 -> rdx
- * 4 -> r9
- * 5 -> r8
- * 6 -> rbx
- * 7 -> r13
- * 8 -> r14
- * 9 -> r15
- * 10 -> rbp
- *
- * eBPF calling convention:
- * - Registers r6-r10 are callee save.
- * - Function call arguments go in r1-r5.
- * - Return value goes in r0.
- *
- * x86 calling convention:
- * - Registers rbp, rbx, r12, r13, r14, and r15 are callee save.
- * - Function call arguments go in rdi, rsi, rdx, rcx, r8, and r9.
- * - Return value goes in rax.
- *
- * rcx (cl) is a required operand for shifts by a register. We reserve it.
- * rsp could not be used for the stack pointer due to DynASM issues.
- * r12 could not be used due to DynASM issues.
- */
-#define RAX 0
-#define RCX 1
-#define RDX 2
-#define RBX 3
-#define RSP 4
-#define RBP 5
-#define RSI 6
-#define RDI 7
-#define R8  8
-#define R9  9
-#define R10 10
-#define R11 11
-/* r12 is unused (encoding problems) */
-#define R13 13
-#define R14 14
-#define R15 15
-
-#define REGISTER_MAP_SIZE 11
-static int register_map[REGISTER_MAP_SIZE] = {
-    RAX,
-    RDI,
-    RSI,
-    RDX,
-    R9,
-    R8,
-    RBX,
-    R13,
-    R14,
-    R15,
-    RBP,
-};
-
-/* Return the x86 register for the given eBPF register */
-static int
-map_register(int r)
-{
-    assert(r < REGISTER_MAP_SIZE);
-    return register_map[r % REGISTER_MAP_SIZE];
-}
-
-/* For testing, this changes the mapping between x86 and eBPF registers */
-void
-ubpf_set_register_offset(int x)
-{
-    int i;
-    if (x < REGISTER_MAP_SIZE) {
-        int tmp[REGISTER_MAP_SIZE];
-        memcpy(tmp, register_map, sizeof(register_map));
-        for (i = 0; i < REGISTER_MAP_SIZE; i++) {
-            register_map[i] = tmp[(i+x)%REGISTER_MAP_SIZE];
-        }
-    } else {
-        /* Shuffle array */
-        unsigned int seed = x;
-        for (i = 0; i < REGISTER_MAP_SIZE-1; i++) {
-            int j = i + (rand_r(&seed) % (REGISTER_MAP_SIZE-i));
-            int tmp = register_map[j];
-            register_map[j] = register_map[i];
-            register_map[i] = tmp;
-        }
-    }
-}
-
-static void muldivmod(dasm_State **dasm, uint16_t pc, uint8_t opcode, int src, int dst, int32_t imm);
-
-|.actionlist actions
-
-ubpf_jit_fn
-ubpf_compile(struct ubpf_vm *vm, char **errmsg)
-{
-    dasm_State *d;
-    void *jitted = NULL;
-    size_t jitted_size;
-    int ret;
-
-    *errmsg = NULL;
-
-    if (vm->jitted) {
-        return vm->jitted;
-    }
-
-    if (!vm->insts) {
-        *errmsg = ubpf_error("code has not been loaded into this VM");
-        return NULL;
-    }
-
-    |.section code
-    dasm_init(&d, DASM_MAXSECTION);
-
-    |.globals lbl_
-    void *labels[lbl__MAX];
-    dasm_setupglobal(&d, labels, lbl__MAX);
-
-    dasm_setup(&d, actions);
-
-    dasm_growpc(&d, vm->num_insts);
-
-    dasm_State **dasm = &d;
-
-    if ((ret = dasm_checkstep(dasm, 0)) != DASM_S_OK) {
-        *errmsg = ubpf_error("DynASM error %#x before prologue", ret);
-        goto error;
-    }
-
-    /* Prologue */
-    |.code
-    |->entry:
-    /* rbp, rbx, r13, r14, and r15 are callee save */
-    /* TODO don't save registers we don't write to */
-    | push rbp
-    | push rbx
-    | push r13
-    | push r14
-    | push r15
-
-    /* Move rdi into register 1 */
-    if (map_register(1) != RDI) {
-        | mov Rq(map_register(1)), rdi
-    }
-
-    /* Allocate stack space and store address in r10 */
-    | sub rsp, STACK_SIZE
-    | mov Rq(map_register(10)), Rq(RSP)
-
-    if ((ret = dasm_checkstep(dasm, 0)) != DASM_S_OK) {
-        *errmsg = ubpf_error("DynASM error %#x after prologue", ret);
-        goto error;
-    }
-
-    int i;
-    for (i = 0; i < vm->num_insts; i++) {
-        struct ebpf_inst inst = vm->insts[i];
-        |=>i:
-
-        int src = map_register(inst.src);
-        int dst = map_register(inst.dst);
-        int jmp_target = i + inst.offset + 1;
-
-        switch (inst.opcode) {
-        case EBPF_OP_ADD_IMM:
-            | add Rd(dst), inst.imm
-            break;
-        case EBPF_OP_ADD_REG:
-            | add Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_SUB_IMM:
-            | sub Rd(dst), inst.imm
-            break;
-        case EBPF_OP_SUB_REG:
-            | sub Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_MUL_IMM:
-        case EBPF_OP_MUL_REG:
-        case EBPF_OP_DIV_IMM:
-        case EBPF_OP_DIV_REG:
-        case EBPF_OP_MOD_IMM:
-        case EBPF_OP_MOD_REG:
-            muldivmod(dasm, i, inst.opcode, src, dst, inst.imm);
-            break;
-        case EBPF_OP_OR_IMM:
-            | or Rd(dst), inst.imm
-            break;
-        case EBPF_OP_OR_REG:
-            | or Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_AND_IMM:
-            | and Rd(dst), inst.imm
-            break;
-        case EBPF_OP_AND_REG:
-            | and Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_LSH_IMM:
-            | shl Rd(dst), inst.imm
-            break;
-        case EBPF_OP_LSH_REG:
-            | mov Rq(RCX), Rq(src)
-            | shl Rd(dst), cl
-            break;
-        case EBPF_OP_RSH_IMM:
-            | shr Rd(dst), inst.imm
-            break;
-        case EBPF_OP_RSH_REG:
-            | mov Rq(RCX), Rq(src)
-            | shr Rd(dst), cl
-            break;
-        case EBPF_OP_NEG:
-            | neg Rd(dst)
-            break;
-        case EBPF_OP_XOR_IMM:
-            | xor Rd(dst), inst.imm
-            break;
-        case EBPF_OP_XOR_REG:
-            | xor Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_MOV_IMM:
-            | mov Rd(dst), inst.imm
-            break;
-        case EBPF_OP_MOV_REG:
-            | mov Rd(dst), Rd(src)
-            break;
-        case EBPF_OP_ARSH_IMM:
-            | sar Rd(dst), inst.imm
-            break;
-        case EBPF_OP_ARSH_REG:
-            | mov Rq(RCX), Rq(src)
-            | sar Rd(dst), cl
-            break;
-
-        case EBPF_OP_LE:
-            /* No-op */
-            break;
-        case EBPF_OP_BE:
-            if (inst.imm == 16) {
-                | rol Rw(dst), 8
-                | and Rd(dst), 0xffff
-            } else if (inst.imm == 32) {
-                /* bswap of r8d+ is misassembled */
-                if (dst < 8) {
-                    | bswap Rd(dst)
-                } else {
-                    | mov Rq(RCX), Rq(dst)
-                    | bswap ecx
-                    | mov Rd(dst), ecx
-                }
-            } else if (inst.imm == 64) {
-                /* bswap of r8+ is misassembled */
-                if (dst < 8) {
-                    | bswap Rq(dst)
-                } else {
-                    | mov Rq(RCX), Rq(dst)
-                    | bswap rcx
-                    | mov Rq(dst), rcx
-                }
-            }
-            break;
-
-        case EBPF_OP_ADD64_IMM:
-            | add Rq(dst), inst.imm
-            break;
-        case EBPF_OP_ADD64_REG:
-            | add Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_SUB64_IMM:
-            | sub Rq(dst), inst.imm
-            break;
-        case EBPF_OP_SUB64_REG:
-            | sub Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_MUL64_IMM:
-        case EBPF_OP_MUL64_REG:
-        case EBPF_OP_DIV64_IMM:
-        case EBPF_OP_DIV64_REG:
-        case EBPF_OP_MOD64_IMM:
-        case EBPF_OP_MOD64_REG:
-            muldivmod(dasm, i, inst.opcode, src, dst, inst.imm);
-            break;
-        case EBPF_OP_OR64_IMM:
-            | or Rq(dst), inst.imm
-            break;
-        case EBPF_OP_OR64_REG:
-            | or Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_AND64_IMM:
-            | and Rq(dst), inst.imm
-            break;
-        case EBPF_OP_AND64_REG:
-            | and Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_LSH64_IMM:
-            | shl Rq(dst), inst.imm
-            break;
-        case EBPF_OP_LSH64_REG:
-            | mov Rq(RCX), Rq(src)
-            | shl Rq(dst), cl
-            break;
-        case EBPF_OP_RSH64_IMM:
-            | shr Rq(dst), inst.imm
-            break;
-        case EBPF_OP_RSH64_REG:
-            | mov Rq(RCX), Rq(src)
-            | shr Rq(dst), cl
-            break;
-        case EBPF_OP_NEG64:
-            | neg Rq(dst)
-            break;
-        case EBPF_OP_XOR64_IMM:
-            | xor Rq(dst), inst.imm
-            break;
-        case EBPF_OP_XOR64_REG:
-            | xor Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_MOV64_IMM:
-            /* TODO use shorter mov for smaller immediates */
-            | mov Rq(dst), inst.imm
-            break;
-        case EBPF_OP_MOV64_REG:
-            | mov Rq(dst), Rq(src)
-            break;
-        case EBPF_OP_ARSH64_IMM:
-            | sar Rq(dst), inst.imm
-            break;
-        case EBPF_OP_ARSH64_REG:
-            | mov Rq(RCX), Rq(src)
-            | sar Rq(dst), cl
-            break;
-
-        case EBPF_OP_JA:
-            | jmp =>jmp_target
-            break;
-        case EBPF_OP_JEQ_IMM:
-            | cmp Rq(dst), inst.imm
-            | je =>jmp_target
-            break;
-        case EBPF_OP_JEQ_REG:
-            | cmp Rq(dst), Rq(src)
-            | je =>jmp_target
-            break;
-        case EBPF_OP_JGT_IMM:
-            | cmp Rq(dst), inst.imm
-            | ja =>jmp_target
-            break;
-        case EBPF_OP_JGT_REG:
-            | cmp Rq(dst), Rq(src)
-            | ja =>jmp_target
-            break;
-        case EBPF_OP_JGE_IMM:
-            | cmp Rq(dst), inst.imm
-            | jae =>jmp_target
-            break;
-        case EBPF_OP_JGE_REG:
-            | cmp Rq(dst), Rq(src)
-            | jae =>jmp_target
-            break;
-        case EBPF_OP_JSET_IMM:
-            | test Rq(dst), inst.imm
-            | jnz =>jmp_target
-            break;
-        case EBPF_OP_JSET_REG:
-            | test Rq(dst), Rq(src)
-            | jnz =>jmp_target
-            break;
-        case EBPF_OP_JNE_IMM:
-            | cmp Rq(dst), inst.imm
-            | jne =>jmp_target
-            break;
-        case EBPF_OP_JNE_REG:
-            | cmp Rq(dst), Rq(src)
-            | jne =>jmp_target
-            break;
-        case EBPF_OP_JSGT_IMM:
-            | cmp Rq(dst), inst.imm
-            | jg =>jmp_target
-            break;
-        case EBPF_OP_JSGT_REG:
-            | cmp Rq(dst), Rq(src)
-            | jg =>jmp_target
-            break;
-        case EBPF_OP_JSGE_IMM:
-            | cmp Rq(dst), inst.imm
-            | jge =>jmp_target
-            break;
-        case EBPF_OP_JSGE_REG:
-            | cmp Rq(dst), Rq(src)
-            | jge =>jmp_target
-            break;
-        case EBPF_OP_CALL:
-            /* We reserve RCX for shifts */
-            | mov rcx, r9
-            /* TODO direct call */
-            | mov rax, vm->ext_funcs[inst.imm]
-            | call rax
-            break;
-        case EBPF_OP_EXIT:
-            if (i != vm->num_insts - 1) {
-                | jmp ->exit
-            }
-            break;
-
-        case EBPF_OP_LDXW:
-            | mov Rd(dst), dword [Rq(src)+inst.offset]
-            break;
-        case EBPF_OP_LDXH:
-            /* movzx is not assembled correctly */
-            | xor ecx, ecx
-            | mov cx, word [Rq(src)+inst.offset]
-            | mov Rq(dst), Rq(RCX)
-            break;
-        case EBPF_OP_LDXB:
-            /* movzx is not assembled correctly */
-            | xor ecx, ecx
-            | mov cl, byte [Rq(src)+inst.offset]
-            | mov Rq(dst), Rq(RCX)
-            break;
-        case EBPF_OP_LDXDW:
-            | mov Rq(dst), qword [Rq(src)+inst.offset]
-            break;
-
-        case EBPF_OP_STW:
-            | mov dword [Rq(dst)+inst.offset], inst.imm
-            break;
-        case EBPF_OP_STH:
-            | mov word [Rq(dst)+inst.offset], inst.imm
-            break;
-        case EBPF_OP_STB:
-            | mov byte [Rq(dst)+inst.offset], inst.imm
-            break;
-        case EBPF_OP_STDW:
-            | mov qword [Rq(dst)+inst.offset], inst.imm
-            break;
-
-        case EBPF_OP_STXW:
-            | mov dword [Rq(dst)+inst.offset], Rd(src)
-            break;
-        case EBPF_OP_STXH:
-            | mov word [Rq(dst)+inst.offset], Rw(src)
-            break;
-        case EBPF_OP_STXB:
-            /* Rb(src) generates the wrong byte registers */
-            /* mov rcx, Rq(src) also did not work */
-            | mov Rq(RCX), Rq(src)
-            | mov byte [Rq(dst)+inst.offset], cl
-            break;
-        case EBPF_OP_STXDW:
-            | mov qword [Rq(dst)+inst.offset], Rq(src)
-            break;
-
-        case EBPF_OP_LDDW: {
-            struct ebpf_inst inst2 = vm->insts[++i];
-            uint64_t imm = (uint32_t)inst.imm | ((uint64_t)inst2.imm << 32);
-            | mov64 Rq(dst), imm
-            break;
-        }
-
-        }
-
-        if ((ret = dasm_checkstep(dasm, 0)) != DASM_S_OK) {
-            *errmsg = ubpf_error("DynASM error %#x at PC %d: opcode %02x src %u dst %u", ret, i, inst.opcode, src, dst);
-            goto error;
-        }
-    }
-
-    /* Epilogue */
-    | ->exit:
-    /* Move register 0 into rax */
-    if (map_register(0) != RAX) {
-        | mov Rq(RAX), Rq(map_register(0))
-    }
-    | ->exit2:
-    | add rsp, STACK_SIZE
-    | pop r15
-    | pop r14
-    | pop r13
-    | pop rbx
-    | pop rbp
-    | ret
-
-    /* Division by zero handler */
-    const char *div_by_zero_fmt = "uBPF error: division by zero at PC %u\n";
-    | ->div_by_zero:
-    | mov64 rdi, (uintptr_t)stderr
-    | mov64 rsi, (uintptr_t)div_by_zero_fmt
-    | mov64 rax, (uintptr_t)fprintf
-    | call rax
-    | mov rax, -1
-    | jmp ->exit2
-
-    if ((ret = dasm_checkstep(dasm, 0)) != DASM_S_OK) {
-        *errmsg = ubpf_error("DynASM error %#x after epilogue", ret);
-        goto error;
-    }
-
-    if ((ret = dasm_link(dasm, &jitted_size)) != DASM_S_OK) {
-        *errmsg = ubpf_error("internal uBPF error: dasm_link failed: %d", ret);
-        goto error;
-    }
-
-    jitted = mmap(0, jitted_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-    if (jitted == MAP_FAILED) {
-        *errmsg = ubpf_error("internal uBPF error: mmap failed: %s\n", strerror(errno));
-        goto error;
-    }
-
-    if ((ret = dasm_encode(dasm, jitted)) != DASM_S_OK) {
-        *errmsg = ubpf_error("internal uBPF error: dasm_encode failed: %d\n", ret);
-        goto error;
-    }
-
-    if (mprotect(jitted, jitted_size, PROT_READ | PROT_EXEC) < 0) {
-        *errmsg = ubpf_error("internal uBPF error: mprotect failed: %s\n", strerror(errno));
-        goto error;
-    }
-
-    assert(labels[lbl_entry] == jitted);
-
-    dasm_free(dasm);
-    vm->jitted = labels[lbl_entry];
-    vm->jitted_size = jitted_size;
-    return vm->jitted;
-
-error:
-    dasm_free(dasm);
-    if (jitted) {
-        munmap(jitted, jitted_size);
-    }
-    return NULL;
-}
-
-static void
-muldivmod(dasm_State **dasm, uint16_t pc, uint8_t opcode, int src, int dst, int32_t imm)
-{
-    bool mul = (opcode & EBPF_ALU_OP_MASK) == (EBPF_OP_MUL_IMM & EBPF_ALU_OP_MASK);
-    bool div = (opcode & EBPF_ALU_OP_MASK) == (EBPF_OP_DIV_IMM & EBPF_ALU_OP_MASK);
-    bool mod = (opcode & EBPF_ALU_OP_MASK) == (EBPF_OP_MOD_IMM & EBPF_ALU_OP_MASK);
-    bool is64 = (opcode & EBPF_CLS_MASK) == EBPF_CLS_ALU64;
-
-    if (div || mod) {
-        if (is64) {
-            | test Rq(src), Rq(src)
-        } else {
-            | test Rd(src), Rd(src)
-        }
-        | jnz >1
-        | mov rdx, pc
-        | jmp ->div_by_zero
-        |1:
-    }
-
-    if (dst != RAX) {
-        | push rax
-    }
-    if (dst != RDX) {
-        | push rdx
-    }
-    if (imm) {
-        | mov Rq(RCX), imm
-    } else {
-        | mov Rq(RCX), Rq(src)
-    }
-    | mov Rq(RAX), Rq(dst)
-    if (div || mod) {
-        | xor edx, edx
-        if (is64) {
-            | div rcx
-        } else {
-            | div ecx
-        }
-    } else {
-        if (is64) {
-            | mul rcx
-        } else {
-            | mul ecx
-        }
-    }
-    if (dst != RDX) {
-        if (mod) {
-            | mov Rq(dst), Rq(RDX)
-        }
-        | pop rdx
-    }
-    if (dst != RAX) {
-        if (div || mul) {
-            | mov Rq(dst), Rq(RAX)
-        }
-        | pop rax
-    }
-}