ast,cgen,parser,pref: support loongarch64 inline assembly, add test (#24440)

This commit is contained in:
Mike 2025-05-09 14:57:52 +03:00 committed by GitHub
parent 9dc69ef2aa
commit 47f8f347b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 6 deletions

View File

@ -1839,6 +1839,12 @@ pub const ppc64le_with_number_register_list = {
'r#': 32 'r#': 32
} }
pub const loongarch64_no_number_register_list = []string{}
pub const loongarch64_with_number_register_list = {
'f#': 32
'r#': 32
}
pub struct DebuggerStmt { pub struct DebuggerStmt {
pub: pub:
pos token.Pos pos token.Pos
@ -2658,6 +2664,13 @@ pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject {
res[k] = v res[k] = v
} }
} }
.loongarch64 {
loongarch64 := gen_all_registers(mut t, loongarch64_no_number_register_list,
loongarch64_with_number_register_list, 64)
for k, v in loongarch64 {
res[k] = v
}
}
.wasm32 { .wasm32 {
// no registers // no registers
} }

View File

@ -53,6 +53,7 @@ pub enum Language {
rv32 // 32-bit risc-v rv32 // 32-bit risc-v
s390x s390x
ppc64le ppc64le
loongarch64
wasm32 wasm32
} }
@ -83,6 +84,9 @@ pub fn pref_arch_to_table_language(pref_arch pref.Arch) Language {
.ppc64le { .ppc64le {
.ppc64le .ppc64le
} }
.loongarch64 {
.loongarch64
}
.js_node, .js_browser, .js_freestanding { .js_node, .js_browser, .js_freestanding {
.js .js
} }

View File

@ -3158,7 +3158,7 @@ fn (mut g Gen) asm_stmt(stmt ast.AsmStmt) {
} }
// swap destination and operands for att syntax, not for arm64 // swap destination and operands for att syntax, not for arm64
if template.args.len != 0 && !template.is_directive && stmt.arch != .arm64 if template.args.len != 0 && !template.is_directive && stmt.arch != .arm64
&& stmt.arch != .s390x && stmt.arch != .ppc64le { && stmt.arch != .s390x && stmt.arch != .ppc64le && stmt.arch != .loongarch64 {
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)
} }
@ -3235,7 +3235,7 @@ fn (mut g Gen) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt) {
ast.IntegerLiteral { ast.IntegerLiteral {
if stmt.arch == .arm64 { if stmt.arch == .arm64 {
g.write('#${arg.val}') g.write('#${arg.val}')
} else if stmt.arch == .s390x || stmt.arch == .ppc64le { } else if stmt.arch == .s390x || stmt.arch == .ppc64le || stmt.arch == .loongarch64 {
g.write('${arg.val}') g.write('${arg.val}')
} else { } else {
g.write('\$${arg.val}') g.write('\$${arg.val}')
@ -3252,10 +3252,14 @@ fn (mut g Gen) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt) {
g.write('\$${arg.val.str()}') g.write('\$${arg.val.str()}')
} }
ast.AsmRegister { ast.AsmRegister {
if !stmt.is_basic { if stmt.arch == .loongarch64 {
g.write('%') // escape percent with percent in extended assembly g.write('$${arg.name}')
} else {
if !stmt.is_basic {
g.write('%') // escape percent with percent in extended assembly
}
g.write('%${arg.name}')
} }
g.write('%${arg.name}')
} }
ast.AsmAddressing { ast.AsmAddressing {
if arg.segment != '' { if arg.segment != '' {

View File

@ -1321,7 +1321,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
p.check(.name) p.check(.name)
} }
// dots are part of instructions for some riscv extensions and webassembly, arm64 // dots are part of instructions for some riscv extensions and webassembly, arm64
if arch in [.rv32, .rv64, .wasm32, .arm64] { if arch in [.rv32, .rv64, .wasm32, .arm64, .loongarch64] {
for p.tok.kind == .dot { for p.tok.kind == .dot {
name += '.' name += '.'
p.next() p.next()

View File

@ -10,6 +10,7 @@ pub enum Arch {
i386 i386
s390x s390x
ppc64le ppc64le
loongarch64
js_node js_node
js_browser js_browser
js_freestanding js_freestanding
@ -53,6 +54,9 @@ pub fn arch_from_string(arch_str string) !Arch {
's390x' { 's390x' {
return .s390x return .s390x
} }
'loongarch64' {
return .loongarch64
}
'ppc64le' { 'ppc64le' {
return .ppc64le return .ppc64le
} }

View File

@ -0,0 +1,37 @@
// vtest build: gcc
asm loongarch64 {
move r20, r21
}
fn test_inline_asm() {
a, mut b := 10, 0
asm loongarch64 {
move r20, a
move b, r20
; +r (b)
; r (a)
; r20
}
assert a == b
mut c := 0
asm loongarch64 {
li.w c, 5
; +r (c)
}
assert c == 5
d, e, mut f := 10, 2, 0
asm loongarch64 {
move f, d
add.w f, f, e
addi.w f, f, 5
; +r (f)
; r (d)
r (e)
}
assert d == 10
assert e == 2
assert f == 17
}