summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm/CBuiltins.ml11
-rw-r--r--arm/PrintAsm.ml13
-rw-r--r--cparser/Machine.ml18
-rw-r--r--cparser/Machine.mli1
-rw-r--r--cparser/PackedStructs.ml63
-rw-r--r--ia32/CBuiltins.ml11
-rw-r--r--ia32/Machregs.v11
-rw-r--r--ia32/PrintAsm.ml19
-rw-r--r--test/regression/Results/builtins-arm4
-rw-r--r--test/regression/Results/builtins-ia324
-rw-r--r--test/regression/builtins-arm.c7
-rw-r--r--test/regression/builtins-ia32.c8
12 files changed, 133 insertions, 37 deletions
diff --git a/arm/CBuiltins.ml b/arm/CBuiltins.ml
index 771243f..ad739f1 100644
--- a/arm/CBuiltins.ml
+++ b/arm/CBuiltins.ml
@@ -31,7 +31,16 @@ let builtins = {
(TInt(IUInt, []), [TInt(IUInt, [])], false);
(* Float arithmetic *)
"__builtin_fsqrt",
- (TFloat(FDouble, []), [TFloat(FDouble, [])], false)
+ (TFloat(FDouble, []), [TFloat(FDouble, [])], false);
+ (* Memory accesses *)
+ "__builtin_read16_reversed",
+ (TInt(IUShort, []), [TPtr(TInt(IUShort, [AConst]), [])], false);
+ "__builtin_read32_reversed",
+ (TInt(IUInt, []), [TPtr(TInt(IUInt, [AConst]), [])], false);
+ "__builtin_write16_reversed",
+ (TVoid [], [TPtr(TInt(IUShort, []), []); TInt(IUShort, [])], false);
+ "__builtin_write32_reversed",
+ (TVoid [], [TPtr(TInt(IUInt, []), []); TInt(IUInt, [])], false);
]
}
diff --git a/arm/PrintAsm.ml b/arm/PrintAsm.ml
index fc7c987..1d46416 100644
--- a/arm/PrintAsm.ml
+++ b/arm/PrintAsm.ml
@@ -388,6 +388,19 @@ let print_builtin_inline oc name args res =
end else begin
fprintf oc " umull %a, %a, %a, %a\n" ireg rl ireg rh ireg a ireg b; 1
end
+ (* Memory accesses *)
+ | "__builtin_read16_reversed", [IR a1], [IR res] ->
+ fprintf oc " ldrh %a, [%a, #0]\n" ireg res ireg a1;
+ fprintf oc " rev16 %a, %a\n" ireg res ireg res; 2
+ | "__builtin_read32_reversed", [IR a1], [IR res] ->
+ fprintf oc " ldr %a, [%a, #0]\n" ireg res ireg a1;
+ fprintf oc " rev %a, %a\n" ireg res ireg res; 2
+ | "__builtin_write16_reversed", [IR a1; IR a2], _ ->
+ fprintf oc " rev16 %a, %a\n" ireg IR14 ireg a2;
+ fprintf oc " strh %a, [%a, #0]\n" ireg IR14 ireg a1; 2
+ | "__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
(* Catch-all *)
| _ ->
invalid_arg ("unrecognized builtin " ^ name)
diff --git a/cparser/Machine.ml b/cparser/Machine.ml
index 0300582..7696444 100644
--- a/cparser/Machine.ml
+++ b/cparser/Machine.ml
@@ -16,6 +16,7 @@
(* Machine-dependent aspects *)
type t = {
+ name: string;
char_signed: bool;
sizeof_ptr: int;
sizeof_short: int;
@@ -45,6 +46,7 @@ type t = {
}
let ilp32ll64 = {
+ name = "ilp32ll64";
char_signed = false;
sizeof_ptr = 4;
sizeof_short = 2;
@@ -74,6 +76,7 @@ let ilp32ll64 = {
}
let i32lpll64 = {
+ name = "i32lpll64";
char_signed = false;
sizeof_ptr = 8;
sizeof_short = 2;
@@ -103,6 +106,7 @@ let i32lpll64 = {
}
let il32pll64 = {
+ name = "il32pll64";
char_signed = false;
sizeof_ptr = 8;
sizeof_short = 2;
@@ -133,11 +137,15 @@ let il32pll64 = {
(* Canned configurations for some ABIs *)
-let x86_32 = { ilp32ll64 with char_signed = true }
-let x86_64 = { i32lpll64 with char_signed = true }
-let win64 = { il32pll64 with char_signed = true }
-let ppc_32_bigendian = { ilp32ll64 with bigendian = true; bitfields_msb_first = true }
-let arm_littleendian = ilp32ll64
+let x86_32 =
+ { ilp32ll64 with char_signed = true; name = "x86_32" }
+let x86_64 =
+ { i32lpll64 with char_signed = true; name = "x86_64" }
+let win64 =
+ { il32pll64 with char_signed = true; name = "x86_64" }
+let ppc_32_bigendian =
+ { ilp32ll64 with bigendian = true; bitfields_msb_first = true; name = "powerpc" }
+let arm_littleendian = { ilp32ll64 with name = "arm" }
(* Add GCC extensions re: sizeof and alignof *)
diff --git a/cparser/Machine.mli b/cparser/Machine.mli
index 3becce3..b621d4c 100644
--- a/cparser/Machine.mli
+++ b/cparser/Machine.mli
@@ -16,6 +16,7 @@
(* Machine-dependent aspects *)
type t = {
+ name: string;
char_signed: bool;
sizeof_ptr: int;
sizeof_short: int;
diff --git a/cparser/PackedStructs.ml b/cparser/PackedStructs.ml
index dbd5160..ebf210b 100644
--- a/cparser/PackedStructs.ml
+++ b/cparser/PackedStructs.ml
@@ -197,25 +197,31 @@ let arrow_packed_field base pf ty =
(* (ty) __builtin_readNN_reversed(&lval)
or (ty) __builtin_bswapNN(lval) *)
+let use_reversed =
+ match !Machine.config.Machine.name with
+ | "powerpc" -> true
+ | _ -> false
+
let bswap_read loc env lval =
let ty = lval.etyp in
let (bsize, aty) = accessor_type loc env ty in
assert (bsize = 16 || bsize = 32);
try
- let (id, fty) =
- lookup_function loc env (sprintf "__builtin_read%d_reversed" bsize) in
- let fn = {edesc = EVar id; etyp = fty} in
- let args = [ecast_opt env (TPtr(aty,[])) (eaddrof lval)] in
- let call = {edesc = ECall(fn, args); etyp = aty} in
- ecast_opt env ty call
- with Env.Error _ ->
- try
- let (id, fty) =
- lookup_function loc env (sprintf "__builtin_bswap%d" bsize) in
- let fn = {edesc = EVar id; etyp = fty} in
- let args = [ecast_opt env aty lval] in
- let call = {edesc = ECall(fn, args); etyp = aty} in
- ecast_opt env ty call
+ if use_reversed then begin
+ let (id, fty) =
+ lookup_function loc env (sprintf "__builtin_read%d_reversed" bsize) in
+ let fn = {edesc = EVar id; etyp = fty} in
+ let args = [ecast_opt env (TPtr(aty,[])) (eaddrof lval)] in
+ let call = {edesc = ECall(fn, args); etyp = aty} in
+ ecast_opt env ty call
+ end else begin
+ let (id, fty) =
+ lookup_function loc env (sprintf "__builtin_bswap%d" bsize) in
+ let fn = {edesc = EVar id; etyp = fty} in
+ let args = [ecast_opt env aty lval] in
+ let call = {edesc = ECall(fn, args); etyp = aty} in
+ ecast_opt env ty call
+ end
with Env.Error msg ->
fatal_error "%a: Error: %s" formatloc loc (Env.error_message msg)
@@ -228,20 +234,21 @@ let bswap_write loc env lhs rhs =
accessor_type loc env ty in
assert (bsize = 16 || bsize = 32);
try
- let (id, fty) =
- lookup_function loc env (sprintf "__builtin_write%d_reversed" bsize) in
- let fn = {edesc = EVar id; etyp = fty} in
- let args = [ecast_opt env (TPtr(aty,[])) (eaddrof lhs);
- ecast_opt env aty rhs] in
- {edesc = ECall(fn, args); etyp = TVoid[]}
- with Env.Error _ ->
- try
- let (id, fty) =
- lookup_function loc env (sprintf "__builtin_bswap%d" bsize) in
- let fn = {edesc = EVar id; etyp = fty} in
- let args = [ecast_opt env aty rhs] in
- let call = {edesc = ECall(fn, args); etyp = aty} in
- eassign lhs (ecast_opt env ty call)
+ if use_reversed then begin
+ let (id, fty) =
+ lookup_function loc env (sprintf "__builtin_write%d_reversed" bsize) in
+ let fn = {edesc = EVar id; etyp = fty} in
+ let args = [ecast_opt env (TPtr(aty,[])) (eaddrof lhs);
+ ecast_opt env aty rhs] in
+ {edesc = ECall(fn, args); etyp = TVoid[]}
+ end else begin
+ let (id, fty) =
+ lookup_function loc env (sprintf "__builtin_bswap%d" bsize) in
+ let fn = {edesc = EVar id; etyp = fty} in
+ let args = [ecast_opt env aty rhs] in
+ let call = {edesc = ECall(fn, args); etyp = aty} in
+ eassign lhs (ecast_opt env ty call)
+ end
with Env.Error msg ->
fatal_error "%a: Error: %s" formatloc loc (Env.error_message msg)
diff --git a/ia32/CBuiltins.ml b/ia32/CBuiltins.ml
index 4a3dde5..cbd5998 100644
--- a/ia32/CBuiltins.ml
+++ b/ia32/CBuiltins.ml
@@ -33,6 +33,15 @@ let builtins = {
"__builtin_fmax",
(TFloat(FDouble, []), [TFloat(FDouble, []); TFloat(FDouble, [])], false);
"__builtin_fmin",
- (TFloat(FDouble, []), [TFloat(FDouble, []); TFloat(FDouble, [])], false)
+ (TFloat(FDouble, []), [TFloat(FDouble, []); TFloat(FDouble, [])], false);
+ (* Memory accesses *)
+ "__builtin_read16_reversed",
+ (TInt(IUShort, []), [TPtr(TInt(IUShort, [AConst]), [])], false);
+ "__builtin_read32_reversed",
+ (TInt(IUInt, []), [TPtr(TInt(IUInt, [AConst]), [])], false);
+ "__builtin_write16_reversed",
+ (TVoid [], [TPtr(TInt(IUShort, []), []); TInt(IUShort, [])], false);
+ "__builtin_write32_reversed",
+ (TVoid [], [TPtr(TInt(IUInt, []), []); TInt(IUInt, [])], false);
]
}
diff --git a/ia32/Machregs.v b/ia32/Machregs.v
index a2f3c3e..31ea8ee 100644
--- a/ia32/Machregs.v
+++ b/ia32/Machregs.v
@@ -101,6 +101,11 @@ Definition destroyed_by_cond (cond: condition): list mreg :=
Definition destroyed_by_jumptable: list mreg :=
nil.
+Local Open Scope string_scope.
+
+Definition builtin_write16_reversed := ident_of_string "__builtin_write16_reversed".
+Definition builtin_write32_reversed := ident_of_string "__builtin_write32_reversed".
+
Definition destroyed_by_builtin (ef: external_function): list mreg :=
match ef with
| EF_memcpy sz al =>
@@ -109,6 +114,10 @@ Definition destroyed_by_builtin (ef: external_function): list mreg :=
| EF_vstore Mfloat32 => X7 :: nil
| EF_vstore_global (Mint8unsigned|Mint8signed) _ _ => AX :: nil
| EF_vstore_global Mfloat32 _ _ => X7 :: nil
+ | EF_builtin id sg =>
+ if ident_eq id builtin_write16_reversed
+ || ident_eq id builtin_write32_reversed
+ then CX :: DX :: nil else nil
| _ => nil
end.
@@ -131,8 +140,6 @@ Definition mregs_for_operation (op: operation): list (option mreg) * option mreg
| _ => (nil, None)
end.
-Local Open Scope string_scope.
-
Definition builtin_negl := ident_of_string "__builtin_negl".
Definition builtin_addl := ident_of_string "__builtin_addl".
Definition builtin_subl := ident_of_string "__builtin_subl".
diff --git a/ia32/PrintAsm.ml b/ia32/PrintAsm.ml
index 0878371..2d676d1 100644
--- a/ia32/PrintAsm.ml
+++ b/ia32/PrintAsm.ml
@@ -442,6 +442,25 @@ let print_builtin_inline oc name args res =
| "__builtin_mull", [IR a; IR b], [IR rh; IR rl] ->
assert (a = EAX && b = EDX && rh = EDX && rl = EAX);
fprintf oc " mull %a\n" ireg EDX
+ (* Memory accesses *)
+ | "__builtin_read16_reversed", [IR a1], [IR res] ->
+ fprintf oc " movzwl 0(%a), %a\n" ireg a1 ireg res;
+ fprintf oc " rolw $8, %a\n" ireg16 res
+ | "__builtin_read32_reversed", [IR a1], [IR res] ->
+ fprintf oc " movl 0(%a), %a\n" ireg a1 ireg res;
+ fprintf oc " bswap %a\n" ireg res
+ | "__builtin_write16_reversed", [IR a1; IR a2], _ ->
+ let tmp = if a1 = ECX then EDX else ECX in
+ if a2 <> tmp then
+ fprintf oc " movl %a, %a\n" ireg a2 ireg tmp;
+ fprintf oc " xchg %a, %a\n" ireg8 tmp high_ireg8 tmp;
+ fprintf oc " movw %a, 0(%a)\n" ireg16 tmp ireg a1
+ | "__builtin_write32_reversed", [IR a1; IR a2], _ ->
+ let tmp = if a1 = ECX then EDX else ECX in
+ if a2 <> tmp then
+ 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
(* Catch-all *)
| _ ->
invalid_arg ("unrecognized builtin " ^ name)
diff --git a/test/regression/Results/builtins-arm b/test/regression/Results/builtins-arm
index e60c159..7925545 100644
--- a/test/regression/Results/builtins-arm
+++ b/test/regression/Results/builtins-arm
@@ -2,3 +2,7 @@ bswap(12345678) = 78563412
bswap16(1234) = 3412
cntlz(12345678) = 3
fsqrt(3.141590) = 1.772453
+read_16_rev = 3412
+read_32_rev = efbeadde
+after write_16_rev: 9a78
+after write_32_rev: 78563412
diff --git a/test/regression/Results/builtins-ia32 b/test/regression/Results/builtins-ia32
index 52d6daf..c16c6ae 100644
--- a/test/regression/Results/builtins-ia32
+++ b/test/regression/Results/builtins-ia32
@@ -3,3 +3,7 @@ bswap16(1234) = 3412
fsqrt(3.141590) = 1.772453
fmin(3.141590, 2.718000) = 2.718000
fmax(3.141590, 2.718000) = 3.141590
+read_16_rev = 3412
+read_32_rev = efbeadde
+after write_16_rev: 9a78
+after write_32_rev: 78563412
diff --git a/test/regression/builtins-arm.c b/test/regression/builtins-arm.c
index 41ea88b..a80cdcd 100644
--- a/test/regression/builtins-arm.c
+++ b/test/regression/builtins-arm.c
@@ -14,6 +14,13 @@ int main(int argc, char ** argv)
printf("cntlz(%x) = %d\n", x, __builtin_cntlz(x));
printf("fsqrt(%f) = %f\n", a, __builtin_fsqrt(a));
+ printf ("read_16_rev = %x\n", __builtin_read16_reversed(&s));
+ printf ("read_32_rev = %x\n", __builtin_read32_reversed(&y));
+ __builtin_write16_reversed(&s, 0x789A);
+ printf ("after write_16_rev: %x\n", s);
+ __builtin_write32_reversed(&y, 0x12345678);
+ printf ("after write_32_rev: %x\n", y);
+
return 0;
}
diff --git a/test/regression/builtins-ia32.c b/test/regression/builtins-ia32.c
index 43e4566..1408444 100644
--- a/test/regression/builtins-ia32.c
+++ b/test/regression/builtins-ia32.c
@@ -5,6 +5,7 @@
int main(int argc, char ** argv)
{
unsigned int x = 0x12345678;
+ unsigned int y = 0xDEADBEEF;
double a = 3.14159;
double b = 2.718;
unsigned short s = 0x1234;
@@ -16,6 +17,13 @@ int main(int argc, char ** argv)
printf("fmin(%f, %f) = %f\n", a, b, __builtin_fmin(a, b));
printf("fmax(%f, %f) = %f\n", a, b, __builtin_fmax(a, b));
+ printf ("read_16_rev = %x\n", __builtin_read16_reversed(&s));
+ printf ("read_32_rev = %x\n", __builtin_read32_reversed(&y));
+ __builtin_write16_reversed(&s, 0x789A);
+ printf ("after write_16_rev: %x\n", s);
+ __builtin_write32_reversed(&y, 0x12345678);
+ printf ("after write_32_rev: %x\n", y);
+
return 0;
}