mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen, parser: fix several assembly bugs (#10498)
This commit is contained in:
parent
39e7290416
commit
4688c75389
@ -1950,7 +1950,7 @@ fn (mut g Gen) gen_asm_stmt(stmt ast.AsmStmt) {
|
||||
g.write(' ')
|
||||
}
|
||||
// swap destionation and operands for att syntax
|
||||
if template.args.len != 0 {
|
||||
if template.args.len != 0 && !template.is_directive {
|
||||
template.args.prepend(template.args[template.args.len - 1])
|
||||
template.args.delete(template.args.len - 1)
|
||||
}
|
||||
@ -2052,8 +2052,16 @@ fn (mut g Gen) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt) {
|
||||
g.write(')')
|
||||
}
|
||||
.index_times_scale_plus_displacement {
|
||||
g.asm_arg(displacement, stmt)
|
||||
g.write('(')
|
||||
if displacement is ast.AsmDisp {
|
||||
g.asm_arg(displacement, stmt)
|
||||
g.write('(, ')
|
||||
} else if displacement is ast.AsmRegister {
|
||||
g.write('(')
|
||||
g.asm_arg(displacement, stmt)
|
||||
g.write(',')
|
||||
} else {
|
||||
panic('unexpected $displacement.type_name()')
|
||||
}
|
||||
g.asm_arg(index, stmt)
|
||||
g.write(',$scale)')
|
||||
}
|
||||
|
@ -885,22 +885,32 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||
for p.tok.kind !in [.semicolon, .rcbr] {
|
||||
template_pos := p.tok.position()
|
||||
mut name := ''
|
||||
if p.tok.kind == .name && arch == .amd64 && p.tok.lit in ['rex', 'vex', 'xop'] {
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
for p.tok.kind == .dot {
|
||||
p.next()
|
||||
name += '.' + p.tok.lit
|
||||
p.check(.name)
|
||||
}
|
||||
name += ' '
|
||||
}
|
||||
is_directive := p.tok.kind == .dot
|
||||
if is_directive {
|
||||
p.next()
|
||||
}
|
||||
if p.tok.kind in [.key_in, .key_lock, .key_orelse] { // `in`, `lock`, `or` are v keywords that are also x86/arm/riscv instructions.
|
||||
name = p.tok.kind.str()
|
||||
name += p.tok.kind.str()
|
||||
p.next()
|
||||
} else if p.tok.kind == .number {
|
||||
name = p.tok.lit
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
} else {
|
||||
name = p.tok.lit
|
||||
name += p.tok.lit
|
||||
p.check(.name)
|
||||
}
|
||||
// dots are part of instructions for some riscv extensions
|
||||
if arch in [.rv32, .rv64, .amd64] {
|
||||
if arch in [.rv32, .rv64] {
|
||||
for p.tok.kind == .dot {
|
||||
name += '.'
|
||||
p.next()
|
||||
@ -949,8 +959,9 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||
}
|
||||
}
|
||||
ast.IntegerLiteral {
|
||||
if is_directive || number_lit.val.ends_with('b')
|
||||
|| number_lit.val.ends_with('f') {
|
||||
if (is_directive || number_lit.val.ends_with('b')
|
||||
|| number_lit.val.ends_with('f'))
|
||||
&& !number_lit.val.starts_with('0x') {
|
||||
args << ast.AsmDisp{
|
||||
val: number_lit.val
|
||||
pos: number_lit.pos
|
||||
@ -1217,11 +1228,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
}
|
||||
} else if p.tok.kind == .number {
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
@ -1241,11 +1253,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
p.next()
|
||||
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
@ -1262,11 +1275,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
if p.peek_tok.kind == .rsbr {
|
||||
if p.tok.kind == .number {
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
@ -1288,11 +1302,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
p.check(.number)
|
||||
p.check(.plus)
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
@ -1308,11 +1323,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
} else if p.tok.kind == .plus {
|
||||
p.next()
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
@ -1333,11 +1349,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
||||
p.check(.number)
|
||||
p.check(.plus)
|
||||
displacement := if p.tok.kind == .name {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
p.next()
|
||||
x
|
||||
p.reg_or_alias()
|
||||
} else {
|
||||
x := ast.AsmArg(p.tok.lit)
|
||||
x := ast.AsmArg(ast.AsmDisp{
|
||||
val: p.tok.lit
|
||||
pos: p.tok.position()
|
||||
})
|
||||
p.check(.number)
|
||||
x
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ fn test_inline_asm() {
|
||||
asm amd64 {
|
||||
movq [m], 7 // have to specify size with q
|
||||
; ; r (m)
|
||||
; memory
|
||||
}
|
||||
assert l == 7
|
||||
|
||||
@ -98,15 +99,15 @@ fn test_inline_asm() {
|
||||
|
||||
assert util.add(8, 9, 34, 7) == 58 // test .amd64.v imported files
|
||||
|
||||
mut manu := Manu{}
|
||||
mut o := Manu{}
|
||||
asm amd64 {
|
||||
mov eax, 0
|
||||
cpuid
|
||||
; =b (manu.ebx) as ebx0
|
||||
=d (manu.edx) as edx0
|
||||
=c (manu.ecx) as ecx0
|
||||
; =b (o.ebx) as ebx0
|
||||
=d (o.edx) as edx0
|
||||
=c (o.ecx) as ecx0
|
||||
}
|
||||
manu.str()
|
||||
o.str()
|
||||
}
|
||||
|
||||
[packed]
|
||||
@ -129,19 +130,47 @@ fn (m Manu) str() string {
|
||||
}
|
||||
|
||||
// this test does not appear in i386 test since rip relative addressing was introduced in 64-bit mode
|
||||
// doesn't actually work
|
||||
[if !macos]
|
||||
fn test_rip_relative_label() {
|
||||
mut a := i64(4)
|
||||
asm amd64 {
|
||||
mov a, [rip + one_two_three] // see below
|
||||
; =r (a)
|
||||
$if !macos {
|
||||
mut a := i64(4)
|
||||
asm amd64 {
|
||||
mov a, [rip + one_two_three] // see below
|
||||
; =r (a)
|
||||
}
|
||||
assert a == 48321074923
|
||||
}
|
||||
assert a == 48321074923
|
||||
}
|
||||
|
||||
asm amd64 {
|
||||
.global one_two_three
|
||||
one_two_three:
|
||||
.quad 48321074923
|
||||
$if !macos {
|
||||
asm amd64 {
|
||||
.global one_two_three
|
||||
one_two_three:
|
||||
.quad 48321074923
|
||||
}
|
||||
}
|
||||
|
||||
// this test does not appear in i386 test since rip relative addressing was introduced in 64-bit mode
|
||||
// doesn't actually work
|
||||
[if !macos]
|
||||
fn test_rip_relative_label_byte() {
|
||||
$if !macos {
|
||||
mut a := int(4)
|
||||
asm amd64 {
|
||||
mov a, [rip + byte_sequence] // see below
|
||||
; =r (a)
|
||||
}
|
||||
assert a == 0x480f3527
|
||||
}
|
||||
}
|
||||
|
||||
$if !macos {
|
||||
asm amd64 {
|
||||
.global one_two_three
|
||||
byte_sequence:
|
||||
.byte 0x27, 0x35, 0x0f, 0x48
|
||||
}
|
||||
}
|
||||
|
||||
fn test_flag_output() {
|
||||
|
Loading…
Reference in New Issue
Block a user