add locals initialization

This commit is contained in:
danyabeerzun 2018-12-12 12:42:38 +03:00
parent 576beac0dc
commit 516a3e190b

View file

@ -54,6 +54,7 @@ type instr =
(* arithmetic correction: or 0x0001 *) | Or1 of opnd (* arithmetic correction: or 0x0001 *) | Or1 of opnd
(* arithmetic correction: shl 1 *) | Sal1 of opnd (* arithmetic correction: shl 1 *) | Sal1 of opnd
(* arithmetic correction: shr 1 *) | Sar1 of opnd (* arithmetic correction: shr 1 *) | Sar1 of opnd
| Repmovsl
(* Instruction printer *) (* Instruction printer *)
let show instr = let show instr =
@ -93,6 +94,7 @@ let show instr =
| Or1 s -> Printf.sprintf "\torl\t$0x0001,\t%s" (opnd s) | Or1 s -> Printf.sprintf "\torl\t$0x0001,\t%s" (opnd s)
| Sal1 s -> Printf.sprintf "\tsall\t%s" (opnd s) | Sal1 s -> Printf.sprintf "\tsall\t%s" (opnd s)
| Sar1 s -> Printf.sprintf "\tsarl\t%s" (opnd s) | Sar1 s -> Printf.sprintf "\tsarl\t%s" (opnd s)
| Repmovsl -> Printf.sprintf "\trep movsl\t"
(* Opening stack machine to use instructions without fully qualified names *) (* Opening stack machine to use instructions without fully qualified names *)
open SM open SM
@ -290,14 +292,20 @@ let compile env code =
| BEGIN (f, a, l) -> | BEGIN (f, a, l) ->
let env = env#enter f a l in let env = env#enter f a l in
env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp)] env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp);
Mov (esp, edi);
Mov (M "$filler", esi);
Mov (M ("$" ^ (env#allocated_size)), ecx);
Repmovsl
]
| END -> | END ->
env, [Label env#epilogue; env#endfunc, [Label env#epilogue;
Mov (ebp, esp); Mov (ebp, esp);
Pop ebp; Pop ebp;
Ret; Ret;
Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size)) Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size));
Meta (Printf.sprintf "\t.set\t%s,\t%d" env#allocated_size env#allocated)
] ]
| RET b -> | RET b ->
@ -388,6 +396,14 @@ class env =
val fname = "" (* function name *) val fname = "" (* function name *)
val stackmap = M.empty (* labels to stack map *) val stackmap = M.empty (* labels to stack map *)
val barrier = false (* barrier condition *) val barrier = false (* barrier condition *)
val max_locals_size = 0
method max_locals_size = max_locals_size
method endfunc =
if stack_slots > max_locals_size
then {< max_locals_size = stack_slots >}
else self
method show_stack = method show_stack =
GT.show(list) (GT.show(opnd)) stack GT.show(list) (GT.show(opnd)) stack
@ -483,6 +499,8 @@ class env =
(* gets a number of stack positions allocated *) (* gets a number of stack positions allocated *)
method allocated = stack_slots method allocated = stack_slots
method allocated_size = Printf.sprintf "LS%s_SIZE" fname
(* enters a function *) (* enters a function *)
method enter f a l = method enter f a l =
let n = List.length l in let n = List.length l in
@ -532,7 +550,9 @@ let genasm (ds, stmt) =
((LABEL "main") :: (BEGIN ("main", [], [])) :: SM.compile (ds, stmt)) ((LABEL "main") :: (BEGIN ("main", [], [])) :: SM.compile (ds, stmt))
in in
let gc_start, gc_end = "__gc_data_start", "__gc_data_end" in let gc_start, gc_end = "__gc_data_start", "__gc_data_end" in
let data = [Meta "\t.data"; Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @ let data = [Meta "\t.data";
Meta (Printf.sprintf "filler:\t.fill\t%d, 4, 1" env#max_locals_size);
Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @
[Meta (Printf.sprintf "%s:" gc_start)] @ [Meta (Printf.sprintf "%s:" gc_start)] @
(List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t1" s )) env#globals) @ (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t1" s )) env#globals) @
[Meta (Printf.sprintf "%s:" gc_end)] @ [Meta (Printf.sprintf "%s:" gc_end)] @