diff options
| -rw-r--r-- | asmcomp/arm/arch.ml | 20 | ||||
| -rw-r--r-- | asmcomp/arm/emit.mlp | 10 | ||||
| -rw-r--r-- | asmcomp/arm/selection.ml | 6 |
3 files changed, 28 insertions, 8 deletions
diff --git a/asmcomp/arm/arch.ml b/asmcomp/arm/arch.ml index a1d88ecc6d..cac286aa48 100644 --- a/asmcomp/arm/arch.ml +++ b/asmcomp/arm/arch.ml @@ -110,14 +110,15 @@ type specific_operation = Ishiftarith of arith_operation * int | Ishiftcheckbound of int | Irevsubimm of int - | Imuladd (* multiply and add *) - | Imulsub (* multiply and subtract *) - | Inegmulf (* floating-point negate and multiply *) - | Imuladdf (* floating-point multiply and add *) - | Inegmuladdf (* floating-point negate, multiply and add *) - | Imulsubf (* floating-point multiply and subtract *) - | Inegmulsubf (* floating-point negate, multiply and subtract *) - | Isqrtf (* floating-point square root *) + | Imuladd (* multiply and add *) + | Imulsub (* multiply and subtract *) + | Inegmulf (* floating-point negate and multiply *) + | Imuladdf (* floating-point multiply and add *) + | Inegmuladdf (* floating-point negate, multiply and add *) + | Imulsubf (* floating-point multiply and subtract *) + | Inegmulsubf (* floating-point negate, multiply and subtract *) + | Isqrtf (* floating-point square root *) + | Ibswap of int (* endianess conversion *) and arith_operation = Ishiftadd @@ -208,6 +209,9 @@ let print_specific_operation printreg op ppf arg = | Isqrtf -> fprintf ppf "sqrtf %a" printreg arg.(0) + | Ibswap n -> + fprintf ppf "bswap%i %a" n + printreg arg.(0) (* Recognize immediate operands *) diff --git a/asmcomp/arm/emit.mlp b/asmcomp/arm/emit.mlp index e0c531c077..4a12615136 100644 --- a/asmcomp/arm/emit.mlp +++ b/asmcomp/arm/emit.mlp @@ -682,6 +682,16 @@ let emit_instr i = | Imulsub -> "mls" | _ -> assert false) in ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}\n`; 1 + | Lop(Ispecific(Ibswap size)) -> + begin match size with + 16 -> + ` rev16 {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`; + ` movt {emit_reg i.res.(0)}, #0\n`; 2 + | 32 -> + ` rev {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`; 1 + | _ -> + assert false + end | Lreloadretaddr -> let n = frame_size() in ` ldr lr, [sp, #{emit_int(n-4)}]\n`; 1 diff --git a/asmcomp/arm/selection.ml b/asmcomp/arm/selection.ml index bded362911..547166b91a 100644 --- a/asmcomp/arm/selection.ml +++ b/asmcomp/arm/selection.ml @@ -174,6 +174,12 @@ method! select_operation op args = | (Cmodi, args) -> (* See above for fix up of return register *) (Iextcall("__aeabi_idivmod", false), args) + (* Recognize 16-bit bswap instruction (ARMv6T2 because we need movt) *) + | (Cextcall("caml_bswap16_direct", _, _, _), args) when !arch >= ARMv6T2 -> + (Ispecific(Ibswap 16), args) + (* Recognize 32-bit bswap instructions (ARMv6 and above) *) + | (Cextcall("caml_int32_direct_bswap", _, _, _), args) when !arch >= ARMv6 -> + (Ispecific(Ibswap 32), 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 VFPv{2,3} *) |
