Skip to content

Commit 1f80b2f

Browse files
authored
Parse label-based addressing (#2028)
1 parent f21a783 commit 1f80b2f

File tree

3 files changed

+106
-20
lines changed

3 files changed

+106
-20
lines changed

src/Assembly/Parse.v

+103-17
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,26 @@ Definition parse_label : ParserAction string
8080
(fun '(char, ls) => string_of_list_ascii (char :: ls))
8181
(([a-zA-Z] || parse_any_ascii "._?$") ;;
8282
(([a-zA-Z] || parse_any_ascii "0123456789_$#@~.?")* )).
83+
Definition parse_non_access_size_label : ParserAction string
84+
:= parse_lookahead_not parse_AccessSize ;;R parse_label.
8385

8486
Definition parse_MEM : ParserAction MEM
85-
:= parse_map
86-
(fun '(access_size, (br (*base reg*), sr (*scale reg, including z *), offset, base_label))
87-
=> {| mem_bits_access_size := access_size:option AccessSize
88-
; mem_base_reg := br:option REG
89-
; mem_base_label := base_label
90-
; mem_scale_reg := sr:option (Z * REG)
91-
; mem_offset := offset:option Z |})
87+
:= parse_option_list_map
88+
(fun '(access_size, (constant_location_label, (br (*base reg*), sr (*scale reg, including z *), offset, base_label)))
89+
=> match base_label, constant_location_label with
90+
| Some _, Some _ => (* invalid? *) None
91+
| Some _ as lbl, None
92+
| None, Some _ as lbl
93+
| None, None as lbl =>
94+
Some
95+
{| mem_bits_access_size := access_size:option AccessSize
96+
; mem_base_reg := br:option REG
97+
; mem_base_label := lbl
98+
; mem_scale_reg := sr:option (Z * REG)
99+
; mem_offset := offset:option Z |}
100+
end)
92101
(((strip_whitespace_after parse_AccessSize)?) ;;
102+
(parse_non_access_size_label?) ;;
93103
(parse_option_list_map
94104
(fun '(offset, vars)
95105
=> (vars <-- List.map (fun '(c, (v, e), vs) => match vs, e with [], 1%Z => Some (c, v) | _, _ => None end) vars;
@@ -281,11 +291,21 @@ Global Instance show_lvl_MEM : ShowLevel MEM
281291
then "0x08 * " ++ Decimal.show_Z (offset / 8)
282292
else Hex.show_Z offset)
283293
end%Z) in
284-
"[" ++ match m.(mem_base_label) with
285-
| None => reg_part ++ offset_part
286-
| Some l => "((" ++ l ++ offset_part ++ "))"
287-
end
288-
++ "]").
294+
match m.(mem_base_label), m.(mem_base_reg), m.(mem_offset), m.(mem_scale_reg) with
295+
| Some lbl, Some rip, None, None => lbl ++ "[" ++ reg_part ++ offset_part ++ "]"
296+
| Some lbl, _, _, _ => let l_offset := lbl ++ offset_part in
297+
"[" ++
298+
(if reg_part =? ""
299+
then "((" ++ l_offset ++ "))"
300+
else reg_part ++ " + " ++ l_offset)
301+
++ "]"
302+
| None, _, _, _ =>
303+
"[" ++
304+
(if reg_part =? ""
305+
then "((" ++ offset_part ++ "))"
306+
else reg_part ++ offset_part)
307+
++ "]"
308+
end).
289309
Global Instance show_MEM : Show MEM := show_lvl_MEM.
290310

291311
Global Instance show_lvl_JUMP_LABEL : ShowLevel JUMP_LABEL
@@ -505,20 +525,86 @@ Definition find_globals (ls : Lines) : list string
505525
end)
506526
ls.
507527

508-
Fixpoint split_code_to_functions' (globals : list string) (ls : Lines) : Lines (* prefix *) * list (string (* global name *) * Lines)
528+
Definition find_labels (ls : Lines) : list string
529+
:= Option.List.map
530+
(fun l => match l.(rawline) with
531+
| LABEL name => Some name
532+
| _ => None
533+
end)
534+
ls.
535+
536+
Fixpoint split_code_to_functions' (label_is_function : string -> bool) (ls : Lines) : Lines (* prefix *) * list (string (* global name *) * Lines)
509537
:= match ls with
510538
| [] => ([], [])
511539
| l :: ls
512-
=> let '(prefix, rest) := split_code_to_functions' globals ls in
540+
=> let '(prefix, rest) := split_code_to_functions' label_is_function ls in
513541
let default := (l :: prefix, rest) in
514542
match l.(rawline) with
515-
| LABEL name => if List.existsb (fun n => name =? n)%string globals
543+
| LABEL name => if label_is_function name
516544
then ([], (name, l::prefix) :: rest)
517545
else default
518546
| _ => default
519547
end
520548
end.
521549

522-
Definition split_code_to_functions (ls : Lines) : Lines (* prefix *) * list (string (* global name *) * Lines)
550+
Definition string_matches_loose (allow_prefix : bool) (allow_suffix : bool) (longer_string shorter_string : string) : bool
551+
:= match allow_prefix, allow_suffix with
552+
| false, false => shorter_string =? longer_string
553+
| true, false => String.endswith shorter_string longer_string
554+
| false, true => String.startswith shorter_string longer_string
555+
| true, true => String.is_substring shorter_string longer_string
556+
end.
557+
Definition split_code_to_listed_functions {allow_prefix allow_suffix : bool} (functions : list string) (ls : Lines) : Lines (* prefix *) * list (string (* global name *) * Lines)
558+
:= split_code_to_functions' (fun name => List.existsb (fun f => string_matches_loose allow_prefix allow_suffix f name)%string functions) ls.
559+
Definition split_code_to_global_functions (ls : Lines) : Lines (* prefix *) * list (string (* global name *) * Lines)
523560
:= let globals := find_globals ls in
524-
split_code_to_functions' globals ls.
561+
split_code_to_listed_functions (allow_prefix:=false) (allow_suffix:=false) globals ls.
562+
Definition split_code_at_labels (ls : Lines) : Lines (* prefix *) * list (string (* label name *) * Lines)
563+
:= let labels := find_labels ls in
564+
split_code_to_listed_functions (allow_prefix:=false) (allow_suffix:=false) labels ls.
565+
566+
Fixpoint get_initial_data (ls : Lines) : list (AccessSize * list Z)
567+
:= let get_arg_consts args :=
568+
Option.List.lift
569+
(List.map (fun arg => match arg with
570+
| const c => Some c
571+
| _ => None
572+
end)
573+
args) in
574+
match ls with
575+
| [] => []
576+
| l :: ls
577+
=> match l.(rawline) with
578+
| INSTR instr =>
579+
match accesssize_of_declaration instr.(op) with
580+
| None => []
581+
| Some size =>
582+
let csts := get_arg_consts instr.(args) in
583+
match csts with
584+
| Some csts => (size, csts) :: get_initial_data ls
585+
| None => []
586+
end
587+
end
588+
| LABEL _
589+
| EMPTY
590+
| GLOBAL _
591+
| DEFAULT_REL
592+
=> get_initial_data ls
593+
| SECTION _
594+
| ALIGN _
595+
=> []
596+
end
597+
end.
598+
599+
Definition get_labeled_data (ls : Lines) : list (string * list (AccessSize * list Z)) :=
600+
let '(_, labeled_data) := split_code_at_labels ls in
601+
let labeled_data := List.map (fun '(lbl, lines) => (lbl, get_initial_data lines)) labeled_data in
602+
let labeled_data := List.filter (fun '(_, data) => match data with nil => false | _ => true end) labeled_data in
603+
labeled_data.
604+
605+
Definition parse_assembly_options (ls : Lines) : assembly_program_options
606+
:= {| default_rel := Option.is_Some (List.find (fun l => match l.(rawline) with
607+
| DEFAULT_REL => true
608+
| _ => false
609+
end) ls)
610+
|}.

src/PushButtonSynthesis/Primitives.v

+1-1
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ Section __.
12881288
| Error err => Error (Pipeline.Assembly_parsing_error fname err)
12891289
| Success v
12901290
=> (vs <- parse_asm_files_lines ls;
1291-
Success ((fname, Assembly.Parse.split_code_to_functions v) :: vs))
1291+
Success ((fname, Assembly.Parse.split_code_to_global_functions v) :: vs))
12921292
end
12931293
end%error.
12941294

src/StandaloneDebuggingExamples.v

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Import ListNotations. Local Open Scope string_scope.
99

1010
Module debugging_no_asm.
1111
Import StandaloneOCamlMain.UnsaturatedSolinas.
12-
Import ZArith.
12+
Import Coq.ZArith.ZArith.
1313
Open Scope Z_scope.
1414
Goal True.
1515
pose main as v.
@@ -73,7 +73,7 @@ Module debugging_no_asm.
7373
cbv beta iota in v.
7474
vm_compute Parse.parse_validated in v.
7575
cbv beta iota in v.
76-
vm_compute Parse.split_code_to_functions in v.
76+
vm_compute Parse.split_code_to_global_functions in v.
7777
cbv beta iota in v.
7878
set (k := map _ _) in (value of v) at 1.
7979
cbn [map] in k.

0 commit comments

Comments
 (0)