From 49aa680ccdac46d1d2a7f9f250999b7ff7099548 Mon Sep 17 00:00:00 2001
From: Kimplul <kimi.h.kuparinen@gmail.com>
Date: Sat, 29 Jun 2024 14:20:07 +0300
Subject: start adding tests

---
 tests/absr_f.c          |  19 +++++++++++++
 tests/addi.c            |  25 ++++++++++++++++++
 tests/addr.c            |  23 ++++++++++++++++
 tests/addr_d.c          |  27 +++++++++++++++++++
 tests/addr_f.c          |  27 +++++++++++++++++++
 tests/addx.c            |  63 +++++++++++++++++++++++++++++++++++++++++++
 tests/andi.c            |  31 ++++++++++++++++++++++
 tests/andr.c            |  48 +++++++++++++++++++++++++++++++++
 tests/beqi.c            |  28 ++++++++++++++++++++
 tests/beqr.c            |  32 ++++++++++++++++++++++
 tests/beqr_d.c          |  35 ++++++++++++++++++++++++
 tests/beqr_f.c          |  35 ++++++++++++++++++++++++
 tests/bgei.c            |  28 ++++++++++++++++++++
 tests/bgei_u.c          |  28 ++++++++++++++++++++
 tests/bger.c            |  31 ++++++++++++++++++++++
 tests/bger_d.c          |  34 ++++++++++++++++++++++++
 tests/bger_f.c          |  34 ++++++++++++++++++++++++
 tests/bger_u.c          |  31 ++++++++++++++++++++++
 tests/bgti.c            |  28 ++++++++++++++++++++
 tests/bgti_u.c          |  28 ++++++++++++++++++++
 tests/bgtr.c            |  31 ++++++++++++++++++++++
 tests/bgtr_d.c          |  34 ++++++++++++++++++++++++
 tests/bgtr_f.c          |  34 ++++++++++++++++++++++++
 tests/bgtr_u.c          |  31 ++++++++++++++++++++++
 tests/blei.c            |  28 ++++++++++++++++++++
 tests/blei_u.c          |  28 ++++++++++++++++++++
 tests/bler.c            |  31 ++++++++++++++++++++++
 tests/bler_d.c          |  34 ++++++++++++++++++++++++
 tests/bler_f.c          |  34 ++++++++++++++++++++++++
 tests/bler_u.c          |  31 ++++++++++++++++++++++
 tests/bltgtr_d.c        |  36 +++++++++++++++++++++++++
 tests/bltgtr_f.c        |  36 +++++++++++++++++++++++++
 tests/blti.c            |  28 ++++++++++++++++++++
 tests/blti_u.c          |  28 ++++++++++++++++++++
 tests/bltr.c            |  31 ++++++++++++++++++++++
 tests/bltr_d.c          |  34 ++++++++++++++++++++++++
 tests/bltr_f.c          |  34 ++++++++++++++++++++++++
 tests/bltr_u.c          |  31 ++++++++++++++++++++++
 tests/bmci.c            |  29 ++++++++++++++++++++
 tests/bmcr.c            |  35 ++++++++++++++++++++++++
 tests/bmsi.c            |  29 ++++++++++++++++++++
 tests/bmsr.c            |  35 ++++++++++++++++++++++++
 tests/bnei.c            |  28 ++++++++++++++++++++
 tests/bner.c            |  31 ++++++++++++++++++++++
 tests/bner_d.c          |  36 +++++++++++++++++++++++++
 tests/bner_f.c          |  36 +++++++++++++++++++++++++
 tests/boaddi.c          |  41 ++++++++++++++++++++++++++++
 tests/boaddi_u.c        |  41 ++++++++++++++++++++++++++++
 tests/boaddr.c          |  51 +++++++++++++++++++++++++++++++++++
 tests/boaddr_u.c        |  51 +++++++++++++++++++++++++++++++++++
 tests/bordr_d.c         |  36 +++++++++++++++++++++++++
 tests/bordr_f.c         |  36 +++++++++++++++++++++++++
 tests/bosubi.c          |  41 ++++++++++++++++++++++++++++
 tests/bosubi_u.c        |  37 ++++++++++++++++++++++++++
 tests/bosubr.c          |  48 +++++++++++++++++++++++++++++++++
 tests/bosubr_u.c        |  47 +++++++++++++++++++++++++++++++++
 tests/bswapr_ui.c       |  28 ++++++++++++++++++++
 tests/bswapr_ul.c       |  27 +++++++++++++++++++
 tests/bswapr_us.c       |  24 +++++++++++++++++
 tests/buneqr_d.c        |  35 ++++++++++++++++++++++++
 tests/buneqr_f.c        |  35 ++++++++++++++++++++++++
 tests/bunger_d.c        |  34 ++++++++++++++++++++++++
 tests/bunger_f.c        |  34 ++++++++++++++++++++++++
 tests/bungtr_d.c        |  34 ++++++++++++++++++++++++
 tests/bungtr_f.c        |  34 ++++++++++++++++++++++++
 tests/bunler_d.c        |  34 ++++++++++++++++++++++++
 tests/bunler_f.c        |  34 ++++++++++++++++++++++++
 tests/bunltr_d.c        |  34 ++++++++++++++++++++++++
 tests/bunltr_f.c        |  34 ++++++++++++++++++++++++
 tests/bunordr_d.c       |  36 +++++++++++++++++++++++++
 tests/bunordr_f.c       |  36 +++++++++++++++++++++++++
 tests/bxaddi.c          |  39 +++++++++++++++++++++++++++
 tests/bxaddi_u.c        |  39 +++++++++++++++++++++++++++
 tests/bxaddr.c          |  49 ++++++++++++++++++++++++++++++++++
 tests/bxaddr_u.c        |  49 ++++++++++++++++++++++++++++++++++
 tests/bxsubi.c          |  39 +++++++++++++++++++++++++++
 tests/bxsubi_u.c        |  35 ++++++++++++++++++++++++
 tests/bxsubr.c          |  46 ++++++++++++++++++++++++++++++++
 tests/bxsubr_u.c        |  45 +++++++++++++++++++++++++++++++
 tests/call_10.c         |  64 ++++++++++++++++++++++++++++++++++++++++++++
 tests/call_double.c     |  38 ++++++++++++++++++++++++++
 tests/call_float.c      |  38 ++++++++++++++++++++++++++
 tests/callee_9.c        |  68 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/cas_atomic.c      |  33 +++++++++++++++++++++++
 tests/comr.c            |  41 ++++++++++++++++++++++++++++
 tests/divr.c            |  60 +++++++++++++++++++++++++++++++++++++++++
 tests/divr_d.c          |  27 +++++++++++++++++++
 tests/divr_f.c          |  27 +++++++++++++++++++
 tests/divr_u.c          |  55 ++++++++++++++++++++++++++++++++++++++
 tests/do_jit.h          |  10 +++++++
 tests/extr_c.c          |  27 +++++++++++++++++++
 tests/extr_d.c          |  25 ++++++++++++++++++
 tests/extr_d_f.c        |  26 ++++++++++++++++++
 tests/extr_f.c          |  25 ++++++++++++++++++
 tests/extr_f_d.c        |  26 ++++++++++++++++++
 tests/extr_i.c          |  30 +++++++++++++++++++++
 tests/extr_s.c          |  28 ++++++++++++++++++++
 tests/extr_uc.c         |  27 +++++++++++++++++++
 tests/extr_ui.c         |  29 ++++++++++++++++++++
 tests/extr_us.c         |  27 +++++++++++++++++++
 tests/jmp0.c            |  24 +++++++++++++++++
 tests/jmp_table.c       |  61 ++++++++++++++++++++++++++++++++++++++++++
 tests/jmpi.c            |  41 ++++++++++++++++++++++++++++
 tests/jmpi_local.c      |  25 ++++++++++++++++++
 tests/jmpr.c            |  25 ++++++++++++++++++
 tests/ldi_c.c           |  24 +++++++++++++++++
 tests/ldi_d.c           |  24 +++++++++++++++++
 tests/ldi_f.c           |  24 +++++++++++++++++
 tests/ldi_i.c           |  24 +++++++++++++++++
 tests/ldi_l.c           |  26 ++++++++++++++++++
 tests/ldi_s.c           |  24 +++++++++++++++++
 tests/ldi_uc.c          |  24 +++++++++++++++++
 tests/ldi_ui.c          |  26 ++++++++++++++++++
 tests/ldi_us.c          |  24 +++++++++++++++++
 tests/ldr_atomic.c      |  28 ++++++++++++++++++++
 tests/ldr_c.c           |  27 +++++++++++++++++++
 tests/ldr_d.c           |  27 +++++++++++++++++++
 tests/ldr_f.c           |  27 +++++++++++++++++++
 tests/ldr_i.c           |  27 +++++++++++++++++++
 tests/ldr_l.c           |  29 ++++++++++++++++++++
 tests/ldr_s.c           |  27 +++++++++++++++++++
 tests/ldr_uc.c          |  27 +++++++++++++++++++
 tests/ldr_ui.c          |  29 ++++++++++++++++++++
 tests/ldr_us.c          |  27 +++++++++++++++++++
 tests/ldxi_c.c          |  27 +++++++++++++++++++
 tests/ldxi_d.c          |  27 +++++++++++++++++++
 tests/ldxi_f.c          |  27 +++++++++++++++++++
 tests/ldxi_i.c          |  27 +++++++++++++++++++
 tests/ldxi_l.c          |  29 ++++++++++++++++++++
 tests/ldxi_s.c          |  27 +++++++++++++++++++
 tests/ldxi_uc.c         |  27 +++++++++++++++++++
 tests/ldxi_ui.c         |  29 ++++++++++++++++++++
 tests/ldxi_us.c         |  27 +++++++++++++++++++
 tests/ldxr_c.c          |  28 ++++++++++++++++++++
 tests/ldxr_d.c          |  28 ++++++++++++++++++++
 tests/ldxr_f.c          |  28 ++++++++++++++++++++
 tests/ldxr_i.c          |  28 ++++++++++++++++++++
 tests/ldxr_l.c          |  30 +++++++++++++++++++++
 tests/ldxr_s.c          |  28 ++++++++++++++++++++
 tests/ldxr_uc.c         |  28 ++++++++++++++++++++
 tests/ldxr_ui.c         |  30 +++++++++++++++++++++
 tests/ldxr_us.c         |  28 ++++++++++++++++++++
 tests/link-register.c   |  35 ++++++++++++++++++++++++
 tests/lshi.c            |  27 +++++++++++++++++++
 tests/lshr.c            |  69 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/makefile          |  32 ++++++++++++++++++++++
 tests/mov_addr.c        |  25 ++++++++++++++++++
 tests/movi.c            |  22 +++++++++++++++
 tests/movi_d.c          |  22 +++++++++++++++
 tests/movi_f.c          |  22 +++++++++++++++
 tests/mulr.c            |  64 ++++++++++++++++++++++++++++++++++++++++++++
 tests/mulr_d.c          |  27 +++++++++++++++++++
 tests/mulr_f.c          |  27 +++++++++++++++++++
 tests/negr.c            |  39 +++++++++++++++++++++++++++
 tests/negr_d.c          |  26 ++++++++++++++++++
 tests/negr_f.c          |  26 ++++++++++++++++++
 tests/ori.c             |  31 ++++++++++++++++++++++
 tests/orr.c             |  48 +++++++++++++++++++++++++++++++++
 tests/qdivr.c           |  45 +++++++++++++++++++++++++++++++
 tests/qdivr_u.c         |  43 ++++++++++++++++++++++++++++++
 tests/qmulr.c           |  59 +++++++++++++++++++++++++++++++++++++++++
 tests/qmulr_u.c         |  47 +++++++++++++++++++++++++++++++++
 tests/remr.c            |  60 +++++++++++++++++++++++++++++++++++++++++
 tests/remr_u.c          |  56 +++++++++++++++++++++++++++++++++++++++
 tests/rshi.c            |  28 ++++++++++++++++++++
 tests/rshi_u.c          |  28 ++++++++++++++++++++
 tests/rshr.c            |  63 +++++++++++++++++++++++++++++++++++++++++++
 tests/rshr_u.c          |  62 +++++++++++++++++++++++++++++++++++++++++++
 tests/sqrtr_d.c         |  25 ++++++++++++++++++
 tests/sqrtr_f.c         |  25 ++++++++++++++++++
 tests/sti_c.c           |  31 ++++++++++++++++++++++
 tests/sti_d.c           |  31 ++++++++++++++++++++++
 tests/sti_f.c           |  31 ++++++++++++++++++++++
 tests/sti_i.c           |  31 ++++++++++++++++++++++
 tests/sti_l.c           |  33 +++++++++++++++++++++++
 tests/sti_s.c           |  31 ++++++++++++++++++++++
 tests/str_atomic.c      |  32 ++++++++++++++++++++++
 tests/str_c.c           |  32 ++++++++++++++++++++++
 tests/str_d.c           |  32 ++++++++++++++++++++++
 tests/str_f.c           |  32 ++++++++++++++++++++++
 tests/str_i.c           |  32 ++++++++++++++++++++++
 tests/str_l.c           |  34 ++++++++++++++++++++++++
 tests/str_s.c           |  32 ++++++++++++++++++++++
 tests/stxi_c.c          |  32 ++++++++++++++++++++++
 tests/stxi_d.c          |  32 ++++++++++++++++++++++
 tests/stxi_f.c          |  32 ++++++++++++++++++++++
 tests/stxi_i.c          |  32 ++++++++++++++++++++++
 tests/stxi_l.c          |  34 ++++++++++++++++++++++++
 tests/stxi_s.c          |  32 ++++++++++++++++++++++
 tests/stxr_c.c          |  33 +++++++++++++++++++++++
 tests/stxr_d.c          |  33 +++++++++++++++++++++++
 tests/stxr_f.c          |  33 +++++++++++++++++++++++
 tests/stxr_i.c          |  33 +++++++++++++++++++++++
 tests/stxr_l.c          |  35 ++++++++++++++++++++++++
 tests/stxr_s.c          |  33 +++++++++++++++++++++++
 tests/subr.c            |  26 ++++++++++++++++++
 tests/subr_d.c          |  27 +++++++++++++++++++
 tests/subr_f.c          |  27 +++++++++++++++++++
 tests/subx.c            |  63 +++++++++++++++++++++++++++++++++++++++++++
 tests/swap_atomic.c     |  32 ++++++++++++++++++++++
 tests/test-bcode-absr_f | Bin 0 -> 288432 bytes
 tests/truncr_d_i.c      |  30 +++++++++++++++++++++
 tests/truncr_d_l.c      |  32 ++++++++++++++++++++++
 tests/truncr_f_i.c      |  30 +++++++++++++++++++++
 tests/truncr_f_l.c      |  32 ++++++++++++++++++++++
 tests/xori.c            |  31 ++++++++++++++++++++++
 tests/xorr.c            |  48 +++++++++++++++++++++++++++++++++
 207 files changed, 6905 insertions(+)
 create mode 100644 tests/absr_f.c
 create mode 100644 tests/addi.c
 create mode 100644 tests/addr.c
 create mode 100644 tests/addr_d.c
 create mode 100644 tests/addr_f.c
 create mode 100644 tests/addx.c
 create mode 100644 tests/andi.c
 create mode 100644 tests/andr.c
 create mode 100644 tests/beqi.c
 create mode 100644 tests/beqr.c
 create mode 100644 tests/beqr_d.c
 create mode 100644 tests/beqr_f.c
 create mode 100644 tests/bgei.c
 create mode 100644 tests/bgei_u.c
 create mode 100644 tests/bger.c
 create mode 100644 tests/bger_d.c
 create mode 100644 tests/bger_f.c
 create mode 100644 tests/bger_u.c
 create mode 100644 tests/bgti.c
 create mode 100644 tests/bgti_u.c
 create mode 100644 tests/bgtr.c
 create mode 100644 tests/bgtr_d.c
 create mode 100644 tests/bgtr_f.c
 create mode 100644 tests/bgtr_u.c
 create mode 100644 tests/blei.c
 create mode 100644 tests/blei_u.c
 create mode 100644 tests/bler.c
 create mode 100644 tests/bler_d.c
 create mode 100644 tests/bler_f.c
 create mode 100644 tests/bler_u.c
 create mode 100644 tests/bltgtr_d.c
 create mode 100644 tests/bltgtr_f.c
 create mode 100644 tests/blti.c
 create mode 100644 tests/blti_u.c
 create mode 100644 tests/bltr.c
 create mode 100644 tests/bltr_d.c
 create mode 100644 tests/bltr_f.c
 create mode 100644 tests/bltr_u.c
 create mode 100644 tests/bmci.c
 create mode 100644 tests/bmcr.c
 create mode 100644 tests/bmsi.c
 create mode 100644 tests/bmsr.c
 create mode 100644 tests/bnei.c
 create mode 100644 tests/bner.c
 create mode 100644 tests/bner_d.c
 create mode 100644 tests/bner_f.c
 create mode 100644 tests/boaddi.c
 create mode 100644 tests/boaddi_u.c
 create mode 100644 tests/boaddr.c
 create mode 100644 tests/boaddr_u.c
 create mode 100644 tests/bordr_d.c
 create mode 100644 tests/bordr_f.c
 create mode 100644 tests/bosubi.c
 create mode 100644 tests/bosubi_u.c
 create mode 100644 tests/bosubr.c
 create mode 100644 tests/bosubr_u.c
 create mode 100644 tests/bswapr_ui.c
 create mode 100644 tests/bswapr_ul.c
 create mode 100644 tests/bswapr_us.c
 create mode 100644 tests/buneqr_d.c
 create mode 100644 tests/buneqr_f.c
 create mode 100644 tests/bunger_d.c
 create mode 100644 tests/bunger_f.c
 create mode 100644 tests/bungtr_d.c
 create mode 100644 tests/bungtr_f.c
 create mode 100644 tests/bunler_d.c
 create mode 100644 tests/bunler_f.c
 create mode 100644 tests/bunltr_d.c
 create mode 100644 tests/bunltr_f.c
 create mode 100644 tests/bunordr_d.c
 create mode 100644 tests/bunordr_f.c
 create mode 100644 tests/bxaddi.c
 create mode 100644 tests/bxaddi_u.c
 create mode 100644 tests/bxaddr.c
 create mode 100644 tests/bxaddr_u.c
 create mode 100644 tests/bxsubi.c
 create mode 100644 tests/bxsubi_u.c
 create mode 100644 tests/bxsubr.c
 create mode 100644 tests/bxsubr_u.c
 create mode 100644 tests/call_10.c
 create mode 100644 tests/call_double.c
 create mode 100644 tests/call_float.c
 create mode 100644 tests/callee_9.c
 create mode 100644 tests/cas_atomic.c
 create mode 100644 tests/comr.c
 create mode 100644 tests/divr.c
 create mode 100644 tests/divr_d.c
 create mode 100644 tests/divr_f.c
 create mode 100644 tests/divr_u.c
 create mode 100644 tests/do_jit.h
 create mode 100644 tests/extr_c.c
 create mode 100644 tests/extr_d.c
 create mode 100644 tests/extr_d_f.c
 create mode 100644 tests/extr_f.c
 create mode 100644 tests/extr_f_d.c
 create mode 100644 tests/extr_i.c
 create mode 100644 tests/extr_s.c
 create mode 100644 tests/extr_uc.c
 create mode 100644 tests/extr_ui.c
 create mode 100644 tests/extr_us.c
 create mode 100644 tests/jmp0.c
 create mode 100644 tests/jmp_table.c
 create mode 100644 tests/jmpi.c
 create mode 100644 tests/jmpi_local.c
 create mode 100644 tests/jmpr.c
 create mode 100644 tests/ldi_c.c
 create mode 100644 tests/ldi_d.c
 create mode 100644 tests/ldi_f.c
 create mode 100644 tests/ldi_i.c
 create mode 100644 tests/ldi_l.c
 create mode 100644 tests/ldi_s.c
 create mode 100644 tests/ldi_uc.c
 create mode 100644 tests/ldi_ui.c
 create mode 100644 tests/ldi_us.c
 create mode 100644 tests/ldr_atomic.c
 create mode 100644 tests/ldr_c.c
 create mode 100644 tests/ldr_d.c
 create mode 100644 tests/ldr_f.c
 create mode 100644 tests/ldr_i.c
 create mode 100644 tests/ldr_l.c
 create mode 100644 tests/ldr_s.c
 create mode 100644 tests/ldr_uc.c
 create mode 100644 tests/ldr_ui.c
 create mode 100644 tests/ldr_us.c
 create mode 100644 tests/ldxi_c.c
 create mode 100644 tests/ldxi_d.c
 create mode 100644 tests/ldxi_f.c
 create mode 100644 tests/ldxi_i.c
 create mode 100644 tests/ldxi_l.c
 create mode 100644 tests/ldxi_s.c
 create mode 100644 tests/ldxi_uc.c
 create mode 100644 tests/ldxi_ui.c
 create mode 100644 tests/ldxi_us.c
 create mode 100644 tests/ldxr_c.c
 create mode 100644 tests/ldxr_d.c
 create mode 100644 tests/ldxr_f.c
 create mode 100644 tests/ldxr_i.c
 create mode 100644 tests/ldxr_l.c
 create mode 100644 tests/ldxr_s.c
 create mode 100644 tests/ldxr_uc.c
 create mode 100644 tests/ldxr_ui.c
 create mode 100644 tests/ldxr_us.c
 create mode 100644 tests/link-register.c
 create mode 100644 tests/lshi.c
 create mode 100644 tests/lshr.c
 create mode 100644 tests/makefile
 create mode 100644 tests/mov_addr.c
 create mode 100644 tests/movi.c
 create mode 100644 tests/movi_d.c
 create mode 100644 tests/movi_f.c
 create mode 100644 tests/mulr.c
 create mode 100644 tests/mulr_d.c
 create mode 100644 tests/mulr_f.c
 create mode 100644 tests/negr.c
 create mode 100644 tests/negr_d.c
 create mode 100644 tests/negr_f.c
 create mode 100644 tests/ori.c
 create mode 100644 tests/orr.c
 create mode 100644 tests/qdivr.c
 create mode 100644 tests/qdivr_u.c
 create mode 100644 tests/qmulr.c
 create mode 100644 tests/qmulr_u.c
 create mode 100644 tests/remr.c
 create mode 100644 tests/remr_u.c
 create mode 100644 tests/rshi.c
 create mode 100644 tests/rshi_u.c
 create mode 100644 tests/rshr.c
 create mode 100644 tests/rshr_u.c
 create mode 100644 tests/sqrtr_d.c
 create mode 100644 tests/sqrtr_f.c
 create mode 100644 tests/sti_c.c
 create mode 100644 tests/sti_d.c
 create mode 100644 tests/sti_f.c
 create mode 100644 tests/sti_i.c
 create mode 100644 tests/sti_l.c
 create mode 100644 tests/sti_s.c
 create mode 100644 tests/str_atomic.c
 create mode 100644 tests/str_c.c
 create mode 100644 tests/str_d.c
 create mode 100644 tests/str_f.c
 create mode 100644 tests/str_i.c
 create mode 100644 tests/str_l.c
 create mode 100644 tests/str_s.c
 create mode 100644 tests/stxi_c.c
 create mode 100644 tests/stxi_d.c
 create mode 100644 tests/stxi_f.c
 create mode 100644 tests/stxi_i.c
 create mode 100644 tests/stxi_l.c
 create mode 100644 tests/stxi_s.c
 create mode 100644 tests/stxr_c.c
 create mode 100644 tests/stxr_d.c
 create mode 100644 tests/stxr_f.c
 create mode 100644 tests/stxr_i.c
 create mode 100644 tests/stxr_l.c
 create mode 100644 tests/stxr_s.c
 create mode 100644 tests/subr.c
 create mode 100644 tests/subr_d.c
 create mode 100644 tests/subr_f.c
 create mode 100644 tests/subx.c
 create mode 100644 tests/swap_atomic.c
 create mode 100755 tests/test-bcode-absr_f
 create mode 100644 tests/truncr_d_i.c
 create mode 100644 tests/truncr_d_l.c
 create mode 100644 tests/truncr_f_i.c
 create mode 100644 tests/truncr_f_l.c
 create mode 100644 tests/xori.c
 create mode 100644 tests/xorr.c

(limited to 'tests')

diff --git a/tests/absr_f.c b/tests/absr_f.c
new file mode 100644
index 0000000..cc070b6
--- /dev/null
+++ b/tests/absr_f.c
@@ -0,0 +1,19 @@
+#include <ejit/ejit.h>
+#include <assert.h>
+#include "do_jit.h"
+
+int main()
+{
+	struct ejit_operand operands[1] = {
+		EJIT_OPERAND_FPR(0, EJIT_DOUBLE)
+	};
+	struct ejit_func *f = ejit_create_func(EJIT_DOUBLE, 1, operands);
+	ejit_absr_f(f, EJIT_FPR(0), EJIT_FPR(0));
+	ejit_retr_f(f, EJIT_FPR(0));
+	ejit_select_compile_func(f, 0, 1, do_jit);
+
+	assert(ejit_run_func_f_1(f, ejit_double(0.0)) == 0.0);
+	assert(ejit_run_func_f_1(f, ejit_double(-0.0)) == 0.0);
+	assert(ejit_run_func_f_1(f, ejit_double(0.5)) == 0.5);
+	assert(ejit_run_func_f_1(f, ejit_double(-0.5)) == 0.5);
+}
diff --git a/tests/addi.c b/tests/addi.c
new file mode 100644
index 0000000..27cdfab
--- /dev/null
+++ b/tests/addi.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_addi(j, JIT_R0, JIT_R0, 69);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	int (*f)(int) = ret;
+	ASSERT(f(42) == 111);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/addr.c b/tests/addr.c
new file mode 100644
index 0000000..f524aa6
--- /dev/null
+++ b/tests/addr.c
@@ -0,0 +1,23 @@
+#include <ejit/ejit.h>
+
+int
+main (int argc, char *argv[])
+{
+	struct ejit_operand operands[2] = {
+		EJIT_OPERAND_GPR(0, EJIT_LONG),
+		EJIT_OPERAND_GPR(1, EJIT_LONG)
+	};
+
+	struct ejit_func *f = ejit_create_func(EJIT_LONG, 2, operands);
+
+	ejit_addr(j, EJIT_GPR(0), EJIT_GPR(0), EJIT_GPR(1));
+	ejit_retr(j, EJIT_GPR(0));
+
+	ejit_compile(f);
+
+	struct ejit_arg args[2] = {
+		EJIT_ARG(42, EJIT_LONG),
+		EJIT_ARG(69, EJIT_LONG)
+	};
+	ASSERT(ejit_run_func(f, 2, args) == 111);
+}
diff --git a/tests/addr_d.c b/tests/addr_d.c
new file mode 100644
index 0000000..2aa9002
--- /dev/null
+++ b/tests/addr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_addr_d(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	double (*f)(double, double) = ret;
+	ASSERT(f(42., 69.) == 111.);
+	ASSERT(f(42.5, 69.5) == 112.);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/addr_f.c b/tests/addr_f.c
new file mode 100644
index 0000000..d27ce8b
--- /dev/null
+++ b/tests/addr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_addr_f(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	float (*f)(float, float) = ret;
+	ASSERT(f(42.f, 69.f) == 111.f);
+	ASSERT(f(42.5f, 69.5f) == 112.f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/addx.c b/tests/addx.c
new file mode 100644
index 0000000..94b2f19
--- /dev/null
+++ b/tests/addx.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_movi(j, JIT_R2, 0);
+	jit_addcr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_addxi(j, JIT_R2, JIT_R2, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R2);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0, 0) == 0);
+
+#if EJIT_WORDSIZE == 32
+	/* carry */
+	ASSERT(f(0xffffffff, 0xffffffff) == 1);
+	/* overflow */
+	ASSERT(f(0x7fffffff, 1) == 0);
+	/* overflow */
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	/* carry */
+	ASSERT(f(0x7fffffff, 0x80000000) == 0);
+	/* carry+overflow */
+	ASSERT(f(0x80000000, 0x80000000) == 1);
+#else
+	/* nothing */
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	/* nothing */
+	ASSERT(f(0x7fffffff, 1) == 0);
+	/* nothing */
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	/* nothing */
+	ASSERT(f(0x7fffffff, 0x80000000) == 0);
+	/* nothing */
+	ASSERT(f(0x80000000, 0x80000000) == 0);
+	/* carry */
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+	/* overflow */
+	ASSERT(f(0x7fffffffffffffff, 1) == 0);
+	/* overflow */
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+	/* overflow */
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+	/* carry+overflow */
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/andi.c b/tests/andi.c
new file mode 100644
index 0000000..fa3551b
--- /dev/null
+++ b/tests/andi.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_andi(j, JIT_R0, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff) == 1);
+	ASSERT(f(0x80000000) == 0);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff) == 1);
+	ASSERT(f(0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/andr.c b/tests/andr.c
new file mode 100644
index 0000000..c4aaeaf
--- /dev/null
+++ b/tests/andr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_andr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 1);
+	ASSERT(f(1, 0x7fffffff) == 1);
+	ASSERT(f(0x80000000, 1) == 0);
+	ASSERT(f(1, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0x7fffffff);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0) == 0);
+	ASSERT(f(0, 0x7fffffff) == 0);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff, 1) == 1);
+	ASSERT(f(1, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0x8000000000000000, 1) == 0);
+	ASSERT(f(1, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/beqi.c b/tests/beqi.c
new file mode 100644
index 0000000..b366a8e
--- /dev/null
+++ b/tests/beqi.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_beqi(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/beqr.c b/tests/beqr.c
new file mode 100644
index 0000000..0cc4476
--- /dev/null
+++ b/tests/beqr.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_beqr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/beqr_d.c b/tests/beqr_d.c
new file mode 100644
index 0000000..8d61e6e
--- /dev/null
+++ b/tests/beqr_d.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_beqr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/beqr_f.c b/tests/beqr_f.c
new file mode 100644
index 0000000..7463ed6
--- /dev/null
+++ b/tests/beqr_f.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_beqr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgei.c b/tests/bgei.c
new file mode 100644
index 0000000..e0b8e1a
--- /dev/null
+++ b/tests/bgei.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bgei(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgei_u.c b/tests/bgei_u.c
new file mode 100644
index 0000000..d2997ff
--- /dev/null
+++ b/tests/bgei_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bgei_u(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bger.c b/tests/bger.c
new file mode 100644
index 0000000..651a9e8
--- /dev/null
+++ b/tests/bger.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bger(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bger_d.c b/tests/bger_d.c
new file mode 100644
index 0000000..6a9cea3
--- /dev/null
+++ b/tests/bger_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bger_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bger_f.c b/tests/bger_f.c
new file mode 100644
index 0000000..7c4974f
--- /dev/null
+++ b/tests/bger_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bger_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bger_u.c b/tests/bger_u.c
new file mode 100644
index 0000000..05038d5
--- /dev/null
+++ b/tests/bger_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bger_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgti.c b/tests/bgti.c
new file mode 100644
index 0000000..79ea2d4
--- /dev/null
+++ b/tests/bgti.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bgti(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgti_u.c b/tests/bgti_u.c
new file mode 100644
index 0000000..69325df
--- /dev/null
+++ b/tests/bgti_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bgti_u(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgtr.c b/tests/bgtr.c
new file mode 100644
index 0000000..c6c1fda
--- /dev/null
+++ b/tests/bgtr.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bgtr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgtr_d.c b/tests/bgtr_d.c
new file mode 100644
index 0000000..aa9b23a
--- /dev/null
+++ b/tests/bgtr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bgtr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgtr_f.c b/tests/bgtr_f.c
new file mode 100644
index 0000000..6245644
--- /dev/null
+++ b/tests/bgtr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bgtr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bgtr_u.c b/tests/bgtr_u.c
new file mode 100644
index 0000000..53373f0
--- /dev/null
+++ b/tests/bgtr_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bgtr_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/blei.c b/tests/blei.c
new file mode 100644
index 0000000..46ce461
--- /dev/null
+++ b/tests/blei.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_blei(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/blei_u.c b/tests/blei_u.c
new file mode 100644
index 0000000..f8ed875
--- /dev/null
+++ b/tests/blei_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_blei_u(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bler.c b/tests/bler.c
new file mode 100644
index 0000000..cf835e0
--- /dev/null
+++ b/tests/bler.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bler(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bler_d.c b/tests/bler_d.c
new file mode 100644
index 0000000..f67df1a
--- /dev/null
+++ b/tests/bler_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bler_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bler_f.c b/tests/bler_f.c
new file mode 100644
index 0000000..ff18190
--- /dev/null
+++ b/tests/bler_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bler_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bler_u.c b/tests/bler_u.c
new file mode 100644
index 0000000..87ac322
--- /dev/null
+++ b/tests/bler_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bler_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltgtr_d.c b/tests/bltgtr_d.c
new file mode 100644
index 0000000..d549d08
--- /dev/null
+++ b/tests/bltgtr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bltgtr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltgtr_f.c b/tests/bltgtr_f.c
new file mode 100644
index 0000000..6f4e6ac
--- /dev/null
+++ b/tests/bltgtr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bltgtr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/blti.c b/tests/blti.c
new file mode 100644
index 0000000..dd9c907
--- /dev/null
+++ b/tests/blti.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_blti(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/blti_u.c b/tests/blti_u.c
new file mode 100644
index 0000000..13582c3
--- /dev/null
+++ b/tests/blti_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_blti_u(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltr.c b/tests/bltr.c
new file mode 100644
index 0000000..b5c7976
--- /dev/null
+++ b/tests/bltr.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bltr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltr_d.c b/tests/bltr_d.c
new file mode 100644
index 0000000..d19be55
--- /dev/null
+++ b/tests/bltr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bltr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltr_f.c b/tests/bltr_f.c
new file mode 100644
index 0000000..35eb77b
--- /dev/null
+++ b/tests/bltr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bltr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bltr_u.c b/tests/bltr_u.c
new file mode 100644
index 0000000..d0a9f39
--- /dev/null
+++ b/tests/bltr_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bltr_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bmci.c b/tests/bmci.c
new file mode 100644
index 0000000..e8310e0
--- /dev/null
+++ b/tests/bmci.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bmci(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 0);
+	ASSERT(f(-1) == 0);
+	ASSERT(f(2) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bmcr.c b/tests/bmcr.c
new file mode 100644
index 0000000..3dbc98a
--- /dev/null
+++ b/tests/bmcr.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bmcr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 0);
+	ASSERT(f(1, -1) == 0);
+	ASSERT(f(-1, 1) == 0);
+	ASSERT(f(-1, -1) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bmsi.c b/tests/bmsi.c
new file mode 100644
index 0000000..aaad68a
--- /dev/null
+++ b/tests/bmsi.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bmsi(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 1);
+	ASSERT(f(2) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bmsr.c b/tests/bmsr.c
new file mode 100644
index 0000000..d471fdf
--- /dev/null
+++ b/tests/bmsr.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bmsr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+	ASSERT(f(1, -1) == 1);
+	ASSERT(f(-1, 1) == 1);
+	ASSERT(f(-1, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bnei.c b/tests/bnei.c
new file mode 100644
index 0000000..3e9e376
--- /dev/null
+++ b/tests/bnei.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bnei(j, JIT_R0, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(-1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bner.c b/tests/bner.c
new file mode 100644
index 0000000..d9b2305
--- /dev/null
+++ b/tests/bner.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bner(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bner_d.c b/tests/bner_d.c
new file mode 100644
index 0000000..b45deed
--- /dev/null
+++ b/tests/bner_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bner_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bner_f.c b/tests/bner_f.c
new file mode 100644
index 0000000..f57bbc4
--- /dev/null
+++ b/tests/bner_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bner_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/boaddi.c b/tests/boaddi.c
new file mode 100644
index 0000000..e0fed81
--- /dev/null
+++ b/tests/boaddi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_boaddi(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == 0);
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == overflowed);
+	ASSERT(f(0x80000000) == 0x80000001);
+	ASSERT(f(0xffffffff) == 0);
+#else
+	ASSERT(f(0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/boaddi_u.c b/tests/boaddi_u.c
new file mode 100644
index 0000000..b6ffa89
--- /dev/null
+++ b/tests/boaddi_u.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_boaddi_u(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == overflowed);
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == 0x80000000);
+	ASSERT(f(0x80000000) == 0x80000001);
+	ASSERT(f(0xffffffff) == overflowed);
+#else
+	ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/boaddr.c b/tests/boaddr.c
new file mode 100644
index 0000000..69668f7
--- /dev/null
+++ b/tests/boaddr.c
@@ -0,0 +1,51 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_boaddr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == -2);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == overflowed);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0x80000000) == -1);
+	ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == -2);
+	ASSERT(f(0x7fffffffffffffff, 1) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/boaddr_u.c b/tests/boaddr_u.c
new file mode 100644
index 0000000..1483471
--- /dev/null
+++ b/tests/boaddr_u.c
@@ -0,0 +1,51 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_boaddr_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffu + 0x7fffffffu);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x8000000000000000);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == -2);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bordr_d.c b/tests/bordr_d.c
new file mode 100644
index 0000000..ca44db7
--- /dev/null
+++ b/tests/bordr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bordr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bordr_f.c b/tests/bordr_f.c
new file mode 100644
index 0000000..a3db62e
--- /dev/null
+++ b/tests/bordr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bordr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 1);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 0);
+	ASSERT(f(0.0/0.0, 0) == 0);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bosubi.c b/tests/bosubi.c
new file mode 100644
index 0000000..b1bbc77
--- /dev/null
+++ b/tests/bosubi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bosubi(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == -2);
+	ASSERT(f(0) == -1);
+	ASSERT(f(1) == 0);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == 0x7ffffffe);
+	ASSERT(f(0x80000000) == overflowed);
+	ASSERT(f(0x80000001) == 0x80000000);
+#else
+	ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+	ASSERT(f(0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000001) == 0x8000000000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bosubi_u.c b/tests/bosubi_u.c
new file mode 100644
index 0000000..c04b971
--- /dev/null
+++ b/tests/bosubi_u.c
@@ -0,0 +1,37 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bosubi_u(j, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == -2);
+	ASSERT(f(0) == overflowed);
+	ASSERT(f(1) == 0);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000) == 0x7fffffff);
+#else
+	ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bosubr.c b/tests/bosubr.c
new file mode 100644
index 0000000..01ea9fe
--- /dev/null
+++ b/tests/bosubr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bosubr(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == -1);
+	ASSERT(f(1, 1) == 0);
+	ASSERT(f(1, -1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	ASSERT(f(0x80000000, 0x7fffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+	ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bosubr_u.c b/tests/bosubr_u.c
new file mode 100644
index 0000000..0f6d5b7
--- /dev/null
+++ b/tests/bosubr_u.c
@@ -0,0 +1,47 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bosubr_u(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_patch_here(j, r);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 0);
+	ASSERT(f(0, 1) == overflowed);
+	ASSERT(f(1, 0) == 1);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+	ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bswapr_ui.c b/tests/bswapr_ui.c
new file mode 100644
index 0000000..9c4b42b
--- /dev/null
+++ b/tests/bswapr_ui.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_bswapr_ui(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(0x12345678) == 0x78563412);
+#if EJIT_WORDSIZE > 32
+	ASSERT(f(0xff12345678) == 0x78563412);
+	ASSERT(f(0xff00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bswapr_ul.c b/tests/bswapr_ul.c
new file mode 100644
index 0000000..03136d8
--- /dev/null
+++ b/tests/bswapr_ul.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_bswapr_ul(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(0x12345678) == 0x7856341200000000);
+	ASSERT(f(0xff12345678) == 0x78563412ff000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bswapr_us.c b/tests/bswapr_us.c
new file mode 100644
index 0000000..a2c223b
--- /dev/null
+++ b/tests/bswapr_us.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_bswapr_us(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(0x12345678) == 0x7856);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/buneqr_d.c b/tests/buneqr_d.c
new file mode 100644
index 0000000..e0ed6e9
--- /dev/null
+++ b/tests/buneqr_d.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_buneqr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/buneqr_f.c b/tests/buneqr_f.c
new file mode 100644
index 0000000..4277f86
--- /dev/null
+++ b/tests/buneqr_f.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_buneqr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunger_d.c b/tests/bunger_d.c
new file mode 100644
index 0000000..e65f136
--- /dev/null
+++ b/tests/bunger_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bunger_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunger_f.c b/tests/bunger_f.c
new file mode 100644
index 0000000..0fa542b
--- /dev/null
+++ b/tests/bunger_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bunger_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bungtr_d.c b/tests/bungtr_d.c
new file mode 100644
index 0000000..0985696
--- /dev/null
+++ b/tests/bungtr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bungtr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bungtr_f.c b/tests/bungtr_f.c
new file mode 100644
index 0000000..94a9170
--- /dev/null
+++ b/tests/bungtr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bungtr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 1);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 1);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunler_d.c b/tests/bunler_d.c
new file mode 100644
index 0000000..decd314
--- /dev/null
+++ b/tests/bunler_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bunler_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunler_f.c b/tests/bunler_f.c
new file mode 100644
index 0000000..3b40f95
--- /dev/null
+++ b/tests/bunler_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bunler_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 1);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunltr_d.c b/tests/bunltr_d.c
new file mode 100644
index 0000000..9ce8d63
--- /dev/null
+++ b/tests/bunltr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bunltr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunltr_f.c b/tests/bunltr_f.c
new file mode 100644
index 0000000..d86ce1a
--- /dev/null
+++ b/tests/bunltr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bunltr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 1);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 1);
+	ASSERT(f(0, -1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunordr_d.c b/tests/bunordr_d.c
new file mode 100644
index 0000000..13ed8a6
--- /dev/null
+++ b/tests/bunordr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_reloc_t r = jit_bunordr_d(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bunordr_f.c b/tests/bunordr_f.c
new file mode 100644
index 0000000..663d988
--- /dev/null
+++ b/tests/bunordr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_reloc_t r = jit_bunordr_f(j, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 0);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_reti(j, 1);
+
+	jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == 0);
+	ASSERT(f(1, 0) == 0);
+	ASSERT(f(-1, 0) == 0);
+	ASSERT(f(0, -1) == 0);
+	ASSERT(f(1, 1) == 0);
+
+	ASSERT(f(0, 0.0/0.0) == 1);
+	ASSERT(f(0.0/0.0, 0) == 1);
+	ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxaddi.c b/tests/bxaddi.c
new file mode 100644
index 0000000..282b1f1
--- /dev/null
+++ b/tests/bxaddi.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bxaddi(j, JIT_R0, 1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == 0);
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == overflowed);
+	ASSERT(f(0x80000000) == 0x80000001);
+	ASSERT(f(0xffffffff) == 0);
+#else
+	ASSERT(f(0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxaddi_u.c b/tests/bxaddi_u.c
new file mode 100644
index 0000000..dc3140e
--- /dev/null
+++ b/tests/bxaddi_u.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bxaddi_u(j, JIT_R0, 1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == overflowed);
+	ASSERT(f(0) == 1);
+	ASSERT(f(1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == 0x80000000);
+	ASSERT(f(0x80000000) == 0x80000001);
+	ASSERT(f(0xffffffff) == overflowed);
+#else
+	ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxaddr.c b/tests/bxaddr.c
new file mode 100644
index 0000000..472906d
--- /dev/null
+++ b/tests/bxaddr.c
@@ -0,0 +1,49 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bxaddr(j, JIT_R0, JIT_R1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == -2);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == overflowed);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0x80000000) == -1);
+	ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == -2);
+	ASSERT(f(0x7fffffffffffffff, 1) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxaddr_u.c b/tests/bxaddr_u.c
new file mode 100644
index 0000000..d40e0ff
--- /dev/null
+++ b/tests/bxaddr_u.c
@@ -0,0 +1,49 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bxaddr_u(j, JIT_R0, JIT_R1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffu + 0x7fffffffu);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+	ASSERT(f(0x7fffffff, 1) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == overflowed);
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x8000000000000000);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == -2);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxsubi.c b/tests/bxsubi.c
new file mode 100644
index 0000000..e6224bf
--- /dev/null
+++ b/tests/bxsubi.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bxsubi(j, JIT_R0, 1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == -2);
+	ASSERT(f(0) == -1);
+	ASSERT(f(1) == 0);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x7fffffff) == 0x7ffffffe);
+	ASSERT(f(0x80000000) == overflowed);
+	ASSERT(f(0x80000001) == 0x80000000);
+#else
+	ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+	ASSERT(f(0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000001) == 0x8000000000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxsubi_u.c b/tests/bxsubi_u.c
new file mode 100644
index 0000000..6c1d1f3
--- /dev/null
+++ b/tests/bxsubi_u.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_bxsubi_u(j, JIT_R0, 1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(-1) == -2);
+	ASSERT(f(0) == overflowed);
+	ASSERT(f(1) == 0);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000) == 0x7fffffff);
+#else
+	ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxsubr.c b/tests/bxsubr.c
new file mode 100644
index 0000000..50f5dbb
--- /dev/null
+++ b/tests/bxsubr.c
@@ -0,0 +1,46 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bxsubr(j, JIT_R0, JIT_R1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(0, 1) == -1);
+	ASSERT(f(1, 1) == 0);
+	ASSERT(f(1, -1) == 2);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	ASSERT(f(0x80000000, 0x7fffffff) == overflowed);
+	ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+	ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/bxsubr_u.c b/tests/bxsubr_u.c
new file mode 100644
index 0000000..771ea3c
--- /dev/null
+++ b/tests/bxsubr_u.c
@@ -0,0 +1,45 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_reloc_t r = jit_bxsubr_u(j, JIT_R0, JIT_R1);
+	jit_movi(j, JIT_R0, overflowed);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0, 0) == 0);
+	ASSERT(f(1, 1) == 0);
+	ASSERT(f(0, 1) == overflowed);
+	ASSERT(f(1, 0) == 1);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+	ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+	ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+	ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/call_10.c b/tests/call_10.c
new file mode 100644
index 0000000..533acda
--- /dev/null
+++ b/tests/call_10.c
@@ -0,0 +1,64 @@
+#include "test.h"
+
+static int32_t f(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e,
+                 int32_t f, int32_t g, int32_t h, int32_t i, int32_t j) {
+	ASSERT(a == 0);
+	ASSERT(b == 1);
+	ASSERT(c == 2);
+	ASSERT(d == 3);
+	ASSERT(e == 4);
+	ASSERT(f == 5);
+	ASSERT(g == 6);
+	ASSERT(h == 7);
+	ASSERT(i == 8);
+	ASSERT(j == 9);
+	return 42;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+	jit_operand_t args[10] = {
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                0 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                1 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                2 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                3 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                4 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                5 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                6 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                7 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                8 * sizeof(int32_t)),
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0,
+		                9 * sizeof(int32_t))
+	};
+	jit_calli(j, f, 10, args);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	int32_t (*f)(int32_t*) = ret;
+
+	int32_t iargs[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+	ASSERT(f(iargs) == 42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/call_double.c b/tests/call_double.c
new file mode 100644
index 0000000..1138655
--- /dev/null
+++ b/tests/call_double.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static double f(int32_t a, double b) {
+	return b + a;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_operand_t args[2] = {
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 0),
+		jit_operand_mem(JIT_OPERAND_ABI_DOUBLE, JIT_R1, 0)
+	};
+	jit_calli(j, f, 2, args);
+	jit_retval_d(j, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	double (*f)(int32_t*, double*) = ret;
+
+	double d = 22.0f;
+	int32_t i = 20;
+	ASSERT(f(&i, &d) == 42.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/call_float.c b/tests/call_float.c
new file mode 100644
index 0000000..9534e4b
--- /dev/null
+++ b/tests/call_float.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static float f(int32_t a, float b) {
+	return b + a;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_operand_t args[2] = {
+		jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 0),
+		jit_operand_mem(JIT_OPERAND_ABI_FLOAT, JIT_R1, 0)
+	};
+	jit_calli(j, f, 2, args);
+	jit_retval_f(j, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	float (*f)(int32_t*, float*) = ret;
+
+	float d = 22.0f;
+	int32_t i = 20;
+	ASSERT(f(&i, &d) == 42.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/callee_9.c b/tests/callee_9.c
new file mode 100644
index 0000000..9d4e217
--- /dev/null
+++ b/tests/callee_9.c
@@ -0,0 +1,68 @@
+#include "test.h"
+
+struct args
+{
+	int8_t a;
+	int16_t b;
+	int32_t c;
+	jit_word_t d;
+	uint16_t e;
+	float f;
+	double g;
+	float h;
+};
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+	jit_operand_t args[9] = {
+		jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R0),
+		jit_operand_gpr(JIT_OPERAND_ABI_INT8, JIT_R1),
+		jit_operand_gpr(JIT_OPERAND_ABI_INT16, JIT_R2),
+		jit_operand_gpr(JIT_OPERAND_ABI_INT32, JIT_V0),
+		jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_V1),
+		jit_operand_gpr(JIT_OPERAND_ABI_UINT16, JIT_V2),
+		jit_operand_fpr(JIT_OPERAND_ABI_FLOAT, JIT_F0),
+		jit_operand_fpr(JIT_OPERAND_ABI_DOUBLE, JIT_F1),
+		jit_operand_fpr(JIT_OPERAND_ABI_FLOAT, JIT_F2),
+	};
+	jit_load_args(j, 9, args);
+	jit_stxi_c(j, offsetof(struct args, a), JIT_R0, JIT_R1); // a
+	jit_stxi_s(j, offsetof(struct args, b), JIT_R0, JIT_R2); // b
+	jit_stxi_i(j, offsetof(struct args, c), JIT_R0, JIT_V0); // c
+	jit_stxi(j,   offsetof(struct args, d), JIT_R0, JIT_V1);// d
+	jit_stxi_s(j, offsetof(struct args, e), JIT_R0, JIT_V2); // e
+	jit_stxi_f(j, offsetof(struct args, f), JIT_R0, JIT_F0); // f
+	jit_stxi_d(j, offsetof(struct args, g), JIT_R0, JIT_F1); // g
+	jit_stxi_f(j, offsetof(struct args, h), JIT_R0, JIT_F2); // h
+
+	jit_leave_jit_abi(j, 3, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	struct args* (*f)(struct args*, int8_t, int16_t, int32_t, jit_word_t,
+	                  uint16_t, float, double, float) = ret;
+
+	struct args in = { 0, 1, 2, 3, 4, 5, 6, 7 };
+	struct args out;
+	ASSERT(f(&out, in.a, in.b, in.c, in.d, in.e, in.f, in.g, in.h) == &out);
+	ASSERT(in.a == out.a);
+	ASSERT(in.b == out.b);
+	ASSERT(in.c == out.c);
+	ASSERT(in.d == out.d);
+	ASSERT(in.e == out.e);
+	ASSERT(in.f == out.f);
+	ASSERT(in.g == out.g);
+	ASSERT(in.h == out.h);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/cas_atomic.c b/tests/cas_atomic.c
new file mode 100644
index 0000000..a382eae
--- /dev/null
+++ b/tests/cas_atomic.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R2));
+
+	jit_cas_atomic(j, JIT_R0, JIT_R0, JIT_R1, JIT_R2);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int32_t, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(&data[1], 0, 0x0f0f0f0f);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x0f0f0f0f);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/comr.c b/tests/comr.c
new file mode 100644
index 0000000..3cfacac
--- /dev/null
+++ b/tests/comr.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_comr(j, JIT_R0, JIT_R0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0) == 0xffffffff);
+	ASSERT(f(1) == 0xfffffffe);
+	ASSERT(f(0xffffffff) == 0);
+	ASSERT(f(0x80000000) == 0x7fffffff);
+	ASSERT(f(0x7fffffff) == 0x80000000);
+	ASSERT(f(0x80000001) == 0x7ffffffe);
+#else
+	ASSERT(f(0) == 0xffffffffffffffff);
+	ASSERT(f(1) == 0xfffffffffffffffe);
+	ASSERT(f(0xffffffff) == 0xffffffff00000000);
+	ASSERT(f(0x80000000) == 0xffffffff7fffffff);
+	ASSERT(f(0x7fffffff) == 0xffffffff80000000);
+	ASSERT(f(0x80000001) == 0xffffffff7ffffffe);
+	ASSERT(f(0xffffffffffffffff) == 0);
+	ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+	ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0x8000000000000001) == 0x7ffffffffffffffe);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/divr.c b/tests/divr.c
new file mode 100644
index 0000000..c68fcaa
--- /dev/null
+++ b/tests/divr.c
@@ -0,0 +1,60 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_divr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+	ASSERT(f(1, 0x7fffffff) == 0);
+	ASSERT(f(0x80000000, 1) == 0x80000000);
+	ASSERT(f(1, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 2) == 0x3fffffff);
+	ASSERT(f(2, 0x7fffffff) == 0);
+	ASSERT(f(2, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0);
+	ASSERT(f(0, 0x7fffffff) == 0);
+	ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000, 2) == 0xc0000000);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000001);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0);
+#else
+	ASSERT(f(0x80000000, 2) == 0x40000000);
+	ASSERT(f(0x80000000, 0x7fffffff) == 1);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 2);
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+	ASSERT(f(1, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+	ASSERT(f(1, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 2) == 0x3fffffffffffffff);
+	ASSERT(f(2, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x8000000000000000, 2) == 0xc000000000000000);
+	ASSERT(f(2, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/divr_d.c b/tests/divr_d.c
new file mode 100644
index 0000000..41dd6c3
--- /dev/null
+++ b/tests/divr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_divr_d(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	double (*f)(double, double) = ret;
+	ASSERT(f(-0.5f, 0.5f) == -1.0f);
+	ASSERT(f(1.25f, 0.5f) == 2.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/divr_f.c b/tests/divr_f.c
new file mode 100644
index 0000000..085ecff
--- /dev/null
+++ b/tests/divr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_divr_f(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	float (*f)(float, float) = ret;
+	ASSERT(f(-0.5f, 0.5f) == -1.0f);
+	ASSERT(f(1.25f, 0.5f) == 2.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/divr_u.c b/tests/divr_u.c
new file mode 100644
index 0000000..65d0ae2
--- /dev/null
+++ b/tests/divr_u.c
@@ -0,0 +1,55 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_divr_u(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+	ASSERT(f(1, 0x7fffffff) == 0);
+	ASSERT(f(0x80000000, 1) == 0x80000000);
+	ASSERT(f(1, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 2) == 0x3fffffff);
+	ASSERT(f(2, 0x7fffffff) == 0);
+	ASSERT(f(0x80000000, 2) == 0x40000000);
+	ASSERT(f(2, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0);
+	ASSERT(f(0x80000000, 0x7fffffff) == 1);
+	ASSERT(f(0, 0x7fffffff) == 0);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 2);
+	ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#if EJIT_WORDSIZE != 32
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+	ASSERT(f(1, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+	ASSERT(f(1, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 2) == 0x3fffffffffffffff);
+	ASSERT(f(2, 0x7fffffffffffffff) == 0);
+	ASSERT(f(0x8000000000000000, 2) == 0x4000000000000000);
+	ASSERT(f(2, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 2);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/do_jit.h b/tests/do_jit.h
new file mode 100644
index 0000000..d0d4921
--- /dev/null
+++ b/tests/do_jit.h
@@ -0,0 +1,10 @@
+#ifndef DOJIT_H
+#define DOJIT_H
+
+#ifdef FORCE_BCODE
+static bool do_jit = false;
+#else
+static bool do_jit = true;
+#endif
+
+#endif /* DOJIT_H */
diff --git a/tests/extr_c.c b/tests/extr_c.c
new file mode 100644
index 0000000..ff652a7
--- /dev/null
+++ b/tests/extr_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_c(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xf) == 0xf);
+	ASSERT(f(0xff) == -1);
+	ASSERT(f(0xfff) == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_d.c b/tests/extr_d.c
new file mode 100644
index 0000000..ac8b2f9
--- /dev/null
+++ b/tests/extr_d.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_extr_d(j, JIT_F0, JIT_R0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0.0);
+	ASSERT(f(1) == 1.0);
+	ASSERT(f(-100) == -100.0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_d_f.c b/tests/extr_d_f.c
new file mode 100644
index 0000000..87ad4a8
--- /dev/null
+++ b/tests/extr_d_f.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_extr_d_f(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0.0f);
+	ASSERT(f(0.5) == 0.5f);
+	ASSERT(f(1.0 / 0.0) == 1.0f / 0.0f);
+	ASSERT(f(1.25) == 1.25f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_f.c b/tests/extr_f.c
new file mode 100644
index 0000000..7721127
--- /dev/null
+++ b/tests/extr_f.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_extr_f(j, JIT_F0, JIT_R0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0.0f);
+	ASSERT(f(1) == 1.0f);
+	ASSERT(f(-100) == -100.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_f_d.c b/tests/extr_f_d.c
new file mode 100644
index 0000000..8a9d38c
--- /dev/null
+++ b/tests/extr_f_d.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_extr_f_d(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(f(0.0f) == 0.0);
+	ASSERT(f(0.5f) == 0.5);
+	ASSERT(f(1.0f / 0.0f) == 1.0 / 0.0);
+	ASSERT(f(1.25f) == 1.25);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_i.c b/tests/extr_i.c
new file mode 100644
index 0000000..cf3a2e1
--- /dev/null
+++ b/tests/extr_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_i(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xfffffff) == 0xfffffff);
+	ASSERT(f(0xffffffff) == -1);
+	ASSERT(f(0xfffffffff) == -1);
+	ASSERT(f(0xf00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_s.c b/tests/extr_s.c
new file mode 100644
index 0000000..08ea42e
--- /dev/null
+++ b/tests/extr_s.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_s(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xfff) == 0xfff);
+	ASSERT(f(0xffff) == -1);
+	ASSERT(f(0xfffff) == -1);
+	ASSERT(f(0xf0000) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_uc.c b/tests/extr_uc.c
new file mode 100644
index 0000000..063962b
--- /dev/null
+++ b/tests/extr_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_uc(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xff) == 0xff);
+	ASSERT(f(0xfff) == 0xff);
+	ASSERT(f(0xf00) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_ui.c b/tests/extr_ui.c
new file mode 100644
index 0000000..457e8f8
--- /dev/null
+++ b/tests/extr_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_ui(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xffffffff) == 0xffffffff);
+	ASSERT(f(0xfffffffff) == 0xffffffff);
+	ASSERT(f(0xf00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/extr_us.c b/tests/extr_us.c
new file mode 100644
index 0000000..61374cc
--- /dev/null
+++ b/tests/extr_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_extr_us(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+	ASSERT(f(1) == 1);
+	ASSERT(f(0xffff) == 0xffff);
+	ASSERT(f(0xfffff) == 0xffff);
+	ASSERT(f(0xf0000) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/jmp0.c b/tests/jmp0.c
new file mode 100644
index 0000000..0f86fe6
--- /dev/null
+++ b/tests/jmp0.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_reloc_t r = jit_jmp(j);
+	jit_patch_here(j, r);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+	ASSERT(f(42) == 42);
+	ASSERT(f(-1) == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/jmp_table.c b/tests/jmp_table.c
new file mode 100644
index 0000000..2ea14cd
--- /dev/null
+++ b/tests/jmp_table.c
@@ -0,0 +1,61 @@
+#include "test.h"
+
+#define NTARGETS ((size_t) 4)
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+	jit_reloc_t default_target = jit_bgei_u(j, JIT_R0, NTARGETS);
+
+	// FIXME: need ldxr with word stride, then can eliminate lshi.
+	jit_lshi(j, JIT_R0, JIT_R0, sizeof(intptr_t) == 4 ? 2 : 3);
+	jit_reloc_t table = jit_mov_addr(j, JIT_R1);
+	jit_ldxr(j, JIT_R1, JIT_R1, JIT_R0);
+	jit_jmpr(j, JIT_R1);
+
+	jit_begin_data (j, (NTARGETS + 1) * sizeof(intptr_t));
+	jit_align(j, sizeof(intptr_t));
+	jit_patch_here(j, table);
+	jit_reloc_t targets[NTARGETS];
+	jit_reloc_t tails[NTARGETS];
+	for (size_t i = 0; i < NTARGETS; i++) {
+		targets[i] = jit_emit_addr(j);
+	}
+	jit_end_data (j);
+
+	for (size_t i = 0; i < NTARGETS; i++) {
+		jit_patch_here(j, targets[i]);
+		jit_movi(j, JIT_R0, i * i);
+		tails[i] = jit_jmp(j);
+	}
+
+	jit_patch_here(j, default_target);
+	jit_movi(j, JIT_R0, 42);
+	for (int i = 0; i < NTARGETS; i++) {
+		jit_patch_here(j, tails[i]);
+	}
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	for (int i = -2; i < ((int) NTARGETS) + 2; i++) {
+		if (i < 0) {
+			ASSERT(f(i) == 42);
+		} else if (i < NTARGETS) {
+			ASSERT(f(i) == i * i);
+		} else {
+			ASSERT(f(i) == 42);
+		}
+	}
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/jmpi.c b/tests/jmpi.c
new file mode 100644
index 0000000..cb12789
--- /dev/null
+++ b/tests/jmpi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+void *tail;
+
+static void *target;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	jit_enter_jit_abi(j, 0, 0, 0);
+	jit_movi(j, JIT_R0, 42);
+	jit_jmpi(j, target);
+	// Unreachable.
+	jit_breakpoint(j);
+	int (*f)(void) = jit_end(j, NULL);
+	ASSERT(f() == 42);
+}
+
+// Make the tail-call target via a separate main_helper because probably the new
+// arena will be allocated farther away, forcing nonlocal jumps.
+static void
+make_target(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	// Tail call target assumes tail caller called enter_jit_abi with compatible
+	// parameters.
+	target = jit_address(j);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+	jit_end(j, NULL);
+
+	main_helper(0, NULL, run_test);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, make_target);
+}
diff --git a/tests/jmpi_local.c b/tests/jmpi_local.c
new file mode 100644
index 0000000..1131997
--- /dev/null
+++ b/tests/jmpi_local.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+
+	jit_reloc_t r = jit_jmp (j);
+	jit_reti (j, 0);
+	jit_pointer_t addr = jit_address (j);
+	jit_reti (j, 1);
+	jit_patch_here (j, r);
+	jit_jmpi (j, addr);
+	jit_reti (j, 2);
+
+	int (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/jmpr.c b/tests/jmpr.c
new file mode 100644
index 0000000..45111f9
--- /dev/null
+++ b/tests/jmpr.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static int tail(void) {
+	return 42;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+	jit_leave_jit_abi(j, 0, 0, align);
+
+	jit_jmpr(j, JIT_R0);
+
+	int (*f)(void*) = jit_end(j, NULL);
+	ASSERT(f(tail) == 42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_c.c b/tests/ldi_c.c
new file mode 100644
index 0000000..c6539c0
--- /dev/null
+++ b/tests/ldi_c.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_c(j, JIT_R0, &data[0]);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_d.c b/tests/ldi_d.c
new file mode 100644
index 0000000..c7574dc
--- /dev/null
+++ b/tests/ldi_d.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static double data = -1.5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_d(j, JIT_F0, &data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == data);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_f.c b/tests/ldi_f.c
new file mode 100644
index 0000000..d5cd095
--- /dev/null
+++ b/tests/ldi_f.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static float data = -1.5f;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_f(j, JIT_F0, &data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == data);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_i.c b/tests/ldi_i.c
new file mode 100644
index 0000000..72035d4
--- /dev/null
+++ b/tests/ldi_i.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint32_t data = 0xffffffff;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_i(j, JIT_R0, &data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_l.c b/tests/ldi_l.c
new file mode 100644
index 0000000..58a8099
--- /dev/null
+++ b/tests/ldi_l.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data = 0xffffffffffffffff;
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_l(j, JIT_R0, &data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == -1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_s.c b/tests/ldi_s.c
new file mode 100644
index 0000000..7d10106
--- /dev/null
+++ b/tests/ldi_s.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint16_t data = 0xffff;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_s(j, JIT_R0, &data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_uc.c b/tests/ldi_uc.c
new file mode 100644
index 0000000..d5c80ac
--- /dev/null
+++ b/tests/ldi_uc.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_uc(j, JIT_R0, data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == 0xff);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_ui.c b/tests/ldi_ui.c
new file mode 100644
index 0000000..bfccc30
--- /dev/null
+++ b/tests/ldi_ui.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_ui(j, JIT_R0, data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == data[0]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldi_us.c b/tests/ldi_us.c
new file mode 100644
index 0000000..970db9c
--- /dev/null
+++ b/tests/ldi_us.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_ldi_us(j, JIT_R0, data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == data[0]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_atomic.c b/tests/ldr_atomic.c
new file mode 100644
index 0000000..339ba56
--- /dev/null
+++ b/tests/ldr_atomic.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static long data[] = { 0x0f0f0f0f, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	/* atm does not test for actual atomicity, just that no segfaults etc happen */
+	jit_ldr_atomic(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == 0x0f0f0f0f);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_c.c b/tests/ldr_c.c
new file mode 100644
index 0000000..a630123
--- /dev/null
+++ b/tests/ldr_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_c(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == -1);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_d.c b/tests/ldr_d.c
new file mode 100644
index 0000000..6a4c1bd
--- /dev/null
+++ b/tests/ldr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_d(j, JIT_F0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == data[0]);
+	ASSERT(f(&data[1]) == data[1]);
+	ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_f.c b/tests/ldr_f.c
new file mode 100644
index 0000000..4ea978d
--- /dev/null
+++ b/tests/ldr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_f(j, JIT_F0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == data[0]);
+	ASSERT(f(&data[1]) == data[1]);
+	ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_i.c b/tests/ldr_i.c
new file mode 100644
index 0000000..a7a4cd0
--- /dev/null
+++ b/tests/ldr_i.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_i(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == -1);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_l.c b/tests/ldr_l.c
new file mode 100644
index 0000000..d689d47
--- /dev/null
+++ b/tests/ldr_l.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_l(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == -1);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_s.c b/tests/ldr_s.c
new file mode 100644
index 0000000..cbb72ab
--- /dev/null
+++ b/tests/ldr_s.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_s(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == -1);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_uc.c b/tests/ldr_uc.c
new file mode 100644
index 0000000..65d56cf
--- /dev/null
+++ b/tests/ldr_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_uc(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == 0xff);
+	ASSERT(f(&data[1]) == 0);
+	ASSERT(f(&data[2]) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_ui.c b/tests/ldr_ui.c
new file mode 100644
index 0000000..92ace34
--- /dev/null
+++ b/tests/ldr_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_ui(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == data[0]);
+	ASSERT(f(&data[1]) == data[1]);
+	ASSERT(f(&data[2]) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldr_us.c b/tests/ldr_us.c
new file mode 100644
index 0000000..5d1a67d
--- /dev/null
+++ b/tests/ldr_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+	jit_ldr_us(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+	ASSERT(f(&data[0]) == data[0]);
+	ASSERT(f(&data[1]) == data[1]);
+	ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_c.c b/tests/ldxi_c.c
new file mode 100644
index 0000000..cc40ddb
--- /dev/null
+++ b/tests/ldxi_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_c(j, JIT_R0, JIT_R0, (uintptr_t)&data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == -1);
+	ASSERT(f(1) == 0);
+	ASSERT(f(2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_d.c b/tests/ldxi_d.c
new file mode 100644
index 0000000..a93e582
--- /dev/null
+++ b/tests/ldxi_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_d(j, JIT_F0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == data[0]);
+	ASSERT(f(8) == data[1]);
+	ASSERT(f(16) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_f.c b/tests/ldxi_f.c
new file mode 100644
index 0000000..015d816
--- /dev/null
+++ b/tests/ldxi_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_f(j, JIT_F0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == data[0]);
+	ASSERT(f(4) == data[1]);
+	ASSERT(f(8) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_i.c b/tests/ldxi_i.c
new file mode 100644
index 0000000..7e53001
--- /dev/null
+++ b/tests/ldxi_i.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+	jit_ldxi_i(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == -1);
+	ASSERT(f(4) == 0);
+	ASSERT(f(8) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_l.c b/tests/ldxi_l.c
new file mode 100644
index 0000000..3a4454f
--- /dev/null
+++ b/tests/ldxi_l.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_l(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == -1);
+	ASSERT(f(8) == 0);
+	ASSERT(f(16) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_s.c b/tests/ldxi_s.c
new file mode 100644
index 0000000..05125da
--- /dev/null
+++ b/tests/ldxi_s.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_s(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == -1);
+	ASSERT(f(2) == 0);
+	ASSERT(f(4) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_uc.c b/tests/ldxi_uc.c
new file mode 100644
index 0000000..dc82aa2
--- /dev/null
+++ b/tests/ldxi_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_uc(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0xff);
+	ASSERT(f(1) == 0);
+	ASSERT(f(2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_ui.c b/tests/ldxi_ui.c
new file mode 100644
index 0000000..4500507
--- /dev/null
+++ b/tests/ldxi_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_ui(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == data[0]);
+	ASSERT(f(4) == data[1]);
+	ASSERT(f(8) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxi_us.c b/tests/ldxi_us.c
new file mode 100644
index 0000000..db2d8c8
--- /dev/null
+++ b/tests/ldxi_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ldxi_us(j, JIT_R0, JIT_R0, (uintptr_t)data);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == data[0]);
+	ASSERT(f(2) == data[1]);
+	ASSERT(f(4) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_c.c b/tests/ldxr_c.c
new file mode 100644
index 0000000..b691b58
--- /dev/null
+++ b/tests/ldxr_c.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_c(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == -1);
+	ASSERT(f(data, 1) == 0);
+	ASSERT(f(data, 2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_d.c b/tests/ldxr_d.c
new file mode 100644
index 0000000..e8bb45e
--- /dev/null
+++ b/tests/ldxr_d.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_d(j, JIT_F0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == data[0]);
+	ASSERT(f(data, 8) == data[1]);
+	ASSERT(f(data, 16) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_f.c b/tests/ldxr_f.c
new file mode 100644
index 0000000..c6dacba
--- /dev/null
+++ b/tests/ldxr_f.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_f(j, JIT_F0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == data[0]);
+	ASSERT(f(data, 4) == data[1]);
+	ASSERT(f(data, 8) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_i.c b/tests/ldxr_i.c
new file mode 100644
index 0000000..e035438
--- /dev/null
+++ b/tests/ldxr_i.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_i(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == -1);
+	ASSERT(f(data, 4) == 0);
+	ASSERT(f(data, 8) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_l.c b/tests/ldxr_l.c
new file mode 100644
index 0000000..6dcb5c7
--- /dev/null
+++ b/tests/ldxr_l.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_l(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == -1);
+	ASSERT(f(data, 8) == 0);
+	ASSERT(f(data, 16) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_s.c b/tests/ldxr_s.c
new file mode 100644
index 0000000..cea155f
--- /dev/null
+++ b/tests/ldxr_s.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_s(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == -1);
+	ASSERT(f(data, 2) == 0);
+	ASSERT(f(data, 4) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_uc.c b/tests/ldxr_uc.c
new file mode 100644
index 0000000..3b6ab3e
--- /dev/null
+++ b/tests/ldxr_uc.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_uc(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == 0xff);
+	ASSERT(f(data, 1) == 0);
+	ASSERT(f(data, 2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_ui.c b/tests/ldxr_ui.c
new file mode 100644
index 0000000..eddb56b
--- /dev/null
+++ b/tests/ldxr_ui.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_ui(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == data[0]);
+	ASSERT(f(data, 4) == data[1]);
+	ASSERT(f(data, 8) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ldxr_us.c b/tests/ldxr_us.c
new file mode 100644
index 0000000..d18c133
--- /dev/null
+++ b/tests/ldxr_us.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_ldxr_us(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+	ASSERT(f(data, 0) == data[0]);
+	ASSERT(f(data, 2) == data[1]);
+	ASSERT(f(data, 4) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/link-register.c b/tests/link-register.c
new file mode 100644
index 0000000..9e5413b
--- /dev/null
+++ b/tests/link-register.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+	jit_reloc_t call_tramp = jit_jmp (j);
+
+	void *tramp = jit_address (j);
+	jit_pop_link_register (j);
+	jit_movr (j, JIT_R0, JIT_LR);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr (j, JIT_R0);
+
+	jit_patch_here (j, call_tramp);
+	jit_jmpi_with_link (j, tramp);
+
+	void *expected_link = jit_address_to_function_pointer (jit_address (j));
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	void* (*f)(void) = ret;
+
+	ASSERT(f() == expected_link);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/lshi.c b/tests/lshi.c
new file mode 100644
index 0000000..772c0ed
--- /dev/null
+++ b/tests/lshi.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_lshi(j, JIT_R0, JIT_R0, 31);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(-0x7f) == 0x80000000);
+#else
+	ASSERT(f(-0x7f) == 0xffffffc080000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/lshr.c b/tests/lshr.c
new file mode 100644
index 0000000..89b9084
--- /dev/null
+++ b/tests/lshr.c
@@ -0,0 +1,69 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_lshr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7f, 1) == 0xfe);
+	ASSERT(f(0x7fff, 2) == 0x1fffc);
+	ASSERT(f(0x81, 16) == 0x810000);
+	ASSERT(f(0xff, 15) == 0x7f8000);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xffffffff, 8) == 0xffffff00);
+	ASSERT(f(0x7fffffff, 3) == 0xfffffff8);
+	ASSERT(f(-0x7f, 31) == 0x80000000);
+	ASSERT(f(-0x7fff, 30) == 0x40000000);
+	ASSERT(f(-0x7fffffff, 29) == 0x20000000);
+	ASSERT(f(0x80000001, 28) == 0x10000000);
+	ASSERT(f(0x8001, 17) == 0x20000);
+	ASSERT(f(0x80000001, 18) == 0x40000);
+	ASSERT(f(-0xffff, 24) == 0x1000000);
+#else
+	ASSERT(f(0xffffffff, 8) == 0xffffffff00);
+	ASSERT(f(0x7fffffff, 3) == 0x3fffffff8);
+	ASSERT(f(-0x7f, 31) == 0xffffffc080000000);
+	ASSERT(f(-0x7fff, 30) == 0xffffe00040000000);
+	ASSERT(f(-0x7fffffff, 29) == 0xf000000020000000);
+	ASSERT(f(0x80000001, 28) == 0x800000010000000);
+	ASSERT(f(0x8001, 17) == 0x100020000);
+	ASSERT(f(0x80000001, 18) == 0x2000000040000);
+	ASSERT(f(-0xffff, 24) == 0xffffff0001000000);
+	ASSERT(f(0x7f, 33) == 0xfe00000000);
+	ASSERT(f(0x7ffff, 34) == 0x1ffffc00000000);
+	ASSERT(f(0x7fffffff, 35) == 0xfffffff800000000);
+	ASSERT(f(-0x7f, 63) == 0x8000000000000000);
+	ASSERT(f(-0x7fff, 62) == 0x4000000000000000);
+	ASSERT(f(-0x7fffffff, 61) == 0x2000000000000000);
+	ASSERT(f(0x80000001, 60) == 0x1000000000000000);
+	ASSERT(f(0x81, 48) == 0x81000000000000);
+	ASSERT(f(0x8001, 49) == 0x2000000000000);
+	ASSERT(f(0x80000001, 40) == 0x10000000000);
+	ASSERT(f(0xff, 47) == 0x7f800000000000);
+	ASSERT(f(0xffff0001, 56) == 0x100000000000000);
+	ASSERT(f(0xffffffff, 40) == 0xffffff0000000000);
+	ASSERT(f(0x7fffffffff, 33) == 0xfffffffe00000000);
+	ASSERT(f(-0x7fffffffff, 63) == 0x8000000000000000);
+	ASSERT(f(0x8000000001, 48) == 0x1000000000000);
+	ASSERT(f(0xffffffffff, 47) == 0xffff800000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/makefile b/tests/makefile
new file mode 100644
index 0000000..3ab921a
--- /dev/null
+++ b/tests/makefile
@@ -0,0 +1,32 @@
+include ./tests.mk
+
+LLVM			?= 0
+CROSS_COMPILE 		:=
+COMPILER		!= [ "$(LLVM)" != "0" ] \
+				&& echo clang --target="$(CROSS_COMPILE)" \
+				|| echo $(CROSS_COMPILE)gcc
+
+CFLAGS			:= -Wall -Wextra -O0 -g
+INCLUDE_FLAGS		:= -I include
+COMPILE_JIT_TEST 	:= $(COMPILER) $(CFLAGS) $(INCLUDE_FLAGS)
+COMPILE_BCODE_TEST	:= $(COMPILER) $(CFLAGS) $(INCLUDE_FLAGS) -DFORCE_BCODE=1
+
+.PHONY: check
+check: $(BCODE_TESTS) $(JIT_TESTS)
+	echo "Success!"
+
+.PHONY: check-bcode
+check-bcode:
+	@echo "Running bytecode tests..."
+	@set -e; for test in $(BCODE_TESTS); do \
+		echo "Testing: $$test"; \
+		./$$test; \
+	done
+
+.PHONY: check-jit
+check-jit:
+	@echo "Running jit tests..."
+	@set -e; for test in $(JIT_TESTS); do \
+		echo "Testing: $$test"; \
+		./$$test; \
+	done
diff --git a/tests/mov_addr.c b/tests/mov_addr.c
new file mode 100644
index 0000000..01a0e7e
--- /dev/null
+++ b/tests/mov_addr.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static uint64_t thing = 0x123456789abcdef0;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_patch_there(j, jit_mov_addr(j, JIT_R0), &thing);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	void* (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == &thing);
+	ASSERT(*(uint64_t*)f() == thing);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/movi.c b/tests/movi.c
new file mode 100644
index 0000000..1282b6f
--- /dev/null
+++ b/tests/movi.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_movi(j, JIT_R0, 0xa500a500);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == 0xa500a500);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/movi_d.c b/tests/movi_d.c
new file mode 100644
index 0000000..650064b
--- /dev/null
+++ b/tests/movi_d.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_movi_d(j, JIT_F0, 3.14159);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == 3.14159);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/movi_f.c b/tests/movi_f.c
new file mode 100644
index 0000000..82e2d0a
--- /dev/null
+++ b/tests/movi_f.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+	jit_movi_f(j, JIT_F0, 3.14159f);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(void) = jit_end(j, NULL);
+
+	ASSERT(f() == 3.14159f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/mulr.c b/tests/mulr.c
new file mode 100644
index 0000000..3f0a6f8
--- /dev/null
+++ b/tests/mulr.c
@@ -0,0 +1,64 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_mulr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+	ASSERT(f(1, 0x7fffffff) == 0x7fffffff);
+	ASSERT(f(0x80000000, 1) == 0x80000000);
+	ASSERT(f(1, 0x80000000) == 0x80000000);
+	ASSERT(f(0x7fffffff, 2) == 0xfffffffe);
+	ASSERT(f(2, 0x7fffffff) == 0xfffffffe);
+	ASSERT(f(0x7fffffff, 0) == 0);
+	ASSERT(f(0, 0x7fffffff) == 0);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000, 2) == 0);
+	ASSERT(f(2, 0x80000000) == 0);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0x80000000);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0x80000000);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000001);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0x80000001);
+	ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#else
+	ASSERT(f(0x80000000, 2) == 0x100000000);
+	ASSERT(f(2, 0x80000000) == 0x100000000);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0x3fffffff80000000);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0x3fffffff80000000);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x7ffffffe80000001);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0x7ffffffe80000001);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xfffffffe00000001);
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+	ASSERT(f(1, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+	ASSERT(f(1, 0x8000000000000000) == 0x8000000000000000);
+	ASSERT(f(0x7fffffffffffffff, 2) == 0xfffffffffffffffe);
+	ASSERT(f(2, 0x7fffffffffffffff) == 0xfffffffffffffffe);
+	ASSERT(f(0x8000000000000000, 2) == 0);
+	ASSERT(f(2, 0x8000000000000000) == 0);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x8000000000000000);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x8000000000000001);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/mulr_d.c b/tests/mulr_d.c
new file mode 100644
index 0000000..5464170
--- /dev/null
+++ b/tests/mulr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_mulr_d(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	double (*f)(double, double) = ret;
+	ASSERT(f(-0.5, 0.5) == -0.25);
+	ASSERT(f(0.25, 0.75) == 0.1875);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/mulr_f.c b/tests/mulr_f.c
new file mode 100644
index 0000000..5e5f46a
--- /dev/null
+++ b/tests/mulr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_mulr_f(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	float (*f)(float, float) = ret;
+	ASSERT(f(-0.5f, 0.5f) == -0.25f);
+	ASSERT(f(0.25f, 0.75f) == 0.1875f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/negr.c b/tests/negr.c
new file mode 100644
index 0000000..db65f3c
--- /dev/null
+++ b/tests/negr.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_negr(j, JIT_R0, JIT_R0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+	ASSERT(f(0) == 0);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(1) == 0xffffffff);
+	ASSERT(f(0xffffffff) == 1);
+	ASSERT(f(0x80000000) == 0x80000000);
+	ASSERT(f(0x7fffffff) == 0x80000001);
+	ASSERT(f(0x80000001) == 0x7fffffff);
+#else
+	ASSERT(f(1) == 0xffffffffffffffff);
+	ASSERT(f(0xffffffff) == 0xffffffff00000001);
+	ASSERT(f(0x80000000) == 0xffffffff80000000);
+	ASSERT(f(0x7fffffff) == 0xffffffff80000001);
+	ASSERT(f(0x80000001) == 0xffffffff7fffffff);
+	ASSERT(f(0xffffffffffffffff) == 1);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000000);
+	ASSERT(f(0x7fffffffffffffff) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/negr_d.c b/tests/negr_d.c
new file mode 100644
index 0000000..b8d4a00
--- /dev/null
+++ b/tests/negr_d.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_negr_d(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == -0.0);
+	ASSERT(f(0.5) == -0.5);
+	ASSERT(f(1.0 / 0.0) == -1.0 / 0.0);
+	ASSERT(f(-1.25) == 1.25);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/negr_f.c b/tests/negr_f.c
new file mode 100644
index 0000000..08b6364
--- /dev/null
+++ b/tests/negr_f.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_negr_f(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(f(0.0f) == -0.0f);
+	ASSERT(f(0.5f) == -0.5f);
+	ASSERT(f(1.0f / 0.0f) == -1.0f / 0.0f);
+	ASSERT(f(-1.25f) == 1.25f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/ori.c b/tests/ori.c
new file mode 100644
index 0000000..27f7b2c
--- /dev/null
+++ b/tests/ori.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_ori(j, JIT_R0, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff) == 0x7fffffff);
+	ASSERT(f(0x80000000) == 0x80000001);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/orr.c b/tests/orr.c
new file mode 100644
index 0000000..af8e141
--- /dev/null
+++ b/tests/orr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_orr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+	ASSERT(f(1, 0x7fffffff) == 0x7fffffff);
+	ASSERT(f(0x80000000, 1) == 0x80000001);
+	ASSERT(f(1, 0x80000000) == 0x80000001);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0xffffffff);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0xffffffff);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0, 0x7fffffff) == 0x7fffffff);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+	ASSERT(f(1, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0x8000000000000000, 1) == 0x8000000000000001);
+	ASSERT(f(1, 0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0xffffffffffffffff);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/qdivr.c b/tests/qdivr.c
new file mode 100644
index 0000000..c559802
--- /dev/null
+++ b/tests/qdivr.c
@@ -0,0 +1,45 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+	jit_operand_t args[] =
+	{ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	  jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+	jit_load_args(j, 4, args);
+
+	jit_qdivr(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+	jit_str(j, JIT_R0, JIT_V1);
+	jit_str(j, JIT_R1, JIT_V2);
+
+	jit_leave_jit_abi(j, 3, 0, align);
+
+	jit_ret(j);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define QDIV(a, b, c, d)                                                  \
+	do {                                                              \
+		jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); \
+		ASSERT(D == d);                                           \
+	} while (0)
+
+	QDIV(10, 3, 3, 1);
+	QDIV(-33, 9, -3, -6);
+	QDIV(-41, -7, 5, -6);
+	QDIV(65536, 4096, 16, 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/qdivr_u.c b/tests/qdivr_u.c
new file mode 100644
index 0000000..df215ec
--- /dev/null
+++ b/tests/qdivr_u.c
@@ -0,0 +1,43 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+
+	size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+	jit_operand_t args[] =
+	{ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	  jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+	jit_load_args(j, 4, args);
+
+	jit_qdivr_u(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+	jit_str(j, JIT_R0, JIT_V1);
+	jit_str(j, JIT_R1, JIT_V2);
+
+	jit_leave_jit_abi(j, 3, 0, align);
+
+	jit_ret(j);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+#define QDIV(a, b, c, d)                                                  \
+	do {                                                              \
+		jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); \
+		ASSERT(D == d);                                           \
+	} while (0)
+
+	QDIV(-1, -2, 1, 1);
+	QDIV(-2, -5, 1, 3);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/qmulr.c b/tests/qmulr.c
new file mode 100644
index 0000000..b7aa5e8
--- /dev/null
+++ b/tests/qmulr.c
@@ -0,0 +1,59 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+
+	size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+	jit_operand_t args[] =
+	{ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	  jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+	jit_load_args(j, 4, args);
+
+	jit_qmulr(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+	jit_str(j, JIT_R0, JIT_V1);
+	jit_str(j, JIT_R1, JIT_V2);
+
+	jit_leave_jit_abi(j, 3, 0, align);
+
+	jit_ret(j);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define QMUL(a, b, c, d)                                                  \
+	do {                                                              \
+		jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); \
+		ASSERT(D == d);                                           \
+	} while (0)
+
+	QMUL(-2, -1, 2, 0);
+	QMUL(0, -1, 0, 0);
+	QMUL(-1, 0, 0, 0);
+	QMUL(1, -1, -1, -1);
+#if EJIT_WORDSIZE == 32
+	QMUL(0x7ffff, 0x7ffff, 0xfff00001, 0x3f);
+	QMUL(0x80000000, -2, 0, 1);
+	QMUL(0x80000000, 2, 0, -1);
+	QMUL(0x80000001, 3, 0x80000003, -2);
+	QMUL(0x80000001, -3, 0x7ffffffd, 1);
+#else
+	QMUL(0x7ffffffff, 0x7ffffffff, 0xfffffff000000001, 0x3f);
+	QMUL(0x8000000000000000, -2, 0, 1);
+	QMUL(0x8000000000000000, 2, 0, -1);
+	QMUL(0x8000000000000001, 3, 0x8000000000000003, -2);
+	QMUL(0x8000000000000001, -3, 0x7ffffffffffffffd, 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/qmulr_u.c b/tests/qmulr_u.c
new file mode 100644
index 0000000..3840c92
--- /dev/null
+++ b/tests/qmulr_u.c
@@ -0,0 +1,47 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+
+	size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+	jit_operand_t args[] =
+	{ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	  jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	  jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+	jit_load_args(j, 4, args);
+
+	jit_qmulr_u(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+	jit_str(j, JIT_R0, JIT_V1);
+	jit_str(j, JIT_R1, JIT_V2);
+
+	jit_leave_jit_abi(j, 3, 0, align);
+
+	jit_ret(j);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define UQMUL(a, b, c, d)                                                 \
+	do {                                                              \
+		jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); \
+		ASSERT(D == d);                                           \
+	} while (0)
+
+#if EJIT_WORDSIZE == 32
+	UQMUL(0xffffff, 0xffffff, 0xfe000001, 0xffff);
+#else
+	UQMUL(0xffffffffff, 0xffffffffff, 0xfffffe0000000001, 0xffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/remr.c b/tests/remr.c
new file mode 100644
index 0000000..cd5bf4f
--- /dev/null
+++ b/tests/remr.c
@@ -0,0 +1,60 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_remr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0);
+	ASSERT(f(1, 0x7fffffff) == 1);
+	ASSERT(f(0x80000000, 1) == 0);
+	ASSERT(f(1, 0x80000000) == 1);
+	ASSERT(f(0x7fffffff, 2) == 1);
+	ASSERT(f(2, 0x7fffffff) == 2);
+	ASSERT(f(0x80000000, 2) == 0);
+	ASSERT(f(2, 0x80000000) == 2);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0x7fffffff);
+	ASSERT(f(0, 0x7fffffff) == 0);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0xffffffff);
+#else
+	ASSERT(f(0x80000000, 0x7fffffff) == 1);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 1);
+	ASSERT(f(0x7fffffffffffffff, 1) == 0);
+	ASSERT(f(1, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0x8000000000000000, 1) == 0);
+	ASSERT(f(1, 0x8000000000000000) == 1);
+	ASSERT(f(0x7fffffffffffffff, 2) == 1);
+	ASSERT(f(2, 0x7fffffffffffffff) == 2);
+	ASSERT(f(0x8000000000000000, 2) == 0);
+	ASSERT(f(2, 0x8000000000000000) == 2);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x7fffffffffffffff);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/remr_u.c b/tests/remr_u.c
new file mode 100644
index 0000000..ba015c1
--- /dev/null
+++ b/tests/remr_u.c
@@ -0,0 +1,56 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_remr_u(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0);
+	ASSERT(f(1, 0x7fffffff) == 1);
+	ASSERT(f(0x80000000, 1) == 0);
+	ASSERT(f(1, 0x80000000) == 1);
+	ASSERT(f(0x7fffffff, 2) == 1);
+	ASSERT(f(2, 0x7fffffff) == 2);
+	ASSERT(f(0x80000000, 2) == 0);
+	ASSERT(f(2, 0x80000000) == 2);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0x7fffffff);
+	ASSERT(f(0x80000000, 0x7fffffff) == 1);
+	ASSERT(f(0, 0x7fffffff) == 0);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 1);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+
+#if EJIT_WORDSIZE != 32
+	ASSERT(f(0x7fffffffffffffff, 1) == 0);
+	ASSERT(f(1, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0x8000000000000000, 1) == 0);
+	ASSERT(f(1, 0x8000000000000000) == 1);
+	ASSERT(f(0x7fffffffffffffff, 2) == 1);
+	ASSERT(f(2, 0x7fffffffffffffff) == 2);
+	ASSERT(f(0x8000000000000000, 2) == 0);
+	ASSERT(f(2, 0x8000000000000000) == 2);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x7fffffffffffffff);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x7fffffffffffffff);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 1);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/rshi.c b/tests/rshi.c
new file mode 100644
index 0000000..ab5438a
--- /dev/null
+++ b/tests/rshi.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_rshi(j, JIT_R0, JIT_R0, 31);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000) == -1);
+#else
+	ASSERT(f(0x80000000) == 1);
+	ASSERT(f(0x8000000000000000) == 0xffffffff00000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/rshi_u.c b/tests/rshi_u.c
new file mode 100644
index 0000000..aa02206
--- /dev/null
+++ b/tests/rshi_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_rshi_u(j, JIT_R0, JIT_R0, 31);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0x80000000) == 1);
+#else
+	ASSERT(f(0x80000000) == 1);
+	ASSERT(f(0x8000000000000000) == 0x100000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/rshr.c b/tests/rshr.c
new file mode 100644
index 0000000..d14f64f
--- /dev/null
+++ b/tests/rshr.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_rshr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0xfe, 1) == 0x7f);
+	ASSERT(f(0x1fffc, 2) == 0x7fff);
+	ASSERT(f(0x40000000, 30) == 1);
+	ASSERT(f(0x20000000, 29) == 1);
+	ASSERT(f(0x10000000, 28) == 1);
+	ASSERT(f(0x810000, 16) == 0x81);
+	ASSERT(f(0x20000, 17) == 1);
+	ASSERT(f(0x40000, 18) == 1);
+	ASSERT(f(0x7f8000, 15) == 0xff);
+	ASSERT(f(0x1000000, 24) == 1);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xfffffff8, 3) == 0xffffffff);
+	ASSERT(f(0x80000000, 31) == 0xffffffff);
+	ASSERT(f(0xffffff00, 8) == 0xffffffff);
+#else
+	ASSERT(f(0x3fffffff8, 3) == 0x7fffffff);
+	ASSERT(f(0xffffffc080000000, 31) == 0xffffffffffffff81);
+	ASSERT(f(0xffffff00, 8) == 0xffffff);
+	ASSERT(f(0xfe00000000, 33) == 0x7f);
+	ASSERT(f(0x1ffffc00000000, 34) == 0x7ffff);
+	ASSERT(f(0xfffffff800000000, 29) == 0xffffffffffffffc0);
+	ASSERT(f(0x8000000000000000, 63) == 0xffffffffffffffff);
+	ASSERT(f(0x4000000000000000, 62) == 1);
+	ASSERT(f(0x2000000000000000, 61) == 1);
+	ASSERT(f(0x1000000000000000, 60) == 1);
+	ASSERT(f(0x81000000000000, 48) == 0x81);
+	ASSERT(f(0x2000000000000, 49) == 1);
+	ASSERT(f(0x10000000000, 40) == 1);
+	ASSERT(f(0x7f800000000000, 47) == 0xff);
+	ASSERT(f(0x100000000000000, 56) == 1);
+	ASSERT(f(0xffffff0000000000, 40) == 0xffffffffffffffff);
+	ASSERT(f(0xfffffffe00000000, 33) == 0xffffffffffffffff);
+	ASSERT(f(0x8000000000000001, 63) == 0xffffffffffffffff);
+	ASSERT(f(0x1000000000000, 48) == 1);
+	ASSERT(f(0xffff800000000000, 47) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/rshr_u.c b/tests/rshr_u.c
new file mode 100644
index 0000000..082b9ed
--- /dev/null
+++ b/tests/rshr_u.c
@@ -0,0 +1,62 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_rshr_u(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0xfe, 1) == 0x7f);
+	ASSERT(f(0x1fffc, 2) == 0x7fff);
+	ASSERT(f(0x80000000, 31) == 1);
+	ASSERT(f(0x40000000, 30) == 1);
+	ASSERT(f(0x20000000, 29) == 1);
+	ASSERT(f(0x10000000, 28) == 1);
+	ASSERT(f(0x810000, 16) == 0x81);
+	ASSERT(f(0x20000, 17) == 1);
+	ASSERT(f(0x40000, 18) == 1);
+	ASSERT(f(0x7f8000, 15) == 0xff);
+	ASSERT(f(0x1000000, 24) == 1);
+	ASSERT(f(0xffffff00, 8) == 0xffffff);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if EJIT_WORDSIZE == 32
+	ASSERT(f(0xfffffff8, 3) == 0x1fffffff);
+#else
+	ASSERT(f(0x3fffffff8, 3) == 0x7fffffff);
+	ASSERT(f(0xffffffc080000000, 31) == 0x1ffffff81);
+	ASSERT(f(0xfe00000000, 33) == 0x7f);
+	ASSERT(f(0x1ffffc00000000, 34) == 0x7ffff);
+	ASSERT(f(0xfffffff800000000, 29) == 0x7ffffffc0);
+	ASSERT(f(0x8000000000000000, 63) == 1);
+	ASSERT(f(0x4000000000000000, 62) == 1);
+	ASSERT(f(0x2000000000000000, 61) == 1);
+	ASSERT(f(0x1000000000000000, 60) == 1);
+	ASSERT(f(0x81000000000000, 48) == 0x81);
+	ASSERT(f(0x2000000000000, 49) == 1);
+	ASSERT(f(0x10000000000, 40) == 1);
+	ASSERT(f(0x7f800000000000, 47) == 0xff);
+	ASSERT(f(0x100000000000000, 56) == 1);
+	ASSERT(f(0xffffff0000000000, 40) == 0xffffff);
+	ASSERT(f(0xfffffffe00000000, 33) == 0x7fffffff);
+	ASSERT(f(0x8000000000000001, 63) == 1);
+	ASSERT(f(0x1000000000000, 48) == 1);
+	ASSERT(f(0xffff800000000000, 47) == 0x1ffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sqrtr_d.c b/tests/sqrtr_d.c
new file mode 100644
index 0000000..f07b94f
--- /dev/null
+++ b/tests/sqrtr_d.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_sqrtr_d(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	double (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0.0);
+	ASSERT(f(4.0) == 2.0);
+	ASSERT(f(-4.0) != f(-4.0)); // nan
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sqrtr_f.c b/tests/sqrtr_f.c
new file mode 100644
index 0000000..7735f68
--- /dev/null
+++ b/tests/sqrtr_f.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_sqrtr_f(j, JIT_F0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	float (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0.0);
+	ASSERT(f(4.0) == 2.0);
+	ASSERT(f(-4.0) != f(-4.0)); // nan
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_c.c b/tests/sti_c.c
new file mode 100644
index 0000000..e323b37
--- /dev/null
+++ b/tests/sti_c.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+	jit_sti_c(j, &data[1], JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(int8_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34);
+	f(-1);
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0xff);
+	ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_d.c b/tests/sti_d.c
new file mode 100644
index 0000000..9fce200
--- /dev/null
+++ b/tests/sti_d.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_sti_d(j, &data[1], JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 0.0);
+	ASSERT(data[2] == 0.5);
+	f(42.5);
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 42.5);
+	ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_f.c b/tests/sti_f.c
new file mode 100644
index 0000000..67a0c38
--- /dev/null
+++ b/tests/sti_f.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_sti_f(j, &data[1], JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 0.0f);
+	ASSERT(data[2] == 0.5f);
+	f(42.5f);
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 42.5f);
+	ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_i.c b/tests/sti_i.c
new file mode 100644
index 0000000..1f014fd
--- /dev/null
+++ b/tests/sti_i.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_sti_i(j, &data[1], JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(-1);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0xffffffff);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_l.c b/tests/sti_l.c
new file mode 100644
index 0000000..36cca18
--- /dev/null
+++ b/tests/sti_l.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+	jit_sti_l(j, &data[1], JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(int64_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x3434343434343434);
+	f(-1);
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0xffffffffffffffff);
+	ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/sti_s.c b/tests/sti_s.c
new file mode 100644
index 0000000..00941ea
--- /dev/null
+++ b/tests/sti_s.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+	jit_sti_s(j, &data[1], JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(int16_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0);
+	ASSERT(data[2] == 0x3434);
+	f(-1);
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0xffff);
+	ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_atomic.c b/tests/str_atomic.c
new file mode 100644
index 0000000..5086078
--- /dev/null
+++ b/tests/str_atomic.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_str_atomic(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(&data[1], 0x0f0f0f0f);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x0f0f0f0f);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_c.c b/tests/str_c.c
new file mode 100644
index 0000000..492cc73
--- /dev/null
+++ b/tests/str_c.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+	jit_str_c(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int8_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34);
+	f(&data[1], -1);
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0xff);
+	ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_d.c b/tests/str_d.c
new file mode 100644
index 0000000..41db4fd
--- /dev/null
+++ b/tests/str_d.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_str_d(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, double) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 0.0);
+	ASSERT(data[2] == 0.5);
+	f(&data[1], 42.5);
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 42.5);
+	ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_f.c b/tests/str_f.c
new file mode 100644
index 0000000..7b394ae
--- /dev/null
+++ b/tests/str_f.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_str_f(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, float) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 0.0f);
+	ASSERT(data[2] == 0.5f);
+	f(&data[1], 42.5f);
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 42.5f);
+	ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_i.c b/tests/str_i.c
new file mode 100644
index 0000000..39e88b9
--- /dev/null
+++ b/tests/str_i.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_str_i(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(&data[1], -1);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0xffffffff);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_l.c b/tests/str_l.c
new file mode 100644
index 0000000..c3338ff
--- /dev/null
+++ b/tests/str_l.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+	jit_str_l(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int64_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x3434343434343434);
+	f(&data[1], -1);
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0xffffffffffffffff);
+	ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/str_s.c b/tests/str_s.c
new file mode 100644
index 0000000..d2e7e45
--- /dev/null
+++ b/tests/str_s.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+	jit_str_s(j, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int16_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0);
+	ASSERT(data[2] == 0x3434);
+	f(&data[1], -1);
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0xffff);
+	ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_c.c b/tests/stxi_c.c
new file mode 100644
index 0000000..828a9d4
--- /dev/null
+++ b/tests/stxi_c.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+	jit_stxi_c(j, (uintptr_t)data, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, int8_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34);
+	f(1, -1);
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0xff);
+	ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_d.c b/tests/stxi_d.c
new file mode 100644
index 0000000..85b3a4a
--- /dev/null
+++ b/tests/stxi_d.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_stxi_d(j, (uintptr_t)data, JIT_R2, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, double) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 0.0);
+	ASSERT(data[2] == 0.5);
+	f(8, 42.5);
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 42.5);
+	ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_f.c b/tests/stxi_f.c
new file mode 100644
index 0000000..7325b3c
--- /dev/null
+++ b/tests/stxi_f.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_stxi_f(j, (uintptr_t)data, JIT_R2, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, float) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 0.0f);
+	ASSERT(data[2] == 0.5f);
+	f(4, 42.5f);
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 42.5f);
+	ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_i.c b/tests/stxi_i.c
new file mode 100644
index 0000000..37bfd8f
--- /dev/null
+++ b/tests/stxi_i.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_stxi_i(j, (uintptr_t)data, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(4, -1);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0xffffffff);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_l.c b/tests/stxi_l.c
new file mode 100644
index 0000000..a758fa9
--- /dev/null
+++ b/tests/stxi_l.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+	jit_stxi_l(j, (uintptr_t)data, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, int64_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x3434343434343434);
+	f(8, -1);
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0xffffffffffffffff);
+	ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxi_s.c b/tests/stxi_s.c
new file mode 100644
index 0000000..d3aebc3
--- /dev/null
+++ b/tests/stxi_s.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+	jit_stxi_s(j, (uintptr_t)data, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(jit_word_t, int16_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0);
+	ASSERT(data[2] == 0x3434);
+	f(2, -1);
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0xffff);
+	ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_c.c b/tests/stxr_c.c
new file mode 100644
index 0000000..329083b
--- /dev/null
+++ b/tests/stxr_c.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+	jit_stxr_c(j, JIT_R0, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, int8_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34);
+	f(data, 1, -1);
+	ASSERT(data[0] == 0x12);
+	ASSERT(data[1] == 0xff);
+	ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_d.c b/tests/stxr_d.c
new file mode 100644
index 0000000..ee6e86a
--- /dev/null
+++ b/tests/stxr_d.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_stxr_d(j, JIT_R0, JIT_R2, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, double) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 0.0);
+	ASSERT(data[2] == 0.5);
+	f(data, 8, 42.5);
+	ASSERT(data[0] == -1.0);
+	ASSERT(data[1] == 42.5);
+	ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_f.c b/tests/stxr_f.c
new file mode 100644
index 0000000..d5bf9bf
--- /dev/null
+++ b/tests/stxr_f.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_stxr_f(j, JIT_R0, JIT_R2, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, float) = jit_end(j, NULL);
+
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 0.0f);
+	ASSERT(data[2] == 0.5f);
+	f(data, 4, 42.5f);
+	ASSERT(data[0] == -1.0f);
+	ASSERT(data[1] == 42.5f);
+	ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_i.c b/tests/stxr_i.c
new file mode 100644
index 0000000..5ee69e7
--- /dev/null
+++ b/tests/stxr_i.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_stxr_i(j, JIT_R0, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(data, 4, -1);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0xffffffff);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_l.c b/tests/stxr_l.c
new file mode 100644
index 0000000..6562dda
--- /dev/null
+++ b/tests/stxr_l.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+	jit_stxr_l(j, JIT_R0, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, int64_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x3434343434343434);
+	f(data, 8, -1);
+	ASSERT(data[0] == 0x1212121212121212);
+	ASSERT(data[1] == 0xffffffffffffffff);
+	ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/stxr_s.c b/tests/stxr_s.c
new file mode 100644
index 0000000..8505892
--- /dev/null
+++ b/tests/stxr_s.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+	jit_stxr_s(j, JIT_R0, JIT_R2, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, jit_word_t, int16_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0);
+	ASSERT(data[2] == 0x3434);
+	f(data, 2, -1);
+	ASSERT(data[0] == 0x1212);
+	ASSERT(data[1] == 0xffff);
+	ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/subr.c b/tests/subr.c
new file mode 100644
index 0000000..e2c22bc
--- /dev/null
+++ b/tests/subr.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_subr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	int (*f)(int, int) = ret;
+	ASSERT(f(42, 69) == -27);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/subr_d.c b/tests/subr_d.c
new file mode 100644
index 0000000..65b5ecd
--- /dev/null
+++ b/tests/subr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+	jit_subr_d(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_d(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	double (*f)(double, double) = ret;
+	ASSERT(f(42., 69.) == -27.);
+	ASSERT(f(42., 69.5) == -27.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/subr_f.c b/tests/subr_f.c
new file mode 100644
index 0000000..3fdf071
--- /dev/null
+++ b/tests/subr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+	                jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+	jit_subr_f(j, JIT_F0, JIT_F0, JIT_F1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr_f(j, JIT_F0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	float (*f)(float, float) = ret;
+	ASSERT(f(42.f, 69.f) == -27.f);
+	ASSERT(f(42.0f, 69.5f) == -27.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/subx.c b/tests/subx.c
new file mode 100644
index 0000000..b2bb3c2
--- /dev/null
+++ b/tests/subx.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_movi(j, JIT_R2, 0);
+	jit_subcr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_subxi(j, JIT_R2, JIT_R2, 0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R2);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0, 0) == 0);
+
+#if EJIT_WORDSIZE == 32
+	/* carry */
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0xffffffff);
+	/* overflow */
+	ASSERT(f(0x80000000, 1) == 0);
+	/* carry */
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	/* overflow */
+	ASSERT(f(0x80000000, 0x7fffffff) == 0);
+	/* carry+overflow */
+	ASSERT(f(1, 0x80000000) == 0xffffffff);
+#else
+	/* carry */
+	ASSERT(f(0x7fffffff, 0xffffffff) == -1);
+	/* nothing */
+	ASSERT(f(0x80000000, 1) == 0);
+	/* carry */
+	ASSERT(f(0x7fffffff, 0x80000000) == -1);
+	/* nothing */
+	ASSERT(f(0x80000000, 0x7fffffff) == 0);
+	/* carry */
+	ASSERT(f(1, 0x80000000) == -1);
+	/* carry */
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == -1);
+	/* overflow */
+	ASSERT(f(0x8000000000000000, 1) == 0);
+	/* carry */
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+	/* overflow */
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0);
+	/* carry+overflow */
+	ASSERT(f(1, 0x8000000000000000) == -1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/swap_atomic.c b/tests/swap_atomic.c
new file mode 100644
index 0000000..5803164
--- /dev/null
+++ b/tests/swap_atomic.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+	jit_swap_atomic(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_ret(j);
+
+	void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x00);
+	ASSERT(data[2] == 0x34343434);
+	f(&data[1], 0x0f0f0f0f);
+	ASSERT(data[0] == 0x12121212);
+	ASSERT(data[1] == 0x0f0f0f0f);
+	ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/test-bcode-absr_f b/tests/test-bcode-absr_f
new file mode 100755
index 0000000..8e902b5
Binary files /dev/null and b/tests/test-bcode-absr_f differ
diff --git a/tests/truncr_d_i.c b/tests/truncr_d_i.c
new file mode 100644
index 0000000..09e163e
--- /dev/null
+++ b/tests/truncr_d_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_truncr_d_i(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	int (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0);
+	ASSERT(f(-0.0) == 0);
+	ASSERT(f(0.5) == 0);
+	ASSERT(f(-0.5) == 0);
+	ASSERT(f(1.5) == 1);
+	ASSERT(f(-1.5) == -1);
+	ASSERT(f(2.5) == 2);
+	ASSERT(f(-2.5) == -2);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/truncr_d_l.c b/tests/truncr_d_l.c
new file mode 100644
index 0000000..ee9b477
--- /dev/null
+++ b/tests/truncr_d_l.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+	jit_truncr_d_l(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	int64_t (*f)(double) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0);
+	ASSERT(f(-0.0) == 0);
+	ASSERT(f(0.5) == 0);
+	ASSERT(f(-0.5) == 0);
+	ASSERT(f(1.5) == 1);
+	ASSERT(f(-1.5) == -1);
+	ASSERT(f(2.5) == 2);
+	ASSERT(f(-2.5) == -2);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/truncr_f_i.c b/tests/truncr_f_i.c
new file mode 100644
index 0000000..0314753
--- /dev/null
+++ b/tests/truncr_f_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_truncr_f_i(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	int (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0);
+	ASSERT(f(-0.0) == 0);
+	ASSERT(f(0.5) == 0);
+	ASSERT(f(-0.5) == 0);
+	ASSERT(f(1.5) == 1);
+	ASSERT(f(-1.5) == -1);
+	ASSERT(f(2.5) == 2);
+	ASSERT(f(-2.5) == -2);
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/truncr_f_l.c b/tests/truncr_f_l.c
new file mode 100644
index 0000000..ad95744
--- /dev/null
+++ b/tests/truncr_f_l.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if EJIT_WORDSIZE > 32
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+	jit_truncr_f_l(j, JIT_R0, JIT_F0);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	int64_t (*f)(float) = jit_end(j, NULL);
+
+	ASSERT(f(0.0) == 0);
+	ASSERT(f(-0.0) == 0);
+	ASSERT(f(0.5) == 0);
+	ASSERT(f(-0.5) == 0);
+	ASSERT(f(1.5) == 1);
+	ASSERT(f(-1.5) == -1);
+	ASSERT(f(2.5) == 2);
+	ASSERT(f(-2.5) == -2);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/xori.c b/tests/xori.c
new file mode 100644
index 0000000..16197ce
--- /dev/null
+++ b/tests/xori.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+	jit_xori(j, JIT_R0, JIT_R0, 1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff) == 0x7ffffffe);
+	ASSERT(f(0x80000000) == 0x80000001);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+	ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
diff --git a/tests/xorr.c b/tests/xorr.c
new file mode 100644
index 0000000..123bfb7
--- /dev/null
+++ b/tests/xorr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+	jit_begin(j, arena_base, arena_size);
+	size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+	jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+	                jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+	jit_xorr(j, JIT_R0, JIT_R0, JIT_R1);
+	jit_leave_jit_abi(j, 0, 0, align);
+	jit_retr(j, JIT_R0);
+
+	size_t size = 0;
+	void* ret = jit_end(j, &size);
+
+	jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+	ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+	ASSERT(f(1, 0x7fffffff) == 0x7ffffffe);
+	ASSERT(f(0x80000000, 1) == 0x80000001);
+	ASSERT(f(1, 0x80000000) == 0x80000001);
+	ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+	ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+	ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000000);
+	ASSERT(f(0xffffffff, 0x7fffffff) == 0x80000000);
+	ASSERT(f(0xffffffff, 0xffffffff) == 0);
+	ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+	ASSERT(f(0, 0x7fffffff) == 0x7fffffff);
+#if EJIT_WORDSIZE == 64
+	ASSERT(f(0x7fffffffffffffff, 1) == 0x7ffffffffffffffe);
+	ASSERT(f(1, 0x7fffffffffffffff) == 0x7ffffffffffffffe);
+	ASSERT(f(0x8000000000000000, 1) == 0x8000000000000001);
+	ASSERT(f(1, 0x8000000000000000) == 0x8000000000000001);
+	ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0xffffffffffffffff);
+	ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+	ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x8000000000000000);
+	ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+	return main_helper(argc, argv, run_test);
+}
-- 
cgit v1.2.3