JavaScriptCore Offlineasm Register Reference

NOTE: This document was largely AI-generated based on offlineasm/*.rb sources and llint/*.asm files. Exercise healthy skepticism.

This document describes the correspondence between offlineasm logical registers, interpreter-specific aliases (LowLevelInterpreter and InPlaceInterpreter), and physical platform registers.

Overview

JavaScriptCore's offline assembler (offlineasm) uses portable logical register names that are mapped to platform-specific physical registers during code generation. The LowLevelInterpreter (LLInt) and InPlaceInterpreter (IPInt) define their own register aliases for clarity and portability.

General Purpose Registers (GPRs)

Temporary Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
t0a0, wa0, r0wa0x0/w0raxArgument 0 / Return value / Temp
t1a1, wa1, r1wa1x1/w1rsiArgument 1 / Temp
t2a2, wa2wa2x2/w2rdxArgument 2 / Temp
t3a3, wa3wa3x3/w3rcxArgument 3 / Temp
t4a4, wa4wa4x4/w4r8Argument 4 / Temp
t5a5, wa5wa5, PL (X86_64)x5/w5r10Argument 5 / Temp / Pointer to Locals
t6a6, wa6wa6, PL (ARM64)x6/w6rdiArgument 6 / Temp / Pointer to Locals
t7a7, wa7wa7, PL (ARMv7)x7/w7r9Argument 7 / Temp / Pointer to Locals
t8--x8/w8-Temp
t9ws0ws0, sc0x9/w9-Wasm scratch 0 / Safe call 0
t10ws1ws1, sc1x10/w10-Wasm scratch 1 / Safe call 1
t11ws2ws2x11/w11-Wasm scratch 2
t12ws3ws3x12/w12-Wasm scratch 3

Special Purpose Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
cfr--x29rbpCall Frame Register
sp--sprspStack Pointer
lr--x30 (lr)-Link Register (ARM64 only)
pc----Program Counter (logical)

Callee-Save Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
csr0-WI (wasmInstance)x19rbxCallee-save / wasmInstance (IPInt)
csr1-MC (X86_64)x20r12Callee-save / Metadata Counter (IPInt X86_64)
csr2-PC (X86_64)x21r13Callee-save / Program Counter (IPInt X86_64)
csr3-MB (memoryBase)x22r14Callee-save / Memory Base (IPInt)
csr4-BC (boundsCheckingSize)x23r15Callee-save / Bounds Check (IPInt)
csr5--x24-Callee-save (ARM64 only)
csr6metadataTableMC (ARM64)x25-Metadata Table (LLInt) / Metadata Counter (IPInt ARM64)
csr7PBPC (ARM64)x26-PB register (LLInt) / Program Counter (IPInt ARM64)
csr8numberTag-x27-Number tag (LLInt ARM64)
csr9notCellMasksc2 (RISCV64)x28-Not cell mask (LLInt ARM64) / Safe call 2 (IPInt RISCV64)
csr10-PL (RISCV64), sc3 (RISCV64)--Pointer to Locals / Safe call 3 (IPInt RISCV64)

Floating Point Registers (FPRs)

Temporary FP Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
ft0fa0, wfa0, fr-q0/d0/s0xmm0FP argument 0 / return / temp
ft1fa1, wfa1-q1/d1/s1xmm1FP argument 1 / temp
ft2fa2, wfa2-q2/d2/s2xmm2FP argument 2 / temp
ft3fa3, wfa3-q3/d3/s3xmm3FP argument 3 / temp
ft4wfa4-q4/d4/s4xmm4Wasm FP temp
ft5wfa5-q5/d5/s5xmm5Wasm FP temp
ft6wfa6-q6/d6/s6xmm6Wasm FP temp
ft7wfa7-q7/d7/s7xmm7Wasm FP temp / scratch

Callee-Save FP Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
csfr0--q8/d8-Callee-save FP (ARM64 only)
csfr1--q9/d9-Callee-save FP (ARM64 only)
csfr2--q10/d10-Callee-save FP (ARM64 only)
csfr3--q11/d11-Callee-save FP (ARM64 only)
csfr4--q12/d12-Callee-save FP (ARM64 only)
csfr5--q13/d13-Callee-save FP (ARM64 only)
csfr6--q14/d14-Callee-save FP (ARM64 only)
csfr7--q15/d15-Callee-save FP (ARM64 only)
csfr8-11----(Reserved)

Vector Registers

SIMD/Vector Registers

OfflineasmLLInt AliasIPInt AliasARM64/ARM64EX86_64Purpose
v0--v16 (q16)xmm0Vector register 0
v0_b--v16.bxmm0 (byte)Vector 0, byte elements
v0_h--v16.hxmm0 (half)Vector 0, halfword elements
v0_i--v16.sxmm0 (int)Vector 0, word elements
v0_q--v16.dxmm0 (quad)Vector 0, doubleword elements
v1--v17 (q17)xmm1Vector register 1
v1_b--v17.bxmm1 (byte)Vector 1, byte elements
v1_h--v17.hxmm1 (half)Vector 1, halfword elements
v1_i--v17.sxmm1 (int)Vector 1, word elements
v1_q--v17.dxmm1 (quad)Vector 1, doubleword elements
v2--v18 (q18)xmm2Vector register 2
v2_b--v18.bxmm2 (byte)Vector 2, byte elements
v2_h--v18.hxmm2 (half)Vector 2, halfword elements
v2_i--v18.sxmm2 (int)Vector 2, word elements
v2_q--v18.dxmm2 (quad)Vector 2, doubleword elements
v3--v19 (q19)xmm3Vector register 3
v3_b--v19.bxmm3 (byte)Vector 3, byte elements
v3_h--v19.hxmm3 (half)Vector 3, halfword elements
v3_i--v19.sxmm3 (int)Vector 3, word elements
v3_q--v19.dxmm3 (quad)Vector 3, doubleword elements
v4--v20 (q20)xmm4Vector register 4
v4_b--v20.bxmm4 (byte)Vector 4, byte elements
v4_h--v20.hxmm4 (half)Vector 4, halfword elements
v4_i--v20.sxmm4 (int)Vector 4, word elements
v4_q--v20.dxmm4 (quad)Vector 4, doubleword elements
v5--v21 (q21)xmm5Vector register 5
v5_b--v21.bxmm5 (byte)Vector 5, byte elements
v5_h--v21.hxmm5 (half)Vector 5, halfword elements
v5_i--v21.sxmm5 (int)Vector 5, word elements
v5_q--v21.dxmm5 (quad)Vector 5, doubleword elements
v6--v22 (q22)xmm6Vector register 6
v6_b--v22.bxmm6 (byte)Vector 6, byte elements
v6_h--v22.hxmm6 (half)Vector 6, halfword elements
v6_i--v22.sxmm6 (int)Vector 6, word elements
v6_q--v22.dxmm6 (quad)Vector 6, doubleword elements
v7--v23 (q23)xmm7Vector register 7
v7_b--v23.bxmm7 (byte)Vector 7, byte elements
v7_h--v23.hxmm7 (half)Vector 7, halfword elements
v7_i--v23.sxmm7 (int)Vector 7, word elements
v7_q--v23.dxmm7 (quad)Vector 7, doubleword elements

Platform-Specific Notes

ARM64/ARM64E

  • Register widths:

    • xN = 64-bit GPR
    • wN = 32-bit GPR (low half of xN)
    • qN = 128-bit FPR/vector
    • dN = 64-bit FPR (double precision)
    • sN = 32-bit FPR (single precision)
    • vN = vector register with element type qualifier
  • Scratch registers: x13, x16, x17 (not exposed in offlineasm)

  • FPR scratch: q31

  • Vector registers: Shared with FPRs (q0-q15 overlap with ft0-csfr7, q16-q23 used for v0-v7)

X86_64

  • Register widths:

    • 64-bit: rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8-r15
    • 32-bit: eax, ebx, ecx, edx, esi, edi, ebp, esp, r8d-r15d
    • 16-bit: ax, bx, cx, dx, si, di, bp, sp, r8w-r15w
    • 8-bit: al, bl, cl, dl, sil, dil, bpl, spl, r8b-r15b
  • Scratch register: r11 (not exposed in offlineasm)

  • FPR scratch: xmm7

  • Limited callee-save: Only rbx, r12-r15 are callee-save

Register Conventions Summary

LowLevelInterpreter (LLInt) Conventions

PurposeOfflineasmARM64/ARM64E PhysicalX86_64 PhysicalDescription
PC (Program Counter)csr7x26r13Bytecode program counter
PB (Program Base)csr7x26r13Same as PC in LLInt
Metadata Tablecsr6x25r12Metadata pointer
Number Tagcsr8x27-Number type tag (ARM64 only)
Not Cell Maskcsr9x28-Cell type mask (ARM64 only)
Tag Type Numbercsr3x22r14Type number for tagging
Tag Maskcsr4x23r15Mask for type tags
Wasm Instancecsr0x19rbxWebAssembly instance pointer
Argumentst0-t7x0-x7rax,rsi,rdx,rcx,r8,r10,rdi,r9Function argument registers
FP Argumentsft0-ft3q0-q3xmm0-xmm3Floating-point arguments
Wasm Scratcht9-t12 (ws0-ws3)x9-x12-Wasm temporary registers

InPlaceInterpreter (IPInt) Conventions

IPInt is the WebAssembly in-place interpreter with its own specialized register assignments:

PurposeOfflineasmARM64/ARM64E PhysicalX86_64 PhysicalARMv7 PhysicalRISCV64 PhysicalDescription
PC (Program Counter)csr7x26csr2 (r13)csr1csr7IPInt bytecode position
MC (Metadata Counter)csr6x25csr1 (r12)t6csr6Metadata pointer
PL (Pointer to Locals)t6x6t5 (r10)t7csr10Address of local 0
WI (Wasm Instance)csr0x19rbxcsr0csr0JSWebAssemblyInstance pointer
MB (Memory Base)csr3x22r14t2 (ARMv7)csr3Wasm memory base address
BC (Bounds Check)csr4x23r15t3 (ARMv7)csr4Wasm memory bounds size
sc0 (safe for call)ws0 (t9)x9t9t4ws0 (t9)Safe call register 0
sc1 (safe for call)ws1 (t10)x10t10t5ws1 (t10)Safe call register 1
sc2 (safe for call)ws2 (t11)x11csr3 (r14)csr0csr9Safe call register 2
sc3 (safe for call)ws3 (t12)x12csr4 (r15)t7csr10Safe call register 3

IPInt Special Notes

  • PC (Program Counter): Records interpreter position in Wasm bytecode
  • MC (Metadata Counter): Tracks corresponding position in generated metadata
  • PL (Pointer to Locals): Fast access to local variables (points to local 0)
  • WI (Wasm Instance): Current JSWebAssemblyInstance object (callee-save)
  • MB (Memory Base): Current Wasm memory base address (callee-save)
  • BC (Bounds Check): Size of Wasm memory region for bounds checking (callee-save)
  • Safe call registers (sc0-sc3): Guaranteed not to overlap with argument registers, safe across calls

Platform-Specific IPInt Notes

ARM64/ARM64E:

  • Uses ldp/stp instructions for efficient register pair operations
  • Memory registers (MB, BC) loaded via loadpairq from instance

X86_64:

  • PC maps to csr2 instead of csr7 (different from LLInt)
  • MC maps to csr1 instead of csr6 (different from LLInt)
  • sc2 and sc3 reuse csr3/csr4 (MB/BC) as they're already in use
  • Fewer argument registers (6 vs 8 on ARM64)

ARMv7:

  • MB and BC use temporary registers (t2, t3) instead of callee-save
  • More limited register set requires creative reuse

RISCV64:

  • Similar to ARM64 in register allocation
  • PL uses csr10 instead of t6

Source Files

  • Register definitions: Source/JavaScriptCore/offlineasm/registers.rb
  • ARM64 mappings: Source/JavaScriptCore/offlineasm/arm64.rb
  • X86_64 mappings: Source/JavaScriptCore/offlineasm/x86.rb
  • LLInt code: Source/JavaScriptCore/llint/LowLevelInterpreter.asm
  • IPInt code: Source/JavaScriptCore/llint/InPlaceInterpreter.asm