Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/asmcomp/arm/emit.mlp b/asmcomp/arm/emit.mlp
- index cfcb0c9..e6cb78d 100644
- --- a/asmcomp/arm/emit.mlp
- +++ b/asmcomp/arm/emit.mlp
- @@ -33,11 +33,23 @@ let fastcode_flag = ref true
- let emit_label lbl =
- emit_string ".L"; emit_int lbl
- -(* Output a symbol *)
- +(* Symbols *)
- let emit_symbol s =
- Emitaux.emit_symbol '$' s
- +(* Returns true if the symbol s is local to the current unit *)
- +let is_local_symbol s =
- + let p = (Compilenv.make_symbol (Some "")) in
- + try p = (String.sub s 0 (String.length p))
- + with Invalid_argument _ -> false
- +
- +let emit_branch instr s =
- + (* Local symbols don't need to branch through the PLT *)
- + if not !Clflags.dlcode || is_local_symbol s
- + then `{emit_string instr} {emit_symbol s}`
- + else `{emit_string instr} {emit_symbol s}(PLT)`
- +
- (* Output a pseudo-register *)
- let emit_reg r =
- @@ -77,16 +89,9 @@ let emit_addressing addr r n =
- Iindexed ofs ->
- `[{emit_reg r.(n)}, #{emit_int ofs}]`
- -(* Record live pointers at call points *)
- -
- -type frame_descr =
- - { fd_lbl: int; (* Return address *)
- - fd_frame_size: int; (* Size of stack frame *)
- - fd_live_offset: int list } (* Offsets/regs of live addresses *)
- +(* Record live pointers at call points -- see Emitaux *)
- -let frame_descriptors = ref([] : frame_descr list)
- -
- -let record_frame live =
- +let record_frame_label live dbg =
- let lbl = new_label() in
- let live_offset = ref [] in
- Reg.Set.iter
- @@ -100,18 +105,25 @@ let record_frame live =
- frame_descriptors :=
- { fd_lbl = lbl;
- fd_frame_size = frame_size();
- - fd_live_offset = !live_offset } :: !frame_descriptors;
- - `{emit_label lbl}:`
- -
- -let emit_frame fd =
- - ` .word {emit_label fd.fd_lbl} + 4\n`;
- - ` .short {emit_int fd.fd_frame_size}\n`;
- - ` .short {emit_int (List.length fd.fd_live_offset)}\n`;
- - List.iter
- - (fun n ->
- - ` .short {emit_int n}\n`)
- - fd.fd_live_offset;
- - ` .align 2\n`
- + fd_live_offset = !live_offset;
- + fd_debuginfo = dbg } :: !frame_descriptors;
- + lbl
- +
- +let record_frame live dbg =
- + let lbl = record_frame_label live dbg in `{emit_label lbl}:`
- +
- +(* Record calls to the GC -- we've moved them out of the way *)
- +
- +type gc_call =
- + { gc_lbl: label; (* Entry label *)
- + gc_return_lbl: label; (* Where to branch after GC *)
- + gc_frame_lbl: label } (* Label of frame descriptor *)
- +
- +let call_gc_sites = ref ([] : gc_call list)
- +
- +let emit_call_gc gc =
- + `{emit_label gc.gc_lbl}: {emit_branch "bl" "caml_invoke_gc"}\n`;
- + `{emit_label gc.gc_frame_lbl}: b {emit_label gc.gc_return_lbl}\n`
- (* Names of various instructions *)
- @@ -236,11 +248,11 @@ let label_constant tbl s size =
- let emit_constants () =
- Hashtbl.iter
- (fun s lbl ->
- - `{emit_label lbl}: .word {emit_symbol s}\n`)
- + `{emit_label lbl}: .word {emit_symbol s}\n`)
- symbol_constants;
- Hashtbl.iter
- (fun s lbl ->
- - `{emit_label lbl}: .double {emit_string s}\n`)
- + `{emit_label lbl}: .double {emit_string s}\n`)
- float_constants;
- Hashtbl.clear symbol_constants;
- Hashtbl.clear float_constants;
- @@ -285,9 +297,11 @@ let emit_instr i =
- ` ldr {emit_reg i.res.(0)}, {emit_label lbl} @ {emit_symbol s}\n`; 1
- | Lop(Icall_ind) ->
- ` mov lr, pc\n`;
- - `{record_frame i.live} bx {emit_reg i.arg.(0)}\n`; 2
- + ` bx {emit_reg i.arg.(0)}\n`;
- + record_frame i.live i.dbg; 2
- | Lop(Icall_imm s) ->
- - `{record_frame i.live} bl {emit_symbol s}\n`; 1
- + ` {emit_branch "bl" s}\n`;
- + record_frame i.live i.dbg; 1
- | Lop(Itailcall_ind) ->
- let n = frame_size() in
- if !contains_calls then
- @@ -306,14 +320,13 @@ let emit_instr i =
- ` b {emit_symbol s}\n`;
- 2 + ninstr
- end
- - | Lop(Iextcall(s, alloc)) ->
- - if alloc then begin
- - let lbl = label_constant symbol_constants s 1 in
- - ` ldr r12, {emit_label lbl} @ {emit_symbol s}\n`;
- - `{record_frame i.live} bl caml_c_call\n`; 2
- - end else begin
- - ` bl {emit_symbol s}\n`; 1
- - end
- + | Lop(Iextcall(s, true)) ->
- + let lbl = label_constant symbol_constants s 1 in
- + ` ldr r10, {emit_label lbl} @ {emit_symbol s}\n`;
- + ` {emit_branch "bl" "caml_c_invoke"}\n`;
- + record_frame i.live i.dbg; 2
- + | Lop(Iextcall(s, false)) ->
- + ` {emit_branch "bl" s}\n`; 1
- | Lop(Istackoffset n) ->
- assert (n mod 8 = 0);
- let ninstr =
- @@ -358,21 +371,37 @@ let emit_instr i =
- ` {emit_string instr} {emit_reg r}, {emit_addressing addr i.arg 1}\n`;
- 1
- | Lop(Ialloc n) ->
- - if !fastcode_flag then begin
- + let lbl_frame = record_frame_label i.live Debuginfo.none in
- + if not !fastcode_flag && (n == 8 || n == 12 || n == 16) then begin
- + ` {emit_branch "bl" ("caml_alloc" ^ (string_of_int ((n-4)/4)))}\n`;
- + `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, alloc_ptr, #4\n`;
- + 2
- + end else if not !fastcode_flag && not !Clflags.dlcode then begin
- let ni = emit_intconst (phys_reg 8 (*r12*)) (Nativeint.of_int n) in
- - ` sub alloc_ptr, alloc_ptr, r12\n`;
- - ` cmp alloc_ptr, alloc_limit\n`;
- - `{record_frame i.live} blcc caml_call_gc\n`;
- - ` add {emit_reg i.res.(0)}, alloc_ptr, #4\n`;
- - 4 + ni
- - end else if n = 8 || n = 12 || n = 16 then begin
- - `{record_frame i.live} bl caml_alloc{emit_int ((n-4)/4)}\n`;
- - ` add {emit_reg i.res.(0)}, alloc_ptr, #4\n`; 2
- + ` {emit_branch "bl" "caml_allocN"}\n`;
- + `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, alloc_ptr, #4\n`;
- + 2 + ni
- end else begin
- - let ni = emit_intconst (phys_reg 8 (*r12*)) (Nativeint.of_int n) in
- - `{record_frame i.live} bl caml_allocN\n`;
- + let lbl_return = new_label() in
- + `{emit_label lbl_return}:`;
- + let n = Nativeint.of_int n in
- + let ni = if is_immediate n then begin
- + ` sub alloc_ptr, alloc_ptr, #{emit_nativeint n}\n`;
- + 1
- + end else begin
- + let ni = emit_intconst (phys_reg 8 (*r12*)) n in
- + ` sub alloc_ptr, alloc_ptr, r12\n`;
- + 1 + ni
- + end in
- + ` cmp alloc_ptr, alloc_limit\n`;
- + let lbl_call_gc = new_label() in
- + ` bcc {emit_label lbl_call_gc}\n`;
- ` add {emit_reg i.res.(0)}, alloc_ptr, #4\n`;
- - 2 + ni
- + call_gc_sites :=
- + { gc_lbl = lbl_call_gc;
- + gc_return_lbl = lbl_return;
- + gc_frame_lbl = lbl_frame } :: !call_gc_sites;
- + 3 + ni
- end
- | Lop(Iintop(Ilsl | Ilsr | Iasr as op)) ->
- let shift = name_for_shift_operation op in
- @@ -384,7 +413,7 @@ let emit_instr i =
- ` mov{emit_string comp} {emit_reg i.res.(0)}, #1\n`; 3
- | Lop(Iintop(Icheckbound)) ->
- ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
- - ` blls caml_ml_array_bound_error\n`; 2
- + ` {emit_branch "blls" "caml_ml_array_bound_error"}\n`; 2
- | Lop(Iintop op) ->
- let instr = name_for_int_operation op in
- ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; 1
- @@ -421,7 +450,7 @@ let emit_instr i =
- ` mov{emit_string comp} {emit_reg i.res.(0)}, #1\n`; 3
- | Lop(Iintop_imm(Icheckbound, n)) ->
- ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`;
- - ` blls caml_ml_array_bound_error\n`; 2
- + ` {emit_branch "blls" "caml_ml_array_bound_error"}\n`; 2
- | Lop(Iintop_imm(op, n)) ->
- let instr = name_for_int_operation op in
- ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n`; 1
- @@ -440,7 +469,7 @@ let emit_instr i =
- 1
- | Lop(Ispecific(Ishiftcheckbound shift)) ->
- ` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`;
- - ` blcs caml_ml_array_bound_error\n`; 2
- + ` {emit_branch "blcs" "caml_ml_array_bound_error"}\n`; 2
- | Lop(Ispecific(Irevsubimm n)) ->
- ` rsb {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n`; 1
- | Lreloadretaddr ->
- @@ -551,11 +580,13 @@ let fundecl fundecl =
- fastcode_flag := fundecl.fun_fast;
- tailrec_entry_point := new_label();
- stack_offset := 0;
- + call_gc_sites := [];
- Hashtbl.clear symbol_constants;
- Hashtbl.clear float_constants;
- ` .text\n`;
- ` .align 2\n`;
- - ` .global {emit_symbol fundecl.fun_name}\n`;
- + ` .globl {emit_symbol fundecl.fun_name}\n`;
- + ` .type {emit_symbol fundecl.fun_name},%function\n`;
- `{emit_symbol fundecl.fun_name}:\n`;
- let n = frame_size() in
- ignore(emit_stack_adjustment "sub" n);
- @@ -563,7 +594,9 @@ let fundecl fundecl =
- ` str lr, [sp, #{emit_int(n - 4)}]\n`;
- `{emit_label !tailrec_entry_point}:\n`;
- emit_all 0 fundecl.fun_body;
- - emit_constants()
- + List.iter emit_call_gc !call_gc_sites;
- + emit_constants();
- + ` .size {emit_symbol fundecl.fun_name},.-{emit_symbol fundecl.fun_name}\n`
- (* Emission of data *)
- @@ -630,6 +663,13 @@ let end_assembly () =
- ` .data\n`;
- ` .global {emit_symbol lbl}\n`;
- `{emit_symbol lbl}:\n`;
- - ` .word {emit_int (List.length !frame_descriptors)}\n`;
- - List.iter emit_frame !frame_descriptors;
- - frame_descriptors := []
- + emit_frames
- + { efa_label = (fun l -> ` .word {emit_label l}\n`);
- + efa_16 = (fun n -> ` .short {emit_int n}\n`);
- + efa_32 = (fun n -> ` .word {emit_int32 n}\n`);
- + efa_word = (fun n -> ` .word {emit_int n}\n`);
- + efa_align = (fun n -> ` .align {emit_int(Misc.log2 n)}\n`);
- + efa_label_rel = (fun lbl ofs ->
- + ` .word {emit_label lbl} - . + {emit_int32 ofs}\n`);
- + efa_def_label = (fun l -> `{emit_label l}:\n`);
- + efa_string = (fun s -> emit_string_directive " .asciz " s) }
- diff --git a/asmrun/arm.S b/asmrun/arm.S
- index 8a47d18..4332148 100644
- --- a/asmrun/arm.S
- +++ b/asmrun/arm.S
- @@ -23,24 +23,11 @@ alloc_limit .req r10
- /* Allocation functions and GC interface */
- - .globl caml_call_gc
- -caml_call_gc:
- - /* Record return address and desired size */
- - /* Can use alloc_limit as a temporary since it will be reloaded by
- - invoke_gc */
- - ldr alloc_limit, .Lcaml_last_return_address
- - str lr, [alloc_limit, #0]
- - ldr alloc_limit, .Lcaml_requested_size
- - str r12, [alloc_limit, #0]
- - /* Branch to shared GC code */
- - bl .Linvoke_gc
- - /* Finish allocation */
- - ldr r12, .Lcaml_requested_size
- - ldr r12, [r12, #0]
- - sub alloc_ptr, alloc_ptr, r12
- - bx lr
- +/* Allocate 8 bytes in minor heap */
- +/* PIC safe */
- .globl caml_alloc1
- + .type caml_alloc1, %function
- caml_alloc1:
- sub alloc_ptr, alloc_ptr, #8
- cmp alloc_ptr, alloc_limit
- @@ -53,7 +40,11 @@ caml_alloc1:
- /* Try again */
- b caml_alloc1
- +/* Allocate 12 bytes in minor heap */
- +/* PIC safe */
- +
- .globl caml_alloc2
- + .type caml_alloc2, %function
- caml_alloc2:
- sub alloc_ptr, alloc_ptr, #12
- cmp alloc_ptr, alloc_limit
- @@ -66,7 +57,11 @@ caml_alloc2:
- /* Try again */
- b caml_alloc2
- +/* Allocate 16 bytes in minor heap */
- +/* PIC safe */
- +
- .globl caml_alloc3
- + .type caml_alloc3, %function
- caml_alloc3:
- sub alloc_ptr, alloc_ptr, #16
- cmp alloc_ptr, alloc_limit
- @@ -79,11 +74,24 @@ caml_alloc3:
- /* Try again */
- b caml_alloc3
- +/* Allocate N bytes in minor heap */
- +/* Number of bytes is in r12 (preserved) */
- +/* Not PIC safe */
- +
- .globl caml_allocN
- + .type caml_allocN, %function
- caml_allocN:
- sub alloc_ptr, alloc_ptr, r12
- cmp alloc_ptr, alloc_limit
- movcs pc, lr /* Return if alloc_ptr >= alloc_limit */
- +
- +/* Call GC and allocate N bytes in minor heap */
- +/* Number of bytes is in r12 (preserved) */
- +/* Not PIC safe */
- +
- + .globl caml_call_gc
- + .type caml_call_gc, %function
- +caml_call_gc:
- /* Record return address and desired size */
- /* Can use alloc_limit as a temporary since it will be reloaded by
- invoke_gc */
- @@ -91,12 +99,23 @@ caml_allocN:
- str lr, [alloc_limit, #0]
- ldr alloc_limit, .Lcaml_requested_size
- str r12, [alloc_limit, #0]
- - /* Invoke GC */
- + /* Branch to shared GC code */
- bl .Linvoke_gc
- - /* Try again */
- - ldr r12, .Lcaml_requested_size
- - ldr r12, [r12, #0]
- - b caml_allocN
- + /* Finish allocation */
- + ldr r12, .Lcaml_requested_size
- + ldr r12, [r12, #0]
- + sub alloc_ptr, alloc_ptr, r12
- + bx lr
- +
- +/* Invoke the GC */
- +/* PIC safe */
- +
- + .globl caml_invoke_gc
- + .type caml_invoke_gc, %function
- +caml_invoke_gc:
- + /* Record return address */
- + ldr r12, .Lcaml_last_return_address
- + str lr, [r12, #0]
- /* Shared code to invoke the GC */
- .Linvoke_gc:
- @@ -132,9 +151,20 @@ caml_allocN:
- /* Call a C function from Caml */
- /* Function to call is in r12 */
- +/* Not PIC safe */
- .globl caml_c_call
- + .type caml_c_call, %function
- caml_c_call:
- + mov r10, r12
- +
- +/* Invoke a C function from Caml (PIC) */
- +/* Function to call is in r10 (alloc_limit) */
- +/* PIC safe */
- +
- + .globl caml_c_invoke
- + .type caml_c_invoke, %function
- +caml_c_invoke:
- /* Preserve return address in callee-save register r4 */
- mov r4, lr
- /* Record lowest stack address and return address */
- @@ -149,7 +179,7 @@ caml_c_call:
- str trap_ptr, [r7, #0]
- /* Call the function */
- mov lr, pc
- - bx r12
- + bx r10
- /* Reload alloc ptr and alloc limit */
- ldr r5, .Lcaml_young_limit
- ldr alloc_ptr, [r6, #0] /* r6 still points to caml_young_ptr */
- @@ -158,8 +188,10 @@ caml_c_call:
- bx r4
- /* Start the Caml program */
- +/* PIC safe */
- .globl caml_start_program
- + .type caml_start_program, %function
- caml_start_program:
- ldr r12, .Lcaml_program
- @@ -220,7 +252,7 @@ caml_start_program:
- str alloc_ptr, [r4, #0]
- /* Reload callee-save registers and return */
- ldmfd sp!, {r4,r5,r6,r7,r8,r10,r11,lr}
- - bx lr
- + bx lr
- /* The trap handler */
- .Ltrap_handler:
- @@ -233,14 +265,16 @@ caml_start_program:
- b .Lreturn_result
- /* Raise an exception from C */
- +/* PIC safe */
- .globl caml_raise_exception
- + .type caml_raise_exception, %function
- caml_raise_exception:
- /* Reload Caml allocation pointers */
- - ldr r12, .Lcaml_young_ptr
- - ldr alloc_ptr, [r12, #0]
- - ldr r12, .Lcaml_young_limit
- - ldr alloc_limit, [r12, #0]
- + ldr alloc_ptr, .Lcaml_young_ptr
- + ldr alloc_limit, .Lcaml_young_limit
- + ldr alloc_ptr, [alloc_ptr, #0]
- + ldr alloc_limit, [alloc_limit, #0]
- /* Cut stack at current trap handler */
- ldr r12, .Lcaml_exception_pointer
- ldr sp, [r12, #0]
- @@ -250,6 +284,7 @@ caml_raise_exception:
- /* Callback from C to Caml */
- .globl caml_callback_exn
- + .type caml_callback_exn, %function
- caml_callback_exn:
- /* Initial shuffling of arguments (r0 = closure, r1 = first arg) */
- mov r12, r0
- @@ -259,6 +294,7 @@ caml_callback_exn:
- b .Ljump_to_caml
- .globl caml_callback2_exn
- + .type caml_callback2_exn, %function
- caml_callback2_exn:
- /* Initial shuffling of arguments (r0 = closure, r1 = arg1, r2 = arg2) */
- mov r12, r0
- @@ -269,6 +305,7 @@ caml_callback2_exn:
- b .Ljump_to_caml
- .globl caml_callback3_exn
- + .type caml_callback3_exn, %function
- caml_callback3_exn:
- /* Initial shuffling of arguments */
- /* (r0 = closure, r1 = arg1, r2 = arg2, r3 = arg3) */
- @@ -281,11 +318,12 @@ caml_callback3_exn:
- b .Ljump_to_caml
- .globl caml_ml_array_bound_error
- + .type caml_ml_array_bound_error, %function
- caml_ml_array_bound_error:
- - /* Load address of [caml_array_bound_error] in r12 */
- - ldr r12, .Lcaml_array_bound_error
- + /* Load address of [caml_array_bound_error] in r10 */
- + ldr r10, .Lcaml_array_bound_error
- /* Call that function */
- - b caml_c_call
- + b caml_c_invoke
- /* Global references */
- @@ -302,9 +340,9 @@ caml_ml_array_bound_error:
- .Lcaml_array_bound_error: .word caml_array_bound_error
- .Lcaml_requested_size: .word caml_requested_size
- - .data
- + .data
- caml_requested_size:
- - .word 0
- + .word 0
- /* GC roots for callback */
- diff --git a/configure b/configure
- index 47cc203..9f66c93 100755
- --- a/configure
- +++ b/configure
- @@ -636,6 +636,7 @@ if test $withsharedlibs = "yes"; then
- i[345]86-*-netbsd*) natdynlink=true;;
- x86_64-*-netbsd*) natdynlink=true;;
- i386-*-gnu0.3) natdynlink=true;;
- + arm*-*-linux*) natdynlink=true;;
- esac
- fi
Add Comment
Please, Sign In to add comment