min_caml_startで渡したスタック領域とヒープ領域を利用するようにした
ヒープ領域を何かしらの方法で確保する必要があることに気付いたので、min_caml_start から渡された hp を利用するようにする。あわせて、一緒に渡される sp をスタック領域として利用することにした。
ヒープとレジスタ用のレジスタ番号を以下の通りとし、利用するレジスタ番号まわりも気まぐれにちょっと変更してみた。
sp = x28
hp = x27
(おまけ)tmpレジスタ = x26
code:diff
diff --git a/AArch64/asm.ml b/AArch64/asm.ml
index 9cada30..bec3ab9 100644
--- a/AArch64/asm.ml
+++ b/AArch64/asm.ml
@@ -43,10 +43,12 @@ type prog = Prog of (Id.l * float) list * fundef list * t
let fletd(x, e1, e2) = Let((x, Type.Float), e1, e2)
let seq(e1, e2) = Let((Id.gentmp Type.Unit, Type.Unit), e1, e2)
-(* ひとまず x0 から x16 までを利用して様子を見る *)
+(* fp (x29) と lr(x30) は除外 *)
+(* x28 は sp として、x27 は hp として、x26 は tmp として利用するため除外 *)
let regs = (* Array.init 27 (fun i -> Printf.sprintf "_R_%d" i) *)
- [| "%x0"; "%x1"; "%x2"; "%x5"; "%x6"; "%x7"; "%x8"; "%x9"; "%x10";
- "%x11"; "%x12"; "%x13"; "%x14"; "%x15"; "%x16" |]
+ [| "%x0"; "%x1"; "%x2"; "%x3"; "%x4"; "%x5"; "%x6"; "%x7"; "%x8"; "%x9"; "%x10";
+ "%x11"; "%x12"; "%x13"; "%x14"; "%x15"; "%x16"; "%x17"; "%x18"; "%x19"; "%x20";
+ "%x21"; "%x22"; "%x23"; "%x24"; "%x25"; "%x26"; "%x27"; "%x28" |]
let fregs = Array.init 32 (fun i -> Printf.sprintf "%%f%d" i)
let allregs = Array.to_list regs
let allfregs = Array.to_list fregs
@@ -54,11 +56,11 @@ let reg_cl = regs.(Array.length regs - 1) (* closure address (caml2html: sparcas
let reg_sw = regs.(Array.length regs - 2) (* temporary for swap *)
let reg_fsw = fregs.(Array.length fregs - 1) (* temporary for swap *)
(* AArch64 のスタックポインタは sp *)
-let reg_sp = "%sp" (* stack pointer *)
+let reg_sp = "%x28" (* stack pointer *)
(* PowerPCが4番レジスタを使ってたので、ひとまずそのままで様子を見る *)
-let reg_hp = "%x4" (* heap pointer (caml2html: sparcasm_reghp) *)
+let reg_hp = "%x27" (* heap pointer (caml2html: sparcasm_reghp) *)
(* 特に意図はなく x17 にしてる *)
-let reg_tmp = "%x17" (* XX ad hoc *) +let reg_tmp = "%x26" (* XX ad hoc *) let is_reg x = (x.0 = '%') (* super-tenuki *)
diff --git a/AArch64/emit.ml b/AArch64/emit.ml
index 81c9ac2..13b07bf 100644
--- a/AArch64/emit.ml
+++ b/AArch64/emit.ml
@@ -203,14 +203,14 @@ and g' oc = function (* 各命令のアセンブリ生成 (caml2html: emit_gprim
Printf.fprintf oc "\tmtlr\t%s\n" (reg reg_tmp)
| (NonTail(a), CallDir(Id.L(x), ys, zs)) ->
(* fpとlrをスタックへ退避 *)
- Printf.fprintf oc "\tstp fp, lr, sp, -16!\n"; + Printf.fprintf oc "\tstp fp, lr, %s, -16!\n" (reg reg_sp); g'_args oc [] ys zs;
let ss = stacksize () in
Printf.fprintf oc "\tbl %s\n" x;
(* fpとlrをスタックから復元 *)
- Printf.fprintf oc "\tldp fp, lr, sp, 16\n" + Printf.fprintf oc "\tldp fp, lr, %s, 16\n" (reg reg_sp) and g'_tail_if oc e1 e2 b bn =
let b_else = Id.genid (b ^ "_else") in
Printf.fprintf oc "\t%s %s\n" bn b_else;
@@ -274,8 +274,12 @@ let f oc (Prog(data, fundefs, e)) =
List.iter (fun fundef -> h oc fundef) fundefs;
Printf.fprintf oc "_min_caml_start: # main entry point\n";
+ (* sp と hp を設定 *)
+ Printf.fprintf oc "\tadd %s, %s, 0\n" (reg reg_sp) (reg "%x0");
+ Printf.fprintf oc "\tadd %s, %s, 0\n" (reg reg_hp) (reg "%x1");
+
(* fpとlrをスタックへ退避 *)
- Printf.fprintf oc "\tstp fp, lr, sp, -16!\n"; + Printf.fprintf oc "\tstp fp, lr, %s, -16!\n" (reg reg_sp); Printf.fprintf oc "#\tmain program starts\n";
stackset := S.empty;
@@ -284,7 +288,7 @@ let f oc (Prog(data, fundefs, e)) =
Printf.fprintf oc "#\tmain program ends\n";
(* fpとlrをスタックから復元 *)
- Printf.fprintf oc "\tldp fp, lr, sp, 16\n"; + Printf.fprintf oc "\tldp fp, lr, %s, 16\n" (reg reg_sp); (* 呼び出し元へ戻る *)
Printf.fprintf oc "\tret\n"
diff --git a/samples/stub.c b/samples/stub.c
index bf4c3b5..7e562c5 100644
--- a/samples/stub.c
+++ b/samples/stub.c
@@ -1,10 +1,19 @@
-extern int min_caml_start();
+extern int min_caml_start(char *, char *);
int main() {
- min_caml_start();
+ char *hp, *sp;
+
+ sp = alloca(1000000); hp = malloc(4000000);
+ if (hp == NULL || sp == NULL) {
+ fprintf(stderr, "malloc or alloca failed\n");
+ return 1;
+ }
+ fprintf(stderr, "sp = %p, hp = %p\n", sp, hp);
+ min_caml_start(sp, hp);
+
return 0;
}