fmt & refactor
This commit is contained in:
parent
f86829dd3a
commit
d6e7a526ee
1 changed files with 58 additions and 40 deletions
|
@ -479,10 +479,12 @@ module InstructionSelector : InstructionSelector = struct
|
||||||
let div ~dst ~srcl ~srcr =
|
let div ~dst ~srcl ~srcr =
|
||||||
(* Division *)
|
(* Division *)
|
||||||
let rax = `Reg X86_64_Architecture.RAX in
|
let rax = `Reg X86_64_Architecture.RAX in
|
||||||
|
(* Dividende dans RAX et diviseur dans R15 *)
|
||||||
mov ~src:srcl ~dst:rax
|
mov ~src:srcl ~dst:rax
|
||||||
@ mov ~src:srcr ~dst:r15
|
@ mov ~src:srcr ~dst:r15
|
||||||
@ [ Instruction cqto; Instruction (idivq ~src:r15)]
|
(* Division avec signe *)
|
||||||
@ mov ~dst ~src:rax
|
@ [ Instruction cqto; Instruction (idivq ~src:r15) ]
|
||||||
|
@ mov ~dst ~src:rax
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let andl ~dst ~srcl ~srcr =
|
let andl ~dst ~srcl ~srcr =
|
||||||
|
@ -531,67 +533,83 @@ module FrameManager (IS : InstructionSelector) : FrameManager = struct
|
||||||
space after the function prologue. *)
|
space after the function prologue. *)
|
||||||
let stack_usage_after_prologue fd =
|
let stack_usage_after_prologue fd =
|
||||||
Mint.size_in_bytes
|
Mint.size_in_bytes
|
||||||
+ ((if empty_frame fd then 0 else 1) * Mint.size_in_bytes)
|
(* Cas où il n'y a 0 arguments et variable locales *)
|
||||||
|
+ (if empty_frame fd then 0 else Mint.size_in_bytes)
|
||||||
|
(* Taille variables locales *)
|
||||||
+ fd.locals_space
|
+ fd.locals_space
|
||||||
|
;;
|
||||||
|
|
||||||
(* Ajoute les éléments de liste sur la pile *)
|
(** Ajoute les éléments de liste sur la pile *)
|
||||||
let add_stack stack list start op_addr =
|
let add_stack stack list start op_addr =
|
||||||
fst
|
fst
|
||||||
(List.fold_left
|
(List.fold_left
|
||||||
(fun (stack, addr) id -> S.IdMap.add id (Mint.of_int addr) stack, op_addr addr)
|
(fun (stack, addr) id -> S.IdMap.add id (Mint.of_int addr) stack, op_addr addr)
|
||||||
(stack, start)
|
(stack, start)
|
||||||
list)
|
list)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let frame_descriptor ~params ~locals =
|
|
||||||
(*Ajout des variables locals d'abord. ON commence à la position -8 dans la pile vide, on décroit l'adresse de 8 à chaque nouvelle valeur*)
|
|
||||||
let stack = add_stack S.IdMap.empty locals (-8) (fun x -> x - 8) in
|
|
||||||
(* Ajout des variables global ensuite. ON reprend la même pile, on commence à l'adresse 16 et on ajoute l'adresse qui suit de 8 *)
|
|
||||||
let stack = add_stack stack params 16 (fun x -> x + 8) in
|
|
||||||
(* ON créé le frame descriptor ensuite*)
|
|
||||||
{param_count = List.length params; locals_space = (List.length locals) * 8; stack_map = stack; }
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
let frame_descriptor ~params ~locals =
|
||||||
|
(* Ajout des variables locals d'abord.
|
||||||
|
On commence à la position -8 dans la pile vide,
|
||||||
|
on décroit l'adresse de 8 à chaque nouvelle valeur *)
|
||||||
|
let stack = add_stack S.IdMap.empty locals (-8) (fun x -> x - 8) in
|
||||||
|
(* Ajout des variables global ensuite.
|
||||||
|
On reprend la même pile, on commence à l'adresse 16
|
||||||
|
et on ajoute l'adresse qui suit de 8 *)
|
||||||
|
let stack = add_stack stack params 16 (fun x -> x + 8) in
|
||||||
|
(* On créé le frame descriptor ensuite *)
|
||||||
|
{ param_count = List.length params
|
||||||
|
; locals_space = List.length locals * 8
|
||||||
|
; stack_map = stack
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
|
||||||
let location_of fd id : T.address =
|
let location_of fd id : T.address =
|
||||||
|
|
||||||
match S.IdMap.find_opt id fd.stack_map with
|
match S.IdMap.find_opt id fd.stack_map with
|
||||||
(* Si on retrouve id dans la stack map, alors c'est une variable locale*)
|
(* Si on retrouve id dans la stack map, alors c'est une variable locale *)
|
||||||
| Some o -> {offset = Some (Lit o); base = Some (RBP); idx = None; scale = `One;}
|
| Some o -> { offset = Some (Lit o); base = Some RBP; idx = None; scale = `One }
|
||||||
(* Sinon, variable globale*)
|
(* Sinon, variable globale *)
|
||||||
| None -> {offset = Some (Lab (data_label_of_global id)); base = Some (RIP); idx = None; scale = `One;}
|
| None ->
|
||||||
|
{ offset = Some (Lab (data_label_of_global id))
|
||||||
|
; base = Some RIP
|
||||||
|
; idx = None
|
||||||
|
; scale = `One
|
||||||
|
}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
open T (* Necessaire pour pouvoir créer des instructions*)
|
|
||||||
let function_prologue fd =
|
let function_prologue fd =
|
||||||
(*Instruction 1 : On pousse rbp sur la pile, pour sauvegarder la valeur actuelle de la base de la pile, quand on dépilera à la fin*)
|
(* On pousse rbp sur la pile,
|
||||||
(*Instruction 2 : On initialise la base de la pile en mettant rsp au niveau de rbp*)
|
pour sauvegarder la valeur actuelle de la base de la pile,
|
||||||
[Instruction (pushq ~src:rbp);Instruction (movq ~src:rsp ~dst:rbp)]
|
permet de revenir là où on en était quand on dépilera à la fin *)
|
||||||
|
[ T.Instruction (T.pushq ~src:rbp)
|
||||||
(*On ajoute de l'espace pour les futurs variables locales. On regarde combien il y en a dans le frame descriptor*)
|
; (* On initialise la base de la pile en mettant rsp au niveau de rbp *)
|
||||||
@ if fd.locals_space <> 0 then
|
T.Instruction (T.movq ~src:rsp ~dst:rbp)
|
||||||
(*On va faire des subq (descendre la pile vers le bas) pour pouvoir y mettre les variables locales.*)
|
]
|
||||||
[Instruction (subq ~src:(liti fd.locals_space) ~dst:rsp)]
|
@
|
||||||
|
(* On ajoute de l'espace pour les futurs variables locales.
|
||||||
|
On regarde combien il y en a dans le frame descriptor *)
|
||||||
|
if fd.locals_space <> 0
|
||||||
|
then
|
||||||
|
(* On va faire des subq (descendre la pile vers le bas)
|
||||||
|
pour pouvoir y mettre les variables locales. *)
|
||||||
|
[ T.Instruction (T.subq ~src:(T.liti fd.locals_space) ~dst:rsp) ]
|
||||||
else []
|
else []
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let function_epilogue fd =
|
let function_epilogue fd =
|
||||||
let remontage =
|
(* Si de l'espace a été alloué pour les variables locales,
|
||||||
(*Si de l'espace a été alloué pour les variables locales, on ajoute des instructiosn pour remonter la pile (vers le haut) avec addq*)
|
on ajoute des instructions pour remonter la pile (vers le haut)
|
||||||
if fd.locals_space <> 0 then
|
avec addq ("l'inverse" du subq du prologue) *)
|
||||||
[Instruction (addq ~src:(liti fd.locals_space) ~dst:rsp)]
|
(if fd.locals_space <> 0
|
||||||
else []
|
then [ T.Instruction (T.addq ~src:(T.liti fd.locals_space) ~dst:rsp) ]
|
||||||
in
|
else [])
|
||||||
remontage @ [Instruction (popq ~dst:rbp)] (*Pour restaurer l'état de la pile, on effectue un popq ("l'inverse" de pushq du prologue)*)
|
@ (* Pour restaurer l'état de la pile,
|
||||||
|
on effectue un popq ("l'inverse" de pushq du prologue) *)
|
||||||
|
[ T.Instruction (T.popq ~dst:rbp) ]
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let call fd ~kind ~f ~args =
|
let call fd ~kind ~f ~args =
|
||||||
(* TODO *)
|
(* TODO : Il faut empiler les arguments ? *)
|
||||||
(* Appelle la fonction *)
|
(* Appelle la fonction *)
|
||||||
[ T.Instruction (T.calldi ~tgt:f) ]
|
[ T.Instruction (T.calldi ~tgt:f) ]
|
||||||
;;
|
;;
|
||||||
|
|
Reference in a new issue