summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm/CBuiltins.ml5
-rw-r--r--arm/PrintAsm.ml53
-rw-r--r--cfrontend/C2C.ml5
-rw-r--r--ia32/PrintAsm.ml3
-rw-r--r--powerpc/Asmexpand.ml16
5 files changed, 53 insertions, 29 deletions
diff --git a/arm/CBuiltins.ml b/arm/CBuiltins.ml
index b9b54e4..4446ab2 100644
--- a/arm/CBuiltins.ml
+++ b/arm/CBuiltins.ml
@@ -43,6 +43,11 @@ let builtins = {
(TVoid [], [TPtr(TInt(IUShort, []), []); TInt(IUShort, [])], false);
"__builtin_write32_reversed",
(TVoid [], [TPtr(TInt(IUInt, []), []); TInt(IUInt, [])], false);
+ (* Synchronization *)
+ "__builtin_dsb",
+ (TVoid [], [], false);
+ "__builtin_isb",
+ (TVoid [], [], false)
]
}
diff --git a/arm/PrintAsm.ml b/arm/PrintAsm.ml
index bb738a1..7dd7e48 100644
--- a/arm/PrintAsm.ml
+++ b/arm/PrintAsm.ml
@@ -515,6 +515,21 @@ let print_builtin_va_start oc r =
fprintf oc " str r14, [%a, #0]\n" ireg r;
n + 1
+(* Auxiliary for 64-bit integer arithmetic built-ins. They expand to
+ two instructions, one computing the low 32 bits of the result,
+ followed by another computing the high 32 bits. In cases where
+ the first instruction would overwrite arguments to the second
+ instruction, we must go through IR14 to hold the low 32 bits of the result.
+*)
+
+let print_int64_arith oc conflict rl fn =
+ if conflict then begin
+ let n = fn IR14 in
+ fprintf oc " mov%t %a, %a\n" thumbS ireg rl ireg IR14;
+ n + 1
+ end else
+ fn rl
+
(* Handling of compiler-inlined builtins *)
let print_builtin_inline oc name args res =
@@ -534,38 +549,25 @@ let print_builtin_inline oc name args res =
fprintf oc " vsqrt.f64 %a, %a\n" freg res freg a1; 1
(* 64-bit integer arithmetic *)
| "__builtin_negl", [IR ah; IR al], [IR rh; IR rl] ->
- fprintf oc " rsbs %a, %a, #0\n"
- ireg (if rl = ah then IR14 else rl) ireg al;
+ print_int64_arith oc (rl = ah) rl (fun rl ->
+ fprintf oc " rsbs %a, %a, #0\n" ireg rl ireg al;
(* No "rsc" instruction in Thumb2. Emulate based on
rsc a, b, #0 == a <- AddWithCarry(~b, 0, carry)
== mvn a, b; adc a, a, #0 *)
if !Clflags.option_fthumb then begin
fprintf oc " mvn %a, %a\n" ireg rh ireg ah;
- fprintf oc " adc %a, %a, #0\n" ireg rh ireg rh
+ fprintf oc " adc %a, %a, #0\n" ireg rh ireg rh; 3
end else begin
- fprintf oc " rsc %a, %a, #0\n" ireg rh ireg ah
- end;
- if rl = ah then
- fprintf oc " mov%t %a, %a\n" thumbS ireg rl ireg IR14;
- 4
+ fprintf oc " rsc %a, %a, #0\n" ireg rh ireg ah; 2
+ end)
| "__builtin_addl", [IR ah; IR al; IR bh; IR bl], [IR rh; IR rl] ->
- if rl = ah || rl = bh then begin
- fprintf oc " adds %a, %a, %a\n" ireg IR14 ireg al ireg bl;
- fprintf oc " adc %a, %a, %a\n" ireg rh ireg ah ireg bh;
- fprintf oc " mov%t %a, %a\n" thumbS ireg rl ireg IR14; 3
- end else begin
+ print_int64_arith oc (rl = ah || rl = bh) rl (fun rl ->
fprintf oc " adds %a, %a, %a\n" ireg rl ireg al ireg bl;
- fprintf oc " adc %a, %a, %a\n" ireg rh ireg ah ireg bh; 2
- end
+ fprintf oc " adc %a, %a, %a\n" ireg rh ireg ah ireg bh; 2)
| "__builtin_subl", [IR ah; IR al; IR bh; IR bl], [IR rh; IR rl] ->
- if rl = ah || rl = bh then begin
- fprintf oc " subs %a, %a, %a\n" ireg IR14 ireg al ireg bl;
- fprintf oc " sbc %a, %a, %a\n" ireg rh ireg ah ireg bh;
- fprintf oc " mov%t %a, %a\n" thumbS ireg rl ireg IR14; 3
- end else begin
+ print_int64_arith oc (rl = ah || rl = bh) rl (fun rl ->
fprintf oc " subs %a, %a, %a\n" ireg rl ireg al ireg bl;
- fprintf oc " sbc %a, %a, %a\n" ireg rh ireg ah ireg bh; 2
- end
+ fprintf oc " sbc %a, %a, %a\n" ireg rh ireg ah ireg bh; 2)
| "__builtin_mull", [IR a; IR b], [IR rh; IR rl] ->
fprintf oc " umull %a, %a, %a, %a\n" ireg rl ireg rh ireg a ireg b; 1
(* Memory accesses *)
@@ -581,6 +583,13 @@ let print_builtin_inline oc name args res =
| "__builtin_write32_reversed", [IR a1; IR a2], _ ->
fprintf oc " rev %a, %a\n" ireg IR14 ireg a2;
fprintf oc " str %a, [%a, #0]\n" ireg IR14 ireg a1; 2
+ (* Synchronization *)
+ | "__builtin_membar", [], _ ->
+ 0
+ | "__builtin_dsb", [], _ ->
+ fprintf oc " dsb\n"; 1
+ | "__builtin_isb", [], _ ->
+ fprintf oc " isb\n"; 1
(* Vararg stuff *)
| "__builtin_va_start", [IR a], _ ->
print_builtin_va_start oc a
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index e7d8337..6ee217c 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -92,6 +92,11 @@ let builtins_generic = {
(TInt(IInt, []),
[TPtr(TInt(IChar, [AConst]), []); TInt(IInt, [])],
false);
+ (* Software memory barrier *)
+ "__builtin_membar",
+ (TVoid [],
+ [],
+ false);
(* Variable arguments *)
(* va_start(ap,n)
(preprocessing) --> __builtin_va_start(ap, arg)
diff --git a/ia32/PrintAsm.ml b/ia32/PrintAsm.ml
index d30c856..56e837d 100644
--- a/ia32/PrintAsm.ml
+++ b/ia32/PrintAsm.ml
@@ -529,6 +529,9 @@ let print_builtin_inline oc name args res =
fprintf oc " movl %a, %a\n" ireg a2 ireg tmp;
fprintf oc " bswap %a\n" ireg tmp;
fprintf oc " movl %a, 0(%a)\n" ireg tmp ireg a1
+ (* Synchronization *)
+ | "__builtin_membar", [], _ ->
+ ()
(* Vararg stuff *)
| "__builtin_va_start", [IR a], _ ->
print_builtin_va_start oc a
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index 243a4d9..07cc50b 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -369,19 +369,19 @@ let expand_builtin_inline name args res =
emit (Pcfi_adjust _m8)
(* 64-bit integer arithmetic *)
| "__builtin_negl", [IR ah; IR al], [IR rh; IR rl] ->
- expand_int64_arith (rl = ah) rl (fun rl' ->
- emit (Psubfic(rl', al, Cint _0));
+ expand_int64_arith (rl = ah) rl (fun rl ->
+ emit (Psubfic(rl, al, Cint _0));
emit (Psubfze(rh, ah)))
| "__builtin_addl", [IR ah; IR al; IR bh; IR bl], [IR rh; IR rl] ->
- expand_int64_arith (rl = ah || rl = bh) rl (fun rl' ->
- emit (Paddc(rl', al, bl));
+ expand_int64_arith (rl = ah || rl = bh) rl (fun rl ->
+ emit (Paddc(rl, al, bl));
emit (Padde(rh, ah, bh)))
| "__builtin_subl", [IR ah; IR al; IR bh; IR bl], [IR rh; IR rl] ->
- expand_int64_arith (rl = ah || rl = bh) rl (fun rl' ->
- emit (Psubfc(rl', bl, al));
+ expand_int64_arith (rl = ah || rl = bh) rl (fun rl ->
+ emit (Psubfc(rl, bl, al));
emit (Psubfe(rh, bh, ah)))
| "__builtin_mull", [IR a; IR b], [IR rh; IR rl] ->
- expand_int64_arith (rl = a || rl = b) rl (fun rl' ->
+ expand_int64_arith (rl = a || rl = b) rl (fun rl ->
emit (Pmullw(rl, a, b));
emit (Pmulhwu(rh, a, b)))
(* Memory accesses *)
@@ -394,6 +394,8 @@ let expand_builtin_inline name args res =
| "__builtin_write32_reversed", [IR a1; IR a2], _ ->
emit (Pstwbrx(a2, GPR0, a1))
(* Synchronization *)
+ | "__builtin_membar", [], _ ->
+ ()
| "__builtin_eieio", [], _ ->
emit (Peieio)
| "__builtin_sync", [], _ ->