@@ -80,16 +80,26 @@ Definition parse_label : ParserAction string
80
80
(fun '(char, ls) => string_of_list_ascii (char :: ls))
81
81
(([a-zA-Z] || parse_any_ascii "._?$") ;;
82
82
(([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.
83
85
84
86
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 )
92
101
(((strip_whitespace_after parse_AccessSize)?) ;;
102
+ (parse_non_access_size_label?) ;;
93
103
(parse_option_list_map
94
104
(fun '(offset, vars)
95
105
=> (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
281
291
then "0x08 * " ++ Decimal.show_Z (offset / 8)
282
292
else Hex.show_Z offset)
283
293
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 ).
289
309
Global Instance show_MEM : Show MEM := show_lvl_MEM.
290
310
291
311
Global Instance show_lvl_JUMP_LABEL : ShowLevel JUMP_LABEL
@@ -505,20 +525,86 @@ Definition find_globals (ls : Lines) : list string
505
525
end )
506
526
ls.
507
527
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)
509
537
:= match ls with
510
538
| [] => ([], [])
511
539
| 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
513
541
let default := (l :: prefix, rest) in
514
542
match l.(rawline) with
515
- | LABEL name => if List.existsb ( fun n => name =? n)%string globals
543
+ | LABEL name => if label_is_function name
516
544
then ([], (name, l::prefix) :: rest)
517
545
else default
518
546
| _ => default
519
547
end
520
548
end .
521
549
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)
523
560
:= 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
+ |}.
0 commit comments