Guest User

Untitled

a guest
Feb 16th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.68 KB | None | 0 0
  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
Add Comment
Please, Sign In to add comment