DIGITALIS

ARM64-to-x86_64 binary translation for Android

Architecture

Berberis is AOSP's binary translation framework, part of Android's NativeBridge system. It provides the core infrastructure for translating guest architecture instructions to host machine code at runtime — including a JIT compiler, an interpreter, an instruction decoder, syscall emulation, and proxy libraries. Berberis currently supports RISC-V-to-x86_64 translation in upstream AOSP.

Berberis (upstream AOSP)
RISC-V APK
NativeBridge
JIT / Interpreter
x86_64 Host

Digitalis extends Berberis with an ARM64 backend, enabling ARM64-only Android apps to run on x86_64 emulators. It reuses Berberis's translation infrastructure while adding ARM64 instruction decoding, JIT code generation, and interpreter support. Guest code runs through three tiers: an interpreter, a single-pass lite translator (first gear) for cold regions, and an optimizing heavy translator (second gear) that engages on hot regions.

Digitalis (this project)
ARM64 APK
NativeBridge
Interpreter / Lite / Heavy JIT
x86_64 Host

Interpreter

Per-instruction fallback for syscalls, complex SIMD operations, and edge cases the JIT can't handle.

fallback path

Lite Translator (first gear)

Single-pass JIT that translates cold ARM64 regions to native x86_64 machine code. Handles ~98% of instructions. Translated regions are cached for reuse.

~98% coverage

Heavy Optimizer (second gear)

An optimizing JIT that engages on hot regions via a hotness counter. It does global register allocation and loop optimization across a whole region — neutral-or-faster than the lite tier, with up to ~2x speedups on register-pressure-heavy loops.

hot-region tier

Read the full how-it-works.md on GitHub → — complete walkthrough including register mapping, translation lifecycle, NZCV flag emulation, syscall path, proxy library forwarding, and the ARM64 → x86_64 instruction-mapping reference.

Features

Two-Gear JIT Compiler

The Lite Translator converts cold ARM64 regions to native x86_64 in a single pass; an optimizing Heavy Translator re-compiles hot regions with global register allocation and loop optimization. Translated regions are cached for reuse. The heavy tier is neutral-or-faster than the lite tier in general, with up to ~2x speedups on register-pressure-heavy loops.

Interpreter Fallback

Per-instruction execution for syscalls, complex SIMD, and anything the JIT can't handle. Ensures complete ARM64 coverage.

Proxy Libraries

21 host libraries — Vulkan, libc/libm, EGL/GLES, AAudio, camera, NDK binder, NNAPI, JNI helpers — forwarded to native x86_64 implementations, with GPU-accelerated Vulkan via GFXStream VkDecoder. OpenGL ES is driven by ANGLE, which implements it on top of Vulkan in-guest — giving full OpenGL ES 3.2 and hardware MSAA on the host GPU. Symbols the auto-generated marshallers can't handle are covered in-surface with custom trampolines, including JNIEnv translation and host→guest callbacks.

131 Sample Apps

Ported NDK samples, Digitalis proxy-lib smoke tests, ARM-extension probes, full-engine samples, and third-party native-library integration samples prove end-to-end translation: Vulkan, OpenGL ES 1.x/2/3 (incl. an ES 3.2 EGL repro and a multisample/MSAA 1x/2x/4x/8x sample), OpenSLES + AAudio + Oboe, camera, MIDI, sensors, NDK binder, NNAPI, the Qt 6, React Native + Hermes, and Lynx + PrimJS UI engines; media, codecs and RTC (ijkplayer, libVLC, FFmpegKit, WebRTC); imaging, maps and vector graphics (Fresco, GPUImage, libpag, gif-drawable, PDFium, RenderScript Toolkit, libavif, Rive, MapLibre); vision/ML/speech (OpenCV, TensorFlow Lite, LiteRT-LM, PyTorch Mobile, ncnn, ZXing, Tesseract OCR, ONNX Runtime, MediaPipe, Vosk); crypto (SQLCipher, Conscrypt, libsignal, MMKV, libsodium, Argon2, Themis); databases/storage (Realm, ObjectBox, Couchbase Lite, Tencent WCDB, zstd); JS engines and JNI bridges (QuickJS, Duktape, J2V8, Javet, JavaCPP, JNA, fbjni); networking (Cronet, WireGuard, libtorrent4j); AndroidX-native (sqlite-bundled, graphics-path, camera-core, tracing-perfetto, AppSearch/Icing, Ink); plus NEON, FP16, BFloat16, FCMA, dot-product, I8MM integer matrix-multiply, JSCVT, PAC, LSE/LRCPC atomics, LDXP/STXP, CRC32/CRC32C, and SHA/AES crypto. The newest additions bring a numeric/scientific tier (OpenBLAS, FFTW, GSL), 2D physics (Box2D), image processing and OCR pre-processing (libyuv, Leptonica), fast compression (Snappy), Bitcoin-curve ECDSA (secp256k1), and Google’s Filament physically-based renderer with glTF loading (gltfio) — including hello-filament-render, which draws a lit glTF cube on screen through Filament’s Vulkan backend, unblocked by a new guest libgui.so stub so Filament’s on-screen present path no longer faults. A further round broadens the catalog into new subsystems: a native Lua 5.4 VM (luajava) and the MuPDF PDF render engine (an alternate to PDFium); the Sentry NDK crash backend, whose signal-handler stack-unwinder install is exercised under translation; Bullet 3D rigid-body physics (libGDX) alongside the existing Box2D; the WebP and Opus codecs; libarchive multi-format archive reading and the LevelDB LSM-tree key-value store; the libxml2 XML parser; and PCRE2 — whose pcre2_jit_compile (sljit) emits ARM64 at runtime and signals self-modified code via IC IVAU, directly exercising the translator’s self-modifying-code cache-invalidation path. The machine-learning samples now run real fixed-weight inference end-to-end under translation — a TensorFlow Lite Conv2D→ReLU→Dense graph, an ONNX Runtime Gemm→ReLU→Gemm graph, and a PyTorch Mobile Module.forward — each checked bit-exact against a golden (the integer-weight design makes the float32 result identical on host and device, so a miscompile in the conv/GEMM/ReLU NEON kernels trips the check). The same golden-assertion hardening now covers the NNAPI graph-execution path, fbjni hybrid dispatch, the AAudio/Oboe/OpenSLES audio DSP path, and binder-NDK typed-parcel round-trips.

Getting Started

# Clone
$ mkdir digitalis && cd digitalis
$ repo init -b android-latest-release -u git@github.com:DigitalisX64/manifest.git
$ repo sync -c -d --no-tags --force-sync
 
# Build
$ source build/envsetup.sh
$ lunch sdk_phone64_x86_64_digitalis-trunk_staging-userdebug
$ m
 
# Run emulator
$ emulator -memory 4096 -writable-system -qemu -cpu host &
 
# Install and test
$ cd sample/hellodigitalis && ./gradlew assembleDebug
$ adb install hello-vulkan/build/outputs/apk/debug/hello-vulkan-debug.apk
$ adb shell am start -n com.example.hellodigitalis/android.app.NativeActivity

Sample Apps

ARM64-only APKs running on an x86_64 emulator via NativeBridge translation.

# Build all sample modules (ARM64-only APKs)
$ cd sample/hellodigitalis && ./gradlew assembleDebug
 
# Install and run
$ adb install hello-vulkan/build/outputs/apk/debug/hello-vulkan-debug.apk
$ adb shell am start -n com.example.hellodigitalis/android.app.NativeActivity
✓ Vulkan triangle rendered via NativeBridge translation
hello-vulkan
hello-gl2
gles3jni
teapots-classic
teapots-more
teapots-textured
native-activity
native-audio
native-codec
native-midi
hello-jni
hello-jniCallback
endless-tunnel
bitmap-plasma
camera-basic
camera-texture-view
sensor-graph
sanitizers
vectorization
orderfile
exceptions
unit-test
hello-gles1
hello-aaudio
hello-binder-ndk
hello-nnapi
hello-neon
hello-fp16
hello-bf16
hello-fp-vector
hello-complex
hello-dotprod
hello-widemul
hello-jscvt
hello-pac-ret
hello-lse
hello-lrcpc
hello-barriers
hello-sha-crypto
hello-ld-interleave
hello-libc-libm
hello-bti
hello-superpack-regress
hello-gles3
hello-msaa
hello-reactnative
hello-lynx
hello-mmkv
hello-qt
hello-ijkplayer
hello-opencv
hello-sqlcipher
hello-conscrypt
hello-graphics-path
hello-gif
hello-zxing
hello-quickjs
hello-sqlite-bundled
hello-tflite
hello-litert-llm
hello-libpag
hello-zstd
hello-libvlc
hello-ink
hello-appsearch
hello-libsignal
hello-fresco
hello-objectbox
hello-pdfium
hello-tracing-perfetto
hello-renderscript-toolkit
hello-pytorch
hello-gpuimage
hello-camera-core
hello-tesseract
hello-oboe
hello-ffmpeg-kit
hello-ncnn
hello-realm
hello-aes
hello-cronet
hello-webview-functor
hello-ldxp
hello-cntvct
hello-sigaction
hello-maplibre
hello-couchbase
hello-wcdb
hello-vosk
hello-onnxruntime
hello-mediapipe
hello-rive
hello-avif
hello-webrtc
hello-wireguard
hello-libtorrent4j
hello-duktape
hello-j2v8
hello-javet
hello-javacpp
hello-jna
hello-fbjni
hello-libsodium
hello-argon2
hello-themis
hello-snappy
hello-libyuv
hello-secp256k1
hello-openblas
hello-fftw
hello-gsl
hello-leptonica
hello-box2d
hello-filament
hello-gltfio
hello-filament-render
hello-lua
hello-mupdf
hello-sentry-ndk
hello-bullet
hello-libwebp
hello-libarchive
hello-opus
hello-leveldb
hello-pcre2
hello-libxml2

Beyond the in-tree samples, real unmodified third-party ARM64 APKs are tracked on the Verified Apps page.