๐Ÿ“ฆ AlistairKeiller / asm-test

๐Ÿ“„ mandel.s ยท 140 lines
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140.data
star: .ascii "*"
star_len = . - star
space:  .ascii " "
space_len = . - space
newline: .ascii "\n"
newline_len = . - newline
width = 80
height = 20
max_iter = 100
scale_x: .double 0.05
scale_y: .double 0.1
offset_x: .double -2.5
offset_y: .double -1.0

.text
.global _start
_start:
    // mandelbrot()
    bl mandelbrot

    // _exit(0)
    mov     x0, #0
    mov     w8, #93
    svc     #0

mandelbrot:
    // x3 = 0, x4 = 0
    mov x3, 0
    mov x4, 0

    // d4 = scale_x, d5 = scale_y, d6 = offset_x, d7 = offset_y
    ldr  x9, =scale_x
    ldr  d4, [x9]

    ldr  x10, =scale_y
    ldr  d5, [x10]

    ldr  x11, =offset_x
    ldr  d6, [x11]

    ldr  x12, =offset_y
    ldr  d7, [x12]


mandelbrot_loop:
    // if (x3 >= height) mandelbrot_done();
    cmp x3, height
    bge mandelbrot_done

    // if (x4 >= width) { mandelbrot_next_line() }
    cmp x4, width
    bge mandelbrot_next_line

    // d0 = (double)x4 * scale_x + offset_x
    // d1 = (double)x3 * scale_y + offset_y
    scvtf d0, x4
    scvtf d1, x3
    fmul d0, d0, d4
    fmul d1, d1, d5
    fadd d0, d0, d6
    fadd d1, d1, d7

    // d2 = 0.0, d3 = 0.0, w5=0
    fmov d2, xzr
    fmov d3, xzr
    mov w5, #0

mandelbrot_iter:
    cmp w5, max_iter
    bge mandelbrot_plot_space

    // (a+b*i)^2=(a^2-b^2)+2*a*b*i
    // d8 = d2*d2 - d3*d3 + d0
    fmul d8, d2, d2
    fmul d9, d3, d3
    fsub d8, d8, d9
    fadd d8, d8, d0
    // d9 = 2*d2*d3 + d1
    fmul d9, d2, d3
    fadd d9, d9, d9
    fadd d9, d9, d1

    // magnitude = d8*d8 + d9*d9
    fmul d10, d8, d8
    fmul d11, d9, d9
    fadd d10, d10, d11

    // if (magnitude > 4.0) { mandelbrot_plot_star(); }
    fmov d11, #4.0
    fcmp d10, d11
    bgt mandelbrot_plot_star

    // d2 = d8, d3 = d9
    fmov d2, d8
    fmov d3, d9

    // iter++
    add w5, w5, 1
    b mandelbrot_iter

// return;
mandelbrot_done:
    ret

// x4 = 0; x3++; putchar('\n');
mandelbrot_next_line:
    mov x4, 0
    add x3, x3, 1

    mov     x0, #1
    ldr x1, =newline
    ldr x2, =newline_len
    mov     w8, #64
    svc     #0

    b mandelbrot_loop

// putchar('*');
mandelbrot_plot_star:
    mov     x0, #1
    ldr x1, =star
    ldr x2, =star_len
    mov     w8, #64
    svc     #0
    b mandelbrot_next_pixel

// putchar(' ');
mandelbrot_plot_space:
    mov     x0, #1
    ldr x1, =space
    ldr x2, =space_len
    mov     w8, #64
    svc     #0

// x4 += 1
mandelbrot_next_pixel:
    add x4, x4, 1
    b mandelbrot_loop