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 {
|
} else {
|
||||||
g.write(' ')
|
g.write(' ')
|
||||||
}
|
}
|
||||||
// swap destination and operands for att syntax
|
// swap destination and operands for att syntax, not for arm64
|
||||||
if template.args.len != 0 && !template.is_directive {
|
if template.args.len != 0 && !template.is_directive && stmt.arch != .arm64 {
|
||||||
template.args.prepend(template.args.last())
|
template.args.prepend(template.args.last())
|
||||||
template.args.delete(template.args.len - 1)
|
template.args.delete(template.args.len - 1)
|
||||||
}
|
}
|
||||||
@ -3206,8 +3206,12 @@ fn (mut g Gen) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt) {
|
|||||||
g.write("'${arg.val}'")
|
g.write("'${arg.val}'")
|
||||||
}
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
|
if stmt.arch == .arm64 {
|
||||||
|
g.write('#${arg.val}')
|
||||||
|
} else {
|
||||||
g.write('\$${arg.val}')
|
g.write('\$${arg.val}')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ast.FloatLiteral {
|
ast.FloatLiteral {
|
||||||
if g.pref.nofloat {
|
if g.pref.nofloat {
|
||||||
g.write('\$${arg.val.int()}')
|
g.write('\$${arg.val.int()}')
|
||||||
|
@ -1266,6 +1266,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
|||||||
for p.tok.kind !in [.semicolon, .rcbr, .eof] {
|
for p.tok.kind !in [.semicolon, .rcbr, .eof] {
|
||||||
template_pos := p.tok.pos()
|
template_pos := p.tok.pos()
|
||||||
mut name := ''
|
mut name := ''
|
||||||
|
mut comments := []ast.Comment{}
|
||||||
if p.tok.kind == .name && arch == .amd64 && p.tok.lit in ['rex', 'vex', 'xop'] {
|
if p.tok.kind == .name && arch == .amd64 && p.tok.lit in ['rex', 'vex', 'xop'] {
|
||||||
name += p.tok.lit
|
name += p.tok.lit
|
||||||
p.next()
|
p.next()
|
||||||
@ -1297,12 +1298,16 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
|||||||
} else if p.tok.kind == .number {
|
} else if p.tok.kind == .number {
|
||||||
name += p.tok.lit
|
name += p.tok.lit
|
||||||
p.next()
|
p.next()
|
||||||
|
} else if p.tok.kind == .comment {
|
||||||
|
for p.tok.kind == .comment {
|
||||||
|
comments << p.comment()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
name += p.tok.lit
|
name += p.tok.lit
|
||||||
p.check(.name)
|
p.check(.name)
|
||||||
}
|
}
|
||||||
// dots are part of instructions for some riscv extensions and webassembly
|
// dots are part of instructions for some riscv extensions and webassembly, arm64
|
||||||
if arch in [.rv32, .rv64, .wasm32] {
|
if arch in [.rv32, .rv64, .wasm32, .arm64] {
|
||||||
for p.tok.kind == .dot {
|
for p.tok.kind == .dot {
|
||||||
name += '.'
|
name += '.'
|
||||||
p.next()
|
p.next()
|
||||||
@ -1405,7 +1410,6 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
|||||||
// break
|
// break
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
mut comments := []ast.Comment{}
|
|
||||||
for p.tok.kind == .comment {
|
for p.tok.kind == .comment {
|
||||||
comments << p.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