summaryrefslogtreecommitdiff
path: root/cparser/Bitfields.ml
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-12-18 07:54:35 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-12-18 07:54:35 +0000
commit712f3cbae6bfd3c6f6cc40d44f438aa0affcd371 (patch)
tree913762a241b5f97b3ef4df086ba6adaeb2ff45c4 /cparser/Bitfields.ml
parentc629161139899e43a2fe7c5af59ca926cdab370e (diff)
Support for inline assembly (asm statements).
cparser: add primitive support for enum types. bitfield emulation: for bitfields with enum type, choose signed/unsigned as appropriate git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2074 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'cparser/Bitfields.ml')
-rw-r--r--cparser/Bitfields.ml24
1 files changed, 22 insertions, 2 deletions
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml
index 257f6c8..937a61f 100644
--- a/cparser/Bitfields.ml
+++ b/cparser/Bitfields.ml
@@ -46,7 +46,7 @@ type bitfield_info =
let bitfield_table =
(Hashtbl.create 57: (ident * string, bitfield_info) Hashtbl.t)
-(* Packing algorithm -- keep consistent with [Cutil.pack_bitfield]! *)
+(* Signedness issues *)
let unsigned_ikind_for_carrier nbits =
if nbits <= 8 then IUChar else
@@ -56,7 +56,26 @@ let unsigned_ikind_for_carrier nbits =
if nbits <= 8 * !config.sizeof_longlong then IULongLong else
assert false
-let pack_bitfields env id ml =
+let fits_unsigned v n =
+ v >= 0L && v < Int64.shift_left 1L n
+
+let fits_signed v n =
+ let p = Int64.shift_left 1L (n-1) in v >= Int64.neg p && v < p
+
+let is_signed_enum_bitfield env sid fld eid n =
+ let info = Env.find_enum env eid in
+ if List.for_all (fun (_, v, _) -> int_representable v n false) info.Env.ei_members
+ then false
+ else if List.for_all (fun (_, v, _) -> int_representable v n true) info.Env.ei_members
+ then true
+ else begin
+ Cerrors.warning "Warning: not all values of type 'enum %s' can be represented in bit-field '%s' of struct '%s' (%d bits are not enough)" eid.name fld sid.name n;
+ false
+ end
+
+(* Packing algorithm -- keep consistent with [Cutil.pack_bitfield]! *)
+
+let pack_bitfields env sid ml =
let rec pack accu pos = function
| [] ->
(pos, accu, [])
@@ -72,6 +91,7 @@ let pack_bitfields env id ml =
let signed =
match unroll env m.fld_typ with
| TInt(ik, _) -> is_signed_ikind ik
+ | TEnum(eid, _) -> is_signed_enum_bitfield env sid m.fld_name eid n
| _ -> assert false (* should never happen, checked in Elab *) in
let signed2 =
match unroll env (type_of_member env m) with