SHARE
TWEET

Untitled

a guest Feb 16th, 2019 72 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. From 4dc3b96bfb6f807349ad67c062bf9f154e80b3a7 Mon Sep 17 00:00:00 2001
  2. From: Pierre Chambart <pierre.chambart@ocamlpro.org>
  3. Date: Tue, 6 Aug 2013 16:00:55 +0200
  4. Subject: [PATCH] atomic 32 bit load
  5.  
  6. ---
  7.  asmcomp/cmmgen.ml | 72 ++++++++++++++++++++++++++++++++++++++++++++-----------
  8.  1 file changed, 58 insertions(+), 14 deletions(-)
  9.  
  10. diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml
  11. index 23d4798..e66c663 100644
  12. --- a/asmcomp/cmmgen.ml
  13. +++ b/asmcomp/cmmgen.ml
  14. @@ -697,24 +697,68 @@ let unaligned_set_16 ptr idx newval =
  15.          Cop(Cstore Byte_unsigned,
  16.              [add_int (add_int ptr idx) (Cconst_int 1); b2]))
  17.  
  18. +let rec is_aligned n = function
  19. +  | Cconst_int i -> i mod n = 0
  20. +  | Cop((Cand | Cmuli), [arg1; arg2]) ->
  21. +    is_aligned n arg1 || is_aligned n arg2
  22. +  | Cop(Clsl, [arg1; Cconst_int n]) ->
  23. +    is_aligned n arg1 || n >= Misc.log2 n
  24. +  | _ -> false
  25. +
  26.  let unaligned_load_32 ptr idx =
  27. -  if Arch.allow_unaligned_access
  28. +  if Arch.allow_unaligned_access || is_aligned 4 idx
  29. +  (* ptr is assumed to be aligned *)
  30.    then Cop(Cload Thirtytwo_unsigned, [add_int ptr idx])
  31.    else
  32. -    let v1 = Cop(Cload Byte_unsigned, [add_int ptr idx]) in
  33. -    let v2 = Cop(Cload Byte_unsigned,
  34. -                 [add_int (add_int ptr idx) (Cconst_int 1)]) in
  35. -    let v3 = Cop(Cload Byte_unsigned,
  36. -                 [add_int (add_int ptr idx) (Cconst_int 2)]) in
  37. -    let v4 = Cop(Cload Byte_unsigned,
  38. -                 [add_int (add_int ptr idx) (Cconst_int 3)]) in
  39. -    let b1, b2, b3, b4 =
  40. +
  41. +    (* if the architecture does not accept unaligned access, we
  42. +       still enforce atomic loads when the address is effectively
  43. +       aligned by loading the whole value on one read. The effect
  44. +       is moraly
  45. +
  46. +       let load addr =
  47. +       if addr mod 4 = 0
  48. +       then Cload addr
  49. +       else
  50. +         let addr1 = addr - (addr mod 4) in
  51. +         let addr2 = addr1 + 4 in
  52. +         let v1 = Cload addr1 in
  53. +         let v2 = Cload addr2 in
  54. +         if big_endian
  55. +         then v1 lsl ((addr mod 4) * 8) || v2 lsr ((4 - (addr mod 4)) * 8)
  56. +         else v1 lsr ((addr mod 4) * 8) || v2 lsl ((4 - (addr mod 4)) * 8)
  57. +
  58. +       but to avoid conditionnal branch, when (addr mod 4 = 0) we in fact
  59. +       set addr2 = addr1 (to avoid potential segmentation fault) *)
  60. +
  61. +    bind "base_addr" (add_int ptr idx) (fun base_addr ->
  62. +    bind "addr1" (lsl_int (lsr_int base_addr (Cconst_int 2)) (Cconst_int 2))
  63. +    (fun addr1 -> (* base_addr - (base_addr mod 4) *)
  64. +    bind "addr2" (lsl_int (incr_int (lsr_int (decr_int base_addr)
  65. +                                       (Cconst_int 2))) (Cconst_int 2))
  66. +    (fun addr2 -> (* if base_addr mod 4 = 0
  67. +                  then base_addr
  68. +                  else v
  69. +                    such that v mod 4 = 0 and v > base_addr
  70. +                    and v - base_addr < 4 *)
  71. +
  72. +    let v1 = Cop(Cload Thirtytwo_unsigned, [addr1]) in
  73. +    let v2 = Cop(Cload Thirtytwo_unsigned, [addr2]) in
  74. +    bind "mod_time_8" (lsl_int (Cop(Cand, [base_addr; Cconst_int 3]))
  75. +                               (Cconst_int 3))
  76. +    (fun mod_time_8 -> (* (base_addr mod 4) * 8 *)
  77. +    let shift1 = mod_time_8 in
  78. +    let shift2 = sub_int (Cconst_int 32) mod_time_8 in
  79. +
  80. +    let v1', v2' =
  81.        if Arch.big_endian
  82. -      then v1, v2, v3, v4
  83. -      else v4, v3, v2, v1 in
  84. -    Cop(Cor,
  85. -        [Cop(Cor, [lsl_int b1 (Cconst_int 24); lsl_int b2 (Cconst_int 16)]);
  86. -         Cop(Cor, [lsl_int b3 (Cconst_int 8); b4])])
  87. +      then lsl_int v1 shift1, lsr_int v2 shift2
  88. +      else lsr_int v1 shift1, lsl_int v2 shift2 in
  89. +
  90. +    let res = Cop(Cor, [v1'; v2']) in
  91. +    if Arch.size_int = 8
  92. +    then Cop(Cand, [res; Cconst_int 0xFF_FF_FF_FF])
  93. +    else res))))
  94.  
  95.  let unaligned_set_32 ptr idx newval =
  96.    if Arch.allow_unaligned_access
  97. --
  98. 1.8.4.rc1
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top