v2 / vlib / v / fmt / asm.v
195 lines · 180 sloc · 3.72 KB · 8e35f4d9848f7ad35d857a187dddbfd2eca5e19d
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module fmt
5
6import v.ast
7
8fn (mut f Fmt) asm_stmt(stmt ast.AsmStmt) {
9 f.write('asm ')
10 if stmt.is_volatile {
11 f.write('volatile ')
12 } else if stmt.is_goto {
13 f.write('goto ')
14 }
15 lit_arch := if stmt.arch == .wasm32 {
16 'wasm'
17 } else {
18 stmt.arch.str()
19 }
20 f.writeln('${lit_arch} {')
21 f.indent++
22
23 f.asm_templates(stmt.templates)
24
25 if stmt.output.len != 0 || stmt.input.len != 0 || stmt.clobbered.len != 0 {
26 f.write('; ')
27 }
28 f.asm_ios(stmt.output)
29
30 if stmt.input.len != 0 || stmt.clobbered.len != 0 {
31 f.write('; ')
32 }
33 f.asm_ios(stmt.input)
34
35 if stmt.clobbered.len != 0 {
36 f.write('; ')
37 }
38 f.asm_clobbered(stmt.clobbered)
39
40 f.indent--
41 f.writeln('}')
42 if f.indent == 0 {
43 f.writeln('')
44 }
45}
46
47fn (mut f Fmt) asm_arg(arg ast.AsmArg) {
48 match arg {
49 ast.AsmRegister {
50 f.asm_reg(arg)
51 }
52 ast.AsmAlias {
53 f.write('${arg.name}')
54 }
55 ast.IntegerLiteral, ast.FloatLiteral, ast.CharLiteral {
56 f.write(arg.val)
57 }
58 ast.BoolLiteral {
59 f.write(arg.val.str())
60 }
61 string {
62 f.string_literal(ast.StringLiteral{ val: arg })
63 }
64 ast.AsmAddressing {
65 if arg.segment != '' {
66 f.write(arg.segment)
67 f.write(':')
68 }
69 f.write('[')
70 base := arg.base
71 index := arg.index
72 displacement := arg.displacement
73 scale := arg.scale
74 match arg.mode {
75 .base {
76 f.asm_arg(base)
77 }
78 .displacement {
79 f.asm_arg(displacement)
80 }
81 .base_plus_displacement {
82 f.asm_arg(base)
83 f.write(' + ')
84 f.asm_arg(displacement)
85 }
86 .index_times_scale_plus_displacement {
87 f.asm_arg(index)
88 f.write(' * ${scale} + ')
89 f.asm_arg(displacement)
90 }
91 .base_plus_index_plus_displacement {
92 f.asm_arg(base)
93 f.write(' + ')
94 f.asm_arg(index)
95 f.write(' + ')
96 f.asm_arg(displacement)
97 }
98 .base_plus_index_times_scale_plus_displacement {
99 f.asm_arg(base)
100 f.write(' + ')
101 f.asm_arg(index)
102 f.write(' * ${scale} + ')
103 f.asm_arg(displacement)
104 }
105 .rip_plus_displacement {
106 f.asm_arg(base)
107 f.write(' + ')
108 f.asm_arg(displacement)
109 }
110 .invalid {
111 panic('fmt: invalid addressing mode')
112 }
113 }
114
115 f.write(']')
116 }
117 ast.AsmDisp {
118 if arg.val.len >= 2 && arg.val[arg.val.len - 1] in [`b`, `f`]
119 && arg.val[..arg.val.len - 1].bytes().all(it.is_digit()) {
120 f.write(arg.val[arg.val.len - 1].ascii_str())
121 f.write(arg.val[..arg.val.len - 1])
122 } else {
123 f.write(arg.val)
124 }
125 }
126 }
127}
128
129fn (mut f Fmt) asm_reg(reg ast.AsmRegister) {
130 f.write(reg.name)
131}
132
133fn (mut f Fmt) asm_templates(templates []ast.AsmTemplate) {
134 for template in templates {
135 if template.is_directive {
136 f.write('.')
137 }
138 f.write('${template.name}')
139 if template.is_label {
140 f.write(':')
141 } else if template.args.len > 0 {
142 f.write(' ')
143 }
144 for i, arg in template.args {
145 f.asm_arg(arg)
146 if i + 1 < template.args.len {
147 f.write(', ')
148 }
149 }
150 if template.comments.len == 0 {
151 f.writeln('')
152 } else {
153 f.comments(template.comments)
154 }
155 }
156}
157
158fn (mut f Fmt) asm_clobbered(clobbered []ast.AsmClobbered) {
159 for i, clob in clobbered {
160 if i != 0 {
161 f.write(' ')
162 }
163 f.write(clob.reg.name)
164
165 if clob.comments.len == 0 {
166 f.writeln('')
167 } else {
168 f.comments(clob.comments)
169 }
170 }
171}
172
173fn (mut f Fmt) asm_ios(ios []ast.AsmIO) {
174 for i, io in ios {
175 if i != 0 {
176 f.write(' ')
177 }
178
179 f.write('${io.constraint} (${io.expr})')
180 mut as_block := true
181 if io.expr is ast.Ident {
182 if io.expr.name == io.alias {
183 as_block = false
184 }
185 }
186 if as_block && io.alias != '' {
187 f.write(' as ${io.alias}')
188 }
189 if io.comments.len == 0 {
190 f.writeln('')
191 } else {
192 f.comments(io.comments)
193 }
194 }
195}
196