Skip to content

Commit

Permalink
parser: add support for flags in asm output constraints (#10103)
Browse files Browse the repository at this point in the history
  • Loading branch information
crthpl committed May 14, 2021
1 parent a849d52 commit 4273a96
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 28 deletions.
2 changes: 1 addition & 1 deletion vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ pub mut:
pub struct AsmIO {
pub:
alias string // [alias_a]
constraint string // '=r'
constraint string // '=r' TODO: allow all backends to easily use this with a struct
expr Expr // (a)
comments []Comment // // this is a comment
typ Type
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,9 @@ fn (mut f Fmt) asm_stmt(stmt ast.AsmStmt) {
}
f.indent--
f.writeln('}')
if stmt.is_top_level {
f.writeln('')
}
}

fn (mut f Fmt) asm_arg(arg ast.AsmArg) {
Expand Down
11 changes: 4 additions & 7 deletions vlib/v/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -1383,15 +1383,12 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO {
if constraint != '' {
p.next()
}
if p.tok.kind == .assign {
constraint += '='
p.next()
} else if p.tok.kind == .plus {
constraint += '+'
constraint += p.tok.lit
if p.tok.kind == .at {
p.next()
} else {
p.check(.name)
}
constraint += p.tok.lit
p.check(.name)
}
mut expr := p.expr(0)
if mut expr is ast.ParExpr {
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/scanner/scanner.v
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ fn (mut s Scanner) text_scan() token.Token {
return s.new_token(.name, '@' + name, name.len + 1)
}
// @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)
}
if !token.is_key(name) {
Expand Down
34 changes: 27 additions & 7 deletions vlib/v/tests/assembly/asm_test.amd64.v
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,37 @@ fn test_rip_relative_label() {
; =r (a)
}
assert a == 48321074923

mut b := i64(4)
asm amd64 {
mov b, one_two_three // see below
; =r (b)
}
assert b == 48321074923
}

asm amd64 {
.global one_two_three
one_two_three:
.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
}
27 changes: 27 additions & 0 deletions vlib/v/tests/assembly/asm_test.i386.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
11 changes: 5 additions & 6 deletions vlib/v/tests/break_in_lock_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@ const (
)

fn test_return_lock() {
start := time.now()
shared s := AA{'3'}
go printer(shared s)
go fn (shared s AA) {
start := time.now()
go printer(shared s, start)
go fn (shared s AA, start time.Time) {
for {
reader(shared s)
if time.now() - start > sleep_time {
exit(0)
}
}
}(shared s)
}(shared s, start)
time.sleep(sleep_time * 2)
assert false
}

fn printer(shared s AA) {
start := time.now()
fn printer(shared s AA, start time.Time) {
for {
lock s {
assert s.b in ['0', '1', '2', '3', '4', '5']
Expand Down
11 changes: 5 additions & 6 deletions vlib/v/tests/return_in_lock_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@ const (
)

fn test_return_lock() {
start := time.now()
shared s := AA{'3'}
go printer(shared s)
go fn (shared s AA) {
start := time.now()
go printer(shared s, start)
go fn (shared s AA, start time.Time) {
for {
reader(shared s)
if time.now() - start > sleep_time {
exit(0)
}
}
}(shared s)
}(shared s, start)
time.sleep(sleep_time * 2)
assert false
}

fn printer(shared s AA) {
start := time.now()
fn printer(shared s AA, start time.Time) {
for {
lock s {
assert s.b in ['0', '1', '2', '3', '4', '5']
Expand Down

0 comments on commit 4273a96

Please sign in to comment.