+ #[cfg(target_arch="x86_64")]
+ pub fn decode_bit(&mut self, idx: usize) -> bool {
+ unsafe {
+ // states offset - 0x18
+ // cod_range offset - 0x418
+ // cod_offset offset - 0x41A
+ let mut bit: u16;
+ asm!(
+ // unpack state
+ "movzx {state_idx:e}, byte ptr [{ctx} + 0x18 + {idx}]",
+ "mov {val_mps:x}, {state_idx:x}",
+ "and {state_idx}, 0x3F",
+ "and {val_mps:r}, 0x80",
+ "movzx {tmp}, word ptr [{ctx} + 0x418]",
+ "mov {bit:r}, {val_mps:r}",
+ "shr {tmp}, 6",
+ "and {tmp}, 3",
+ "lea {range_lps:r}, {range_tab}[rip]",
+ "lea {range_lps:r}, [{range_lps:r} + {state_idx} * 4]",
+ "movzx {range_lps:x}, byte ptr [{range_lps:r} + {tmp}]",
+ // self.cod_range -= range_lps;
+ "sub word ptr [{ctx} + 0x418], {range_lps:x}",
+ // determine bit value
+ "mov {tmp:x}, word ptr [{ctx} + 0x41A]",
+ "cmp {tmp:x}, word ptr [{ctx} + 0x418]",
+ "jl 1f",
+ "sub {tmp:x}, word ptr [{ctx} + 0x418]",
+ "mov word ptr [{ctx} + 0x418], {range_lps:x}",
+ "mov word ptr [{ctx} + 0x41A], {tmp:x}",
+ "xor {bit:l}, 0x80",
+ "1:",
+ // update state[idx]
+ "cmp {bit:x}, {val_mps:x}",
+ "jne 2f",
+ "lea {tmp}, {trans_idx_mps}[rip]",
+ "jmp 3f",
+ "2:",
+ "lea {tmp}, {trans_idx_lps}[rip]",
+ "cmp {state_idx}, 0",
+ "jnz 3f",
+ "xor {val_mps:x}, 0x80",
+ "3:",
+ "movzx {tmp}, byte ptr [{tmp} + {state_idx}]",
+ "or {tmp:x}, {val_mps:x}",
+ "mov byte ptr [{ctx} + 0x18 + {idx}], {tmp:l}",
+
+ ctx = inout(reg) self => _,
+ idx = inout(reg) idx => _,
+ bit = out(reg) bit,
+ range_tab = sym RANGE_TBL_LPS,
+ trans_idx_mps = sym TRANS_IDX_MPS,
+ trans_idx_lps = sym TRANS_IDX_LPS,
+ val_mps = out(reg) _,
+ state_idx = out(reg) _,
+ tmp = out(reg) _,
+ range_lps = out(reg) _,
+ );
+
+ self.renorm();
+ bit != 0
+ }
+ }