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(' ')
|
g.write(' ')
|
||||||
}
|
}
|
||||||
// swap destionation and operands for att syntax
|
// 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.prepend(template.args[template.args.len - 1])
|
||||||
template.args.delete(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(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
.index_times_scale_plus_displacement {
|
.index_times_scale_plus_displacement {
|
||||||
g.asm_arg(displacement, stmt)
|
if displacement is ast.AsmDisp {
|
||||||
g.write('(')
|
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.asm_arg(index, stmt)
|
||||||
g.write(',$scale)')
|
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] {
|
for p.tok.kind !in [.semicolon, .rcbr] {
|
||||||
template_pos := p.tok.position()
|
template_pos := p.tok.position()
|
||||||
mut name := ''
|
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
|
is_directive := p.tok.kind == .dot
|
||||||
if is_directive {
|
if is_directive {
|
||||||
p.next()
|
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.
|
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()
|
p.next()
|
||||||
} 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 {
|
} else {
|
||||||
name = p.tok.lit
|
name += p.tok.lit
|
||||||
p.check(.name)
|
p.check(.name)
|
||||||
}
|
}
|
||||||
// dots are part of instructions for some riscv extensions
|
// 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 {
|
for p.tok.kind == .dot {
|
||||||
name += '.'
|
name += '.'
|
||||||
p.next()
|
p.next()
|
||||||
@ -949,8 +959,9 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
if is_directive || number_lit.val.ends_with('b')
|
if (is_directive || number_lit.val.ends_with('b')
|
||||||
|| number_lit.val.ends_with('f') {
|
|| number_lit.val.ends_with('f'))
|
||||||
|
&& !number_lit.val.starts_with('0x') {
|
||||||
args << ast.AsmDisp{
|
args << ast.AsmDisp{
|
||||||
val: number_lit.val
|
val: number_lit.val
|
||||||
pos: number_lit.pos
|
pos: number_lit.pos
|
||||||
@ -1217,11 +1228,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
}
|
}
|
||||||
} else if p.tok.kind == .number {
|
} else if p.tok.kind == .number {
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -1241,11 +1253,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
p.next()
|
p.next()
|
||||||
|
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -1262,11 +1275,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
if p.peek_tok.kind == .rsbr {
|
if p.peek_tok.kind == .rsbr {
|
||||||
if p.tok.kind == .number {
|
if p.tok.kind == .number {
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -1288,11 +1302,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
p.check(.number)
|
p.check(.number)
|
||||||
p.check(.plus)
|
p.check(.plus)
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -1308,11 +1323,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
} else if p.tok.kind == .plus {
|
} else if p.tok.kind == .plus {
|
||||||
p.next()
|
p.next()
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -1333,11 +1349,12 @@ fn (mut p Parser) asm_addressing() ast.AsmAddressing {
|
|||||||
p.check(.number)
|
p.check(.number)
|
||||||
p.check(.plus)
|
p.check(.plus)
|
||||||
displacement := if p.tok.kind == .name {
|
displacement := if p.tok.kind == .name {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
p.reg_or_alias()
|
||||||
p.next()
|
|
||||||
x
|
|
||||||
} else {
|
} else {
|
||||||
x := ast.AsmArg(p.tok.lit)
|
x := ast.AsmArg(ast.AsmDisp{
|
||||||
|
val: p.tok.lit
|
||||||
|
pos: p.tok.position()
|
||||||
|
})
|
||||||
p.check(.number)
|
p.check(.number)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ fn test_inline_asm() {
|
|||||||
asm amd64 {
|
asm amd64 {
|
||||||
movq [m], 7 // have to specify size with q
|
movq [m], 7 // have to specify size with q
|
||||||
; ; r (m)
|
; ; r (m)
|
||||||
|
; memory
|
||||||
}
|
}
|
||||||
assert l == 7
|
assert l == 7
|
||||||
|
|
||||||
@ -98,15 +99,15 @@ fn test_inline_asm() {
|
|||||||
|
|
||||||
assert util.add(8, 9, 34, 7) == 58 // test .amd64.v imported files
|
assert util.add(8, 9, 34, 7) == 58 // test .amd64.v imported files
|
||||||
|
|
||||||
mut manu := Manu{}
|
mut o := Manu{}
|
||||||
asm amd64 {
|
asm amd64 {
|
||||||
mov eax, 0
|
mov eax, 0
|
||||||
cpuid
|
cpuid
|
||||||
; =b (manu.ebx) as ebx0
|
; =b (o.ebx) as ebx0
|
||||||
=d (manu.edx) as edx0
|
=d (o.edx) as edx0
|
||||||
=c (manu.ecx) as ecx0
|
=c (o.ecx) as ecx0
|
||||||
}
|
}
|
||||||
manu.str()
|
o.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
[packed]
|
[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
|
// 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() {
|
fn test_rip_relative_label() {
|
||||||
mut a := i64(4)
|
$if !macos {
|
||||||
asm amd64 {
|
mut a := i64(4)
|
||||||
mov a, [rip + one_two_three] // see below
|
asm amd64 {
|
||||||
; =r (a)
|
mov a, [rip + one_two_three] // see below
|
||||||
|
; =r (a)
|
||||||
|
}
|
||||||
|
assert a == 48321074923
|
||||||
}
|
}
|
||||||
assert a == 48321074923
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asm amd64 {
|
$if !macos {
|
||||||
.global one_two_three
|
asm amd64 {
|
||||||
one_two_three:
|
.global one_two_three
|
||||||
.quad 48321074923
|
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() {
|
fn test_flag_output() {
|
||||||
|
Loading…
Reference in New Issue
Block a user