Skip to content

Commit

Permalink
[arm] Implement the byte swap operations (PR#5774).
Browse files Browse the repository at this point in the history
Use rev16/movt to implement direct 16-bit byte-swap operation
(ARMv6T2 and above) and rev to implement the 32-bit byte-swap
operation (ARMv6 and above).

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13203 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
  • Loading branch information
bmeurer committed Jan 6, 2013
1 parent c80aac9 commit ab0eb76
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
20 changes: 12 additions & 8 deletions asmcomp/arm/arch.ml
Expand Up @@ -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
Expand Down Expand Up @@ -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 *)

Expand Down
10 changes: 10 additions & 0 deletions asmcomp/arm/emit.mlp
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions asmcomp/arm/selection.ml
Expand Up @@ -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} *)
Expand Down

0 comments on commit ab0eb76

Please sign in to comment.