1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
b0VIM 9.0 �q�j�{ . mkeeter cfarm14 ~mkeeter/fidget/fidget-jit/src/x86_64/grad_slice.rs utf-8
U3210 #"! U tp Q h R i � k # ^ � @ � �
b d ad
f Q � � | < � � � � t ; �
�
�
H
D
� q # � � 9 �
�
O
� e � { - � � C � � Y � y x R * � � � d Y
� � � k X W ; � � � � � Z " � � � � w l f e } ); ; vmovups Rx(reg(dst_reg)), [rsp + sp_offset] dynasm!(self.0.ops .unwrap(); .try_into() + STACK_SIZE_LOWER as u32) let sp_offset: i32 = (self.0.stack_pos(src_mem) assert!((dst_reg as usize) < REGISTER_LIMIT); fn build_load(&mut self, dst_reg: u8, src_mem: u32) { } Self(out) ); ; jz ->X // jump to the exit if we're done, otherwise fallthrough ; test rdx, rdx ; ->L: // The loop returns here, and we check whether to keep looping ; xor rcx, rcx // set the array offset (rcx) to 0 dynasm!(out.ops out.prepare_stack(slot_count, STACK_SIZE_UPPER + STACK_SIZE_LOWER); ); ; mov rbp, rsp ; push rbp dynasm!(out.ops let mut out = AssemblerData::new(mmap); fn init(mmap: Mmap, slot_count: usize) -> Self { type Data = Grad; impl Assembler for GradSliceAssembler { #[expect(clippy::useless_conversion)] const STACK_SIZE_LOWER: usize = 0xc0; // Positions relative to `rsp` const STACK_SIZE_UPPER: usize = 0x20; // Positions relative to `rbp` /// ``` /// | 0x00 | xmm4 | | /// | 0x10 | xmm5 | | /// | 0x20 | xmm6 | | /// | 0x30 | xmm7 | | /// | 0x40 | xmm8 | | /// | 0x50 | xmm9 | | /// | 0x60 | xmm10 | | /// | 0x70 | xmm11 | | /// | 0x80 | xmm12 | | /// | 0x90 | xmm13 | | /// | 0xa0 | xmm14 | calls are placed here, then restored | /// | 0xb0 | xmm15 | Caller-saved registers during functions | /// |----------|--------------|---------------------------------------------| /// | ... | ... | Register spills live up here | /// |----------|--------------|---------------------------------------------| /// | -0x20 | `rcx` | | /// | -0x18 | `rdx` | previous values on the stack | /// | -0x10 | `rsi` | as temporary storage so must preserve their | /// | -0x08 | `rdi` | During functions calls, we use these | /// |----------|--------------|---------------------------------------------| /// | 0x00 | `rbp` | Previous value for base pointer | /// |----------|--------------|---------------------------------------------| /// | Position | Value | Notes | /// ```text ///