mirror of
https://github.com/vlang/v.git
synced 2025-09-12 00:46:55 -04:00
cgen,parser: fix arm64 asm operand position; fix arm64 asm imm; support arm64 dot instruction (#24017)
This commit is contained in:
parent
1f07431e1a
commit
e733c007bf
@ -3130,8 +3130,8 @@ fn (mut g Gen) asm_stmt(stmt ast.AsmStmt) {
|
||||
} else {
|
||||
g.write(' ')
|
||||
}
|
||||
// swap destination and operands for att syntax
|
||||
if template.args.len != 0 && !template.is_directive {
|
||||
// swap destination and operands for att syntax, not for arm64
|
||||
if template.args.len != 0 && !template.is_directive && stmt.arch != .arm64 {
|
||||
template.args.prepend(template.args.last())
|
||||
template.args.delete(template.args.len - 1)
|
||||
}
|
||||
@ -3206,7 +3206,11 @@ fn (mut g Gen) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt) {
|
||||
g.write("'${arg.val}'")
|
||||
}
|
||||
ast.IntegerLiteral {
|
||||
g.write('\$${arg.val}')
|
||||
if stmt.arch == .arm64 {
|
||||
g.write('#${arg.val}')
|
||||
} else {
|
||||
g.write('\$${arg.val}')
|
||||
}
|
||||
}
|
||||
ast.FloatLiteral {
|
||||
if g.pref.nofloat {
|
||||
|
@ -1266,6 +1266,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||
for p.tok.kind !in [.semicolon, .rcbr, .eof] {
|
||||
template_pos := p.tok.pos()
|
||||
mut name := ''
|
||||
mut comments := []ast.Comment{}
|
||||
if p.tok.kind == .name && arch == .amd64 && p.tok.lit in ['rex', 'vex', 'xop'] {
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
@ -1297,12 +1298,16 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||
} else if p.tok.kind == .number {
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
} else if p.tok.kind == .comment {
|
||||
for p.tok.kind == .comment {
|
||||
comments << p.comment()
|
||||
}
|
||||
} else {
|
||||
name += p.tok.lit
|
||||
p.check(.name)
|
||||
}
|
||||
// dots are part of instructions for some riscv extensions and webassembly
|
||||
if arch in [.rv32, .rv64, .wasm32] {
|
||||
// dots are part of instructions for some riscv extensions and webassembly, arm64
|
||||
if arch in [.rv32, .rv64, .wasm32, .arm64] {
|
||||
for p.tok.kind == .dot {
|
||||
name += '.'
|
||||
p.next()
|
||||
@ -1405,7 +1410,6 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||
// break
|
||||
// }
|
||||
}
|
||||
mut comments := []ast.Comment{}
|
||||
for p.tok.kind == .comment {
|
||||
comments << p.comment()
|
||||
}
|
||||
|
124
vlib/v/slow_tests/assembly/asm_test.arm64.v
Normal file
124
vlib/v/slow_tests/assembly/asm_test.arm64.v
Normal file
@ -0,0 +1,124 @@
|
||||
// vtest build: gcc
|
||||
fn test_inline_asm() {
|
||||
a, mut b := 10, 0
|
||||
asm arm64 {
|
||||
mov x0, a
|
||||
mov b, x0
|
||||
; +r (b)
|
||||
; r (a)
|
||||
; x0
|
||||
}
|
||||
assert a == 10
|
||||
assert b == 10
|
||||
|
||||
mut c := 0
|
||||
asm arm64 {
|
||||
mov x0, 5
|
||||
mov c, x0
|
||||
; +r (c)
|
||||
; ; x0
|
||||
}
|
||||
assert c == 5
|
||||
|
||||
d, e, mut f := 10, 2, 0
|
||||
asm arm64 {
|
||||
mov x0, d
|
||||
mov x1, e
|
||||
add x0, x0, x1
|
||||
add x0, x0, 5
|
||||
mov f, x0
|
||||
; +r (f) // output
|
||||
; r (d)
|
||||
r (e) // input
|
||||
; x0
|
||||
x1
|
||||
}
|
||||
assert d == 10
|
||||
assert e == 2
|
||||
assert f == 17
|
||||
|
||||
mut j := 0
|
||||
// do 5*3
|
||||
// adding three, five times
|
||||
asm arm64 {
|
||||
mov x0, 5 // loop 5 times
|
||||
mov x1, 0
|
||||
loop_start:
|
||||
add x1, x1, 3
|
||||
sub x0, x0, 1
|
||||
cmp x0, 0
|
||||
b.gt loop_start
|
||||
mov j, x1
|
||||
; +r (j)
|
||||
; ; x0
|
||||
x1
|
||||
}
|
||||
assert j == 5 * 3
|
||||
/*
|
||||
// not marked as mut because we dereference m to change l
|
||||
l := 5
|
||||
m := &l
|
||||
asm arm64 {
|
||||
movd [m], 7 // have to specify size with q
|
||||
; ; r (m)
|
||||
}
|
||||
assert l == 7
|
||||
|
||||
mut manu := Manu{}
|
||||
asm arm64 {
|
||||
mov x0, MIDR_EL1
|
||||
mov x1, ID_AA64ISAR0_EL1
|
||||
mov x2, ID_AA64MMFR0_EL1
|
||||
; =r (manu.midr_el1) as x0
|
||||
=r (manu.id_aa64isar0_el1) as x1
|
||||
=r (manu.id_aa64mmfr0_el1) as x2
|
||||
}
|
||||
manu.str()
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@[packed]
|
||||
struct Manu {
|
||||
mut:
|
||||
midr_el1 u64
|
||||
id_aa64isar0_el1 u64
|
||||
id_aa64mmfr0_el1 u64
|
||||
zero u8 // for string
|
||||
}
|
||||
|
||||
fn (m Manu) str() string {
|
||||
return unsafe {
|
||||
string{
|
||||
str: &u8(&m)
|
||||
len: 24
|
||||
is_lit: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_asm_generic() {
|
||||
u := u64(49)
|
||||
b := unsafe { bool(123) }
|
||||
assert generic_asm(u) == 14
|
||||
assert u == 63
|
||||
assert u64(generic_asm(b)) == 14
|
||||
assert u64(b) == 137
|
||||
}
|
||||
|
||||
fn generic_asm[T](var &T) T {
|
||||
mut ret := T(14)
|
||||
unsafe {
|
||||
asm volatile arm64 {
|
||||
mov x0, ret
|
||||
mov x1, var
|
||||
add x1, x0, 0
|
||||
mov var, x1
|
||||
; +m (var[0]) as var
|
||||
+r (ret)
|
||||
; ; memory x0 x1
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user