From d6e7a526ee315cb33ad1ee9fe8969bd643b3b8f4 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Tue, 2 Jan 2024 02:06:59 +0100 Subject: [PATCH] fmt & refactor --- flap/src/x86-64/retrolixToX86_64.ml | 98 +++++++++++++++++------------ 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/flap/src/x86-64/retrolixToX86_64.ml b/flap/src/x86-64/retrolixToX86_64.ml index d5f77d6..2712dad 100644 --- a/flap/src/x86-64/retrolixToX86_64.ml +++ b/flap/src/x86-64/retrolixToX86_64.ml @@ -479,10 +479,12 @@ module InstructionSelector : InstructionSelector = struct let div ~dst ~srcl ~srcr = (* Division *) let rax = `Reg X86_64_Architecture.RAX in + (* Dividende dans RAX et diviseur dans R15 *) mov ~src:srcl ~dst:rax @ mov ~src:srcr ~dst:r15 - @ [ Instruction cqto; Instruction (idivq ~src:r15)] - @ mov ~dst ~src:rax + (* Division avec signe *) + @ [ Instruction cqto; Instruction (idivq ~src:r15) ] + @ mov ~dst ~src:rax ;; let andl ~dst ~srcl ~srcr = @@ -531,67 +533,83 @@ module FrameManager (IS : InstructionSelector) : FrameManager = struct space after the function prologue. *) let stack_usage_after_prologue fd = 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 + ;; - (* 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 = fst (List.fold_left (fun (stack, addr) id -> S.IdMap.add id (Mint.of_int addr) stack, op_addr addr) (stack, start) 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 = - match S.IdMap.find_opt id fd.stack_map with - (* 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;} - (* Sinon, variable globale*) - | None -> {offset = Some (Lab (data_label_of_global id)); base = Some (RIP); idx = None; scale = `One;} + (* 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 } + (* Sinon, variable globale *) + | 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 = - (*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*) - (*Instruction 2 : On initialise la base de la pile en mettant rsp au niveau de rbp*) - [Instruction (pushq ~src:rbp);Instruction (movq ~src:rsp ~dst:rbp)] - - (*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.*) - [Instruction (subq ~src:(liti fd.locals_space) ~dst:rsp)] + (* On pousse rbp sur la pile, + pour sauvegarder la valeur actuelle de la base de la pile, + permet de revenir là où on en était quand on dépilera à la fin *) + [ T.Instruction (T.pushq ~src:rbp) + ; (* On initialise la base de la pile en mettant rsp au niveau de rbp *) + T.Instruction (T.movq ~src:rsp ~dst:rbp) + ] + @ + (* 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 [] ;; let function_epilogue fd = - let remontage = - (*Si de l'espace a été alloué pour les variables locales, on ajoute des instructiosn pour remonter la pile (vers le haut) avec addq*) - if fd.locals_space <> 0 then - [Instruction (addq ~src:(liti fd.locals_space) ~dst:rsp)] - else [] - in - remontage @ [Instruction (popq ~dst:rbp)] (*Pour restaurer l'état de la pile, on effectue un popq ("l'inverse" de pushq du prologue)*) - + (* Si de l'espace a été alloué pour les variables locales, + on ajoute des instructions pour remonter la pile (vers le haut) + avec addq ("l'inverse" du subq du prologue) *) + (if fd.locals_space <> 0 + then [ T.Instruction (T.addq ~src:(T.liti fd.locals_space) ~dst:rsp) ] + else []) + @ (* 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 = - (* TODO *) + (* TODO : Il faut empiler les arguments ? *) (* Appelle la fonction *) [ T.Instruction (T.calldi ~tgt:f) ] ;;