parser: add support for flags in asm output constraints (#10103)

pull/10106/head
crthpl 2021-05-14 02:01:15 -07:00 committed by GitHub
parent a849d52d4a
commit 4273a9697e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 29 deletions

View File

@ -1180,7 +1180,7 @@ pub mut:
pub struct AsmIO { pub struct AsmIO {
pub: pub:
alias string // [alias_a] alias string // [alias_a]
constraint string // '=r' constraint string // '=r' TODO: allow all backends to easily use this with a struct
expr Expr // (a) expr Expr // (a)
comments []Comment // // this is a comment comments []Comment // // this is a comment
typ Type typ Type

View File

@ -727,6 +727,9 @@ fn (mut f Fmt) asm_stmt(stmt ast.AsmStmt) {
} }
f.indent-- f.indent--
f.writeln('}') f.writeln('}')
if stmt.is_top_level {
f.writeln('')
}
} }
fn (mut f Fmt) asm_arg(arg ast.AsmArg) { fn (mut f Fmt) asm_arg(arg ast.AsmArg) {

View File

@ -1383,16 +1383,13 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO {
if constraint != '' { if constraint != '' {
p.next() p.next()
} }
if p.tok.kind == .assign {
constraint += '='
p.next()
} else if p.tok.kind == .plus {
constraint += '+'
p.next()
}
constraint += p.tok.lit constraint += p.tok.lit
if p.tok.kind == .at {
p.next()
} else {
p.check(.name) p.check(.name)
} }
}
mut expr := p.expr(0) mut expr := p.expr(0)
if mut expr is ast.ParExpr { if mut expr is ast.ParExpr {
expr = expr.expr expr = expr.expr

View File

@ -873,7 +873,7 @@ fn (mut s Scanner) text_scan() token.Token {
return s.new_token(.name, '@' + name, name.len + 1) return s.new_token(.name, '@' + name, name.len + 1)
} }
// @FN, @STRUCT, @MOD etc. See full list in token.valid_at_tokens // @FN, @STRUCT, @MOD etc. See full list in token.valid_at_tokens
if '@' + name in token.valid_at_tokens { if '@' + name in token.valid_at_tokens || name.starts_with('cc') { // `=@cccond` in inline assembly
return s.new_token(.at, '@' + name, name.len + 1) return s.new_token(.at, '@' + name, name.len + 1)
} }
if !token.is_key(name) { if !token.is_key(name) {

View File

@ -136,13 +136,6 @@ fn test_rip_relative_label() {
; =r (a) ; =r (a)
} }
assert a == 48321074923 assert a == 48321074923
mut b := i64(4)
asm amd64 {
mov b, one_two_three // see below
; =r (b)
}
assert b == 48321074923
} }
asm amd64 { asm amd64 {
@ -150,3 +143,30 @@ asm amd64 {
one_two_three: one_two_three:
.quad 48321074923 .quad 48321074923
} }
fn test_flag_output() {
a, b := 4, 9
mut out := false
asm amd64 {
cmp a, b
; =@ccl (out)
; r (a)
r (b)
}
assert out
asm amd64 {
cmp b, a
; =@ccl (out)
; r (a)
r (b)
}
assert !out
zero := 0
asm amd64 {
cmp zero, zero
; =@ccz (out)
; r (zero)
}
assert out
}

View File

@ -125,3 +125,30 @@ fn (m Manu) str() string {
} }
} }
} }
fn test_flag_output() {
a, b := 4, 9
mut out := false
asm amd64 {
cmp a, b
; =@ccl (out)
; r (a)
r (b)
}
assert out
asm amd64 {
cmp b, a
; =@ccl (out)
; r (a)
r (b)
}
assert !out
zero := 0
asm amd64 {
cmp zero, zero
; =@ccz (out)
; r (zero)
}
assert out
}

View File

@ -10,23 +10,22 @@ const (
) )
fn test_return_lock() { fn test_return_lock() {
shared s := AA{'3'}
go printer(shared s)
go fn (shared s AA) {
start := time.now() start := time.now()
shared s := AA{'3'}
go printer(shared s, start)
go fn (shared s AA, start time.Time) {
for { for {
reader(shared s) reader(shared s)
if time.now() - start > sleep_time { if time.now() - start > sleep_time {
exit(0) exit(0)
} }
} }
}(shared s) }(shared s, start)
time.sleep(sleep_time * 2) time.sleep(sleep_time * 2)
assert false assert false
} }
fn printer(shared s AA) { fn printer(shared s AA, start time.Time) {
start := time.now()
for { for {
lock s { lock s {
assert s.b in ['0', '1', '2', '3', '4', '5'] assert s.b in ['0', '1', '2', '3', '4', '5']

View File

@ -10,23 +10,22 @@ const (
) )
fn test_return_lock() { fn test_return_lock() {
shared s := AA{'3'}
go printer(shared s)
go fn (shared s AA) {
start := time.now() start := time.now()
shared s := AA{'3'}
go printer(shared s, start)
go fn (shared s AA, start time.Time) {
for { for {
reader(shared s) reader(shared s)
if time.now() - start > sleep_time { if time.now() - start > sleep_time {
exit(0) exit(0)
} }
} }
}(shared s) }(shared s, start)
time.sleep(sleep_time * 2) time.sleep(sleep_time * 2)
assert false assert false
} }
fn printer(shared s AA) { fn printer(shared s AA, start time.Time) {
start := time.now()
for { for {
lock s { lock s {
assert s.b in ['0', '1', '2', '3', '4', '5'] assert s.b in ['0', '1', '2', '3', '4', '5']