Index: asmcomp/arm/arch.ml =================================================================== --- asmcomp/arm/arch.ml (revision 94) +++ asmcomp/arm/arch.ml (working copy) @@ -20,7 +20,7 @@ type abi = EABI | EABI_VFP type arch = ARMv4 | ARMv5 | ARMv5TE | ARMv6 | ARMv6T2 | ARMv7 -type fpu = Soft | VFPv3_D16 | VFPv3 +type fpu = Soft | VFPv2 | VFPv3_D16 | VFPv3 let abi = match Config.system with @@ -38,6 +38,7 @@ let string_of_fpu = function Soft -> "soft" + | VFPv2 -> "vfpv2" | VFPv3_D16 -> "vfpv3-d16" | VFPv3 -> "vfpv3" @@ -72,6 +73,7 @@ let ffpu spec = fpu := (match spec with "soft" when abi <> EABI_VFP -> Soft + | "vfpv2" when abi = EABI_VFP -> VFPv2 | "vfpv3-d16" when abi = EABI_VFP -> VFPv3_D16 | "vfpv3" when abi = EABI_VFP -> VFPv3 | spec -> raise (Arg.Bad spec)) Index: asmcomp/arm/emit.mlp =================================================================== --- asmcomp/arm/emit.mlp (revision 94) +++ asmcomp/arm/emit.mlp (working copy) @@ -402,6 +402,10 @@ ` ldr {emit_reg i.res.(1)}, {emit_label lbl} + 4\n`; 2 end + | Lop(Iconst_float f) when !fpu = VFPv2 -> + let lbl = float_literal f in + ` fldd {emit_reg i.res.(0)}, {emit_label lbl} @ {emit_string f}\n`; + 1 | Lop(Iconst_float f) -> let encode imm = let sg = Int64.to_int (Int64.shift_right_logical imm 63) in @@ -468,7 +472,7 @@ let ninstr = emit_stack_adjustment (-n) in stack_offset := !stack_offset + n; ninstr - | Lop(Iload(Single, addr)) when !fpu >= VFPv3_D16 -> + | Lop(Iload(Single, addr)) when !fpu >= VFPv2 -> ` flds s14, {emit_addressing addr i.arg 0}\n`; ` fcvtds {emit_reg i.res.(0)}, s14\n`; 2 | Lop(Iload((Double | Double_u), addr)) when !fpu = Soft -> @@ -502,7 +506,7 @@ | Double_u -> "fldd" | _ (* 32-bit quantities *) -> "ldr" in ` {emit_string instr} {emit_reg r}, {emit_addressing addr i.arg 0}\n`; 1 - | Lop(Istore(Single, addr)) when !fpu >= VFPv3_D16 -> + | Lop(Istore(Single, addr)) when !fpu >= VFPv2 -> ` fcvtsd s14, {emit_reg i.arg.(0)}\n`; ` fsts s14, {emit_addressing addr i.arg 1}\n`; 2 | Lop(Istore((Double | Double_u), addr)) when !fpu = Soft -> @@ -808,7 +812,7 @@ let n = emit_instr i in let ninstr' = ninstr + n in (* fldd can address up to +/-1KB, ldr can address up to +/-4KB *) - let limit = (if !fpu >= VFPv3_D16 && !float_literals <> [] + let limit = (if !fpu >= VFPv2 && !float_literals <> [] then 127 else 511) in let limit = limit - !num_literals in @@ -910,6 +914,7 @@ end; begin match !fpu with Soft -> ` .fpu softvfp\n` + | VFPv2 -> ` .fpu vfpv2\n` | VFPv3_D16 -> ` .fpu vfpv3-d16\n` | VFPv3 -> ` .fpu vfpv3\n` end; Index: asmcomp/arm/proc.ml =================================================================== --- asmcomp/arm/proc.ml (revision 94) +++ asmcomp/arm/proc.ml (working copy) @@ -38,7 +38,7 @@ r13 stack pointer r14 return address r15 program counter - Floatinng-point register map (VFPv3): + Floating-point register map (VFPv{2,3}): d0 - d7 general purpose (not preserved) d8 - d15 general purpose (preserved) d16 - d31 generat purpose (not preserved), VFPv3 only @@ -55,9 +55,9 @@ (* We have three register classes: 0 for integer registers - 1 for VFPv3-D16 + 1 for VFPv2 and VFPv3-D16 2 for VFPv3 - This way we can choose between VFPv3-D16 and VFPv3 + This way we can choose between VFPv2/VFPv3-D16 and VFPv3 at (ocamlopt) runtime using command line switches. *) @@ -66,6 +66,7 @@ let register_class r = match (r.typ, !fpu) with (Int | Addr), _ -> 0 + | Float, VFPv2 -> 1 | Float, VFPv3_D16 -> 1 | Float, _ -> 2 @@ -125,7 +126,7 @@ end | Float -> assert (abi = EABI_VFP); - assert (!fpu >= VFPv3_D16); + assert (!fpu >= VFPv2); if !float <= last_float then begin loc.(i) <- phys_reg !float; incr float Index: asmcomp/arm/scheduling.ml =================================================================== --- asmcomp/arm/scheduling.ml (revision 94) +++ asmcomp/arm/scheduling.ml (working copy) @@ -42,7 +42,7 @@ | Imulf | Ispecific Inegmulf | Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf) | Ispecific Isqrtf - | Inegf | Iabsf when !fpu >= VFPv3_D16 -> 2 + | Inegf | Iabsf when !fpu >= VFPv2 -> 2 (* Everything else *) | _ -> 1 @@ -72,7 +72,7 @@ | Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf) -> 17 | Idivf | Ispecific Isqrtf -> 27 - | Inegf | Iabsf | Iconst_float _ when !fpu >= VFPv3_D16 -> 4 + | Inegf | Iabsf | Iconst_float _ when !fpu >= VFPv2 -> 4 (* Everything else *) | _ -> 1 Index: asmcomp/arm/selection.ml =================================================================== --- asmcomp/arm/selection.ml (revision 94) +++ asmcomp/arm/selection.ml (working copy) @@ -24,9 +24,9 @@ let is_offset chunk n = match chunk with - (* VFPv3 load/store have -1020 to 1020 *) + (* VFPv{2,3} load/store have -1020 to 1020 *) Single | Double | Double_u - when !fpu >= VFPv3_D16 -> + when !fpu >= VFPv2 -> n >= -1020 && n <= 1020 (* ARM load/store byte/word have -4095 to 4095 *) | Byte_unsigned | Byte_signed @@ -61,7 +61,7 @@ (* Soft-float Iabsf and Inegf: arg.(0) and res.(0) must be the same *) | Iabsf | Inegf when !fpu = Soft -> ([|res.(0); arg.(1)|], res) - (* VFPv3 Imuladdf...Inegmulsubf: arg.(0) and res.(0) must be the same *) + (* VFPv{2,3} Imuladdf...Inegmulsubf: arg.(0) and res.(0) must be the same *) | Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf) -> let arg' = Array.copy arg in arg'.(0) <- res.(0); @@ -95,7 +95,7 @@ method! is_simple_expr = function (* inlined floating-point ops are simple if their arguments are *) - | Cop(Cextcall("sqrt", _, _, _), args) when !fpu >= VFPv3_D16 -> + | Cop(Cextcall("sqrt", _, _, _), args) when !fpu >= VFPv2 -> List.for_all self#is_simple_expr args | e -> super#is_simple_expr e @@ -180,7 +180,7 @@ (Iextcall("__aeabi_idivmod", false), args) (* Turn floating-point operations into runtime ABI calls for softfp *) | (op, args) when !fpu = Soft -> self#select_operation_softfp op args - (* Select operations for VFPv3 *) + (* Select operations for VFPv{2,3} *) | (op, args) -> self#select_operation_vfpv3 op args method private select_operation_softfp op args =