Skip to content

Commit

Permalink
Extended inline asm: handle missing cases.
Browse files Browse the repository at this point in the history
Bitfields: better translation of initializers and compound literals; run this pass before unblocking.
Transform.stmt: extend with ability to treat unblocked code.
test/regression: more bitfield tests.
  • Loading branch information
xavierleroy committed Apr 28, 2015
1 parent 3c6f534 commit b04bb78
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 19 deletions.
10 changes: 8 additions & 2 deletions cparser/Cutil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -964,8 +964,7 @@ let rec subst_stmt phi s =
| Sskip
| Sbreak
| Scontinue
| Sgoto _
| Sasm _ -> s.sdesc
| Sgoto _ -> s.sdesc
| Sdo e -> Sdo (subst_expr phi e)
| Sseq(s1, s2) -> Sseq (subst_stmt phi s1, subst_stmt phi s2)
| Sif(e, s1, s2) ->
Expand All @@ -981,6 +980,13 @@ let rec subst_stmt phi s =
| Sreturn (Some e) -> Sreturn (Some (subst_expr phi e))
| Sblock sl -> Sblock (List.map (subst_stmt phi) sl)
| Sdecl d -> Sdecl (subst_decl phi d)
| Sasm(attr, template, outputs, inputs, clob) ->
let subst_asm_operand (lbl, cstr, e) =
(lbl, cstr, subst_expr phi e) in
Sasm(attr, template,
List.map subst_asm_operand outputs,
List.map subst_asm_operand inputs,
clob)
}


Expand Down
2 changes: 1 addition & 1 deletion cparser/PackedStructs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ let transf_expr loc env ctx e =
(* Statements *)

let transf_stmt env s =
Transform.stmt transf_expr env s
Transform.stmt ~expr:transf_expr env s

(* Functions *)

Expand Down
6 changes: 5 additions & 1 deletion cparser/StructReturn.ml
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ let transf_decl env (sto, id, ty, init) =
let transf_funbody env body optres =

let transf_expr ctx e = transf_expr env ctx e in
let transf_asm_operand (lbl, cstr, e) = (lbl, cstr, transf_expr Val e) in

(* Function returns:
return kind scalar -> return e
Expand Down Expand Up @@ -484,7 +485,10 @@ let rec transf_stmt s =
{s with sdesc = Sblock(List.map transf_stmt sl)}
| Sdecl d ->
{s with sdesc = Sdecl(transf_decl env d)}
| Sasm _ -> s
| Sasm(attr, template, outputs, inputs, clob) ->
{s with sdesc = Sasm(attr, template,
List.map transf_asm_operand outputs,
List.map transf_asm_operand inputs, clob)}

in
transf_stmt body
Expand Down
33 changes: 21 additions & 12 deletions cparser/Transform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -138,37 +138,46 @@ let expand_postincrdecr ~read ~write env ctx op l =
ecomma (eassign tmp (read l)) (ecomma (write l newval) tmp))

(* Generic transformation of a statement, transforming expressions within
and preserving the statement structure. Applies only to unblocked code. *)
and preserving the statement structure.
If [decl] is not given, it applies only to unblocked code. *)

let stmt trexpr env s =
let stmt ~expr ?(decl = fun env decl -> assert false) env s =
let rec stm s =
match s.sdesc with
| Sskip -> s
| Sdo e ->
{s with sdesc = Sdo(trexpr s.sloc env Effects e)}
{s with sdesc = Sdo(expr s.sloc env Effects e)}
| Sseq(s1, s2) ->
{s with sdesc = Sseq(stm s1, stm s2)}
| Sif(e, s1, s2) ->
{s with sdesc = Sif(trexpr s.sloc env Val e, stm s1, stm s2)}
{s with sdesc = Sif(expr s.sloc env Val e, stm s1, stm s2)}
| Swhile(e, s1) ->
{s with sdesc = Swhile(trexpr s.sloc env Val e, stm s1)}
{s with sdesc = Swhile(expr s.sloc env Val e, stm s1)}
| Sdowhile(s1, e) ->
{s with sdesc = Sdowhile(stm s1, trexpr s.sloc env Val e)}
{s with sdesc = Sdowhile(stm s1, expr s.sloc env Val e)}
| Sfor(s1, e, s2, s3) ->
{s with sdesc = Sfor(stm s1, trexpr s.sloc env Val e, stm s2, stm s3)}
{s with sdesc = Sfor(stm s1, expr s.sloc env Val e, stm s2, stm s3)}
| Sbreak -> s
| Scontinue -> s
| Sswitch(e, s1) ->
{s with sdesc = Sswitch(trexpr s.sloc env Val e, stm s1)}
{s with sdesc = Sswitch(expr s.sloc env Val e, stm s1)}
| Slabeled(lbl, s) ->
{s with sdesc = Slabeled(lbl, stm s)}
| Sgoto lbl -> s
| Sreturn None -> s
| Sreturn (Some e) ->
{s with sdesc = Sreturn(Some(trexpr s.sloc env Val e))}
| Sasm _ -> s
| Sblock _ | Sdecl _ ->
assert false (* should not occur in unblocked code *)
{s with sdesc = Sreturn(Some(expr s.sloc env Val e))}
| Sasm(attr, template, outputs, inputs, clob) ->
let asm_operand (lbl, cstr, e) =
(lbl, cstr, expr s.sloc env Val e) in
{s with sdesc = Sasm(attr, template,
List.map asm_operand outputs,
List.map asm_operand inputs, clob)}
| Sblock sl ->
{s with sdesc = Sblock (List.map stm sl)}
| Sdecl d ->
{s with sdesc = Sdecl (decl env d)}
in stm s
(* Generic transformation of a function definition *)
Expand Down
6 changes: 4 additions & 2 deletions cparser/Transform.mli
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ val expand_postincrdecr :

(** Generic transformation of a statement *)

val stmt : (C.location -> Env.t -> context -> C.exp -> C.exp) ->
Env.t -> C.stmt -> C.stmt
val stmt :
expr: (C.location -> Env.t -> context -> C.exp -> C.exp) ->
?decl: (Env.t -> C.decl -> C.decl) ->
Env.t -> C.stmt -> C.stmt

(** Generic transformation of a function definition *)

Expand Down
8 changes: 7 additions & 1 deletion cparser/Unblock.ml
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@ let rec unblock_stmt env s =
{s with sdesc = Sreturn(Some (expand_expr true env e))}
| Sblock sl -> unblock_block env sl
| Sdecl d -> assert false
| Sasm _ -> s
| Sasm(attr, template, outputs, inputs, clob) ->
let expand_asm_operand (lbl, cstr, e) =
(lbl, cstr, expand_expr true env e) in
{s with sdesc = Sasm(attr, template,
List.map expand_asm_operand outputs,
List.map expand_asm_operand inputs, clob)}


and unblock_block env = function
| [] -> sskip
Expand Down
10 changes: 10 additions & 0 deletions test/regression/Results/bitfields9
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
glob_s = { a = -12, b = 1 }
glob_t = { c = 123, d = 0, e = -45 }
loc_s = { a = 11, b = 2 }
loc_t = { c = 11, d = 1, e = 2 }
compound_s = { a = 2, b = 3 }
compound_t = { c = 2, d = 0, e = -11 }
loc_s = { a = 7, b = 2 }
loc_t = { c = 7, d = 1, e = 50 }
compound_s = { a = -14, b = 3 }
compound_t = { c = 50, d = 0, e = -7 }
49 changes: 49 additions & 0 deletions test/regression/bitfields9.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdio.h>

/* Initialization of bit-fields */

struct s {
signed char a: 6;
unsigned int b: 2;
};

struct t {
unsigned int c: 16;
unsigned int d: 1;
short e: 8;
};

void print_s(char * msg, struct s p)
{
printf("%s = { a = %d, b = %d }\n", msg, p.a, p.b);
}

void print_t(char * msg, struct t p)
{
printf("%s = { c = %d, d = %d, e = %d }\n", msg, p.c, p.d, p.e);
}

/* Global initialization */
struct s glob_s = { -12, 1 };
struct t glob_t = { 123, 0, -45 };

/* Local initialization */
void f(int x, int y)
{
struct s loc_s = { x, y };
struct t loc_t = { x, 1, y };
print_s("loc_s", loc_s);
print_t("loc_t", loc_t);
print_s("compound_s", (struct s) { y, x });
print_t("compound_t", (struct t) { y, 0, -x });
}

int main()
{
print_s("glob_s", glob_s);
print_t("glob_t", glob_t);
f(11, 2);
f(7, 50);
return 0;
}

0 comments on commit b04bb78

Please sign in to comment.