Previous Up Next

Module Pentiumframe

module Frame : Frames.FRAME =
   struct
     type register = string 
     let rvTemp.temp = Temp.getnewtemp()
     let fpTemp.temp = Temp.getnewtemp()
     let registers : register list = [ ] (∗ list of register name of the pentium ∗)

     let temp_map = Temp.Table.empty (∗ access ∗)
     let wordsize = 16

     type access = (∗ Not the same as the access of the translate module ∗)
         InFrame of int (∗ (positive/negative) offset from the frame pointer ∗)
       ∣ InReg of Temp.temp

             cf. page 165. needs adjustment
     let external_call ((sargs): (string × Tree.exp list)) = 
       Tree.Call(Tree.Name(Temp.getnamedlabel s), args)

     class frameclass ((n:Temp.label), (flbool list)) = (∗ frames are implemented as objects ∗)
       object (∗ what is missing is: code to implement the view shift + locations of all the formals ∗)
         val mutable counter : int = 0 (∗ to count the locals allocated so far ∗)
             (∗ The formal parameters are counted non-negatively from the frame pointer, starting at the offset 0. ∗)
         val formals_access = 
           snd (List.fold_left 
                   (function (n,al) →
                     (function b → 
                       if b 
                       then ((n+wordsize), al @ [InFrame n])
                       else ((n+wordsize), al @ [InReg (Temp.getnewtemp())])))
                   (0,[ ]) fl)
         val name : Temp.label = n
         method get_newlocal() = countercounter − wordsizecounter (∗ we start at “-1” ∗)
         method formals() : access list = 
           formals_access

         method get_name() : Temp.label = name
       end

     type frame = frameclass

     let new_frame ((name:Temp.label), (formalsbool list)) = 
       new frameclass(nameformals)

     The function formal gives back the “references” to the formal parameters of the corresponding function, i.e., a list of accesses.


     let formals (f:frame) = f#formals() 
     let name (f:frame) = f#get_name()

     let alloc_local (fframeb = (∗ cf. page 137 ∗) 
       (∗ Currently, no locals escape, thus they are all allocate within the frame. ∗)
       InFrame(f#get_newlocal())
     let string (l,s) = ""

     The following is part of the view-shift. Given the naked body of a procedure, it takes care for storing callee-save registers upon procedure entry and restoring them at exit, which is wrapped around the translated body of a procedure. Currently, the transformation does nothing.
     let proc_entry_exit1 (f,(bodyTree.stm)) = body (∗ p. 168/170, dummy ∗)
     let proc_entry_exit2 (fil) = [ ] (∗ p. 208 ∗)
     let proc_entry_exit3 (fil) = ("", [ ], "")

     type frag = Proc of Tree.stm × frame 
       ∣ String of Temp.label × string

     The provided tree expression picks the responsible frame; this is done by the Translate-module in calculating the static links. The function exp calculates the offset within a given frame. This means, when the variable is frame-resident with offset k, the offset is just added to the expression that gives the access to the frame in question.
     let exp (aaccess) (tTree.exp) = (∗ cf. page 156 ∗)
       match a with 
         InFrame(k) → Tree.Mem(Tree.Binop(Tree.PLUSTree.Const kt))
       ∣ InReg(te) → Tree.Temp(te)

     let direct_exp (aaccess) =
       match a with 
         InFrame(k) → Tree.Mem(Tree.Const k)
       ∣ InReg(te) → Tree.Temp(te)

     let string_of_access a = match a with
       InFrame(i) → "in frame(" ^ (string_of_int i) ^")"
     ∣ InReg t → "register(" ^ (Temp.string_of_temp t) ^")"

     let string_of_frame f = 
       (Temp.string_of_label (f#get_name())) ^ "[" ^
       (List.fold_left (function s → (function a → (s ^ "," ^ string_of_access a))) "" (f#formals()))
       ^ "]"

   end

 ,
Previous Up Next