This commit is contained in:
Mylloon 2024-01-02 11:50:39 +01:00
parent f960f9c23b
commit f455643dc0
Signed by: Anri
GPG key ID: A82D63DFF8D1317F

View file

@ -506,8 +506,39 @@ module InstructionSelector : InstructionSelector = struct
;; ;;
let switch ?default ~discriminant ~cases () = let switch ?default ~discriminant ~cases () =
(* TODO *) (* Switch *)
failwith "Students! This is your job! (switch)" let add_default_case =
match default with
| None -> []
| Some ll ->
(* Déplace le discrimant dans R15 *)
[ Instruction (movq ~src:discriminant ~dst:r15)
(* Compare le cas avec R15 (= discriminant)
">=" avec le nombre total des cas *)
; Instruction (cmpq ~src1:(liti (Array.length cases)) ~src2:r15)
(* Si condition est vrai : jump vers le label ll *)
; Instruction (jccl ~cc:AE ~tgt:ll)
]
in
(* Label pour le switch *)
let switch_label = fresh_label () in
(* On vérifie le cas par défaut *)
add_default_case
(* Une case = 8 octets donc on multiplie par 8
et on stocke la position du discriminant dans R15 *)
@ mul ~srcl:discriminant ~srcr:(liti 8) ~dst:r15
(* Charge l'adresse du label du switch dans R15,
avec chaque élément séparer de 4 octets (taille pointeur) *)
@ mov
~src:(`Addr (addr ~offset:(Lab switch_label) ~base:R15 ~scale:`Four ()))
~dst:r15
(* Saute vers l'adresse R15 aka là où on doit mettre le label
et on y met le label du switch *)
@ [ Instruction (jmpi ~tgt:r15)
; Label switch_label
(* Table de saut pour les adresses des autres cas *************)
; Directive (Quad (List.map (fun x -> Lab x) (Array.to_list cases)))
]
;; ;;
end end