aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-03 15:26:14 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-23 13:11:20 +0200
commita8e1df57346cb6a456e36d82c5d50a159479ba5d (patch)
tree216ec9dcc0ed79e2a59d61ab229d36465affa71d
parent5c02493b916eb59cd78b7f79940163b3f7755c77 (diff)
downloadsparse-dev-a8e1df57346cb6a456e36d82c5d50a159479ba5d.tar.gz
bitfield: extract linearize_bitfield_insert()
linearize_store_gen() is complex because it has to handle the insertion of bitfields. Isolate this operation in a separate function in order to facilitate the incoming changes there.
-rw-r--r--linearize.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/linearize.c b/linearize.c
index 273a534f..c1e4498e 100644
--- a/linearize.c
+++ b/linearize.c
@@ -973,6 +973,24 @@ static void add_store(struct entrypoint *ep, struct access_data *ad, pseudo_t va
add_one_insn(ep, store);
}
+static pseudo_t linearize_bitfield_insert(struct entrypoint *ep,
+ pseudo_t ori, pseudo_t val, struct symbol *ctype, struct symbol *btype)
+{
+ unsigned int shift = ctype->bit_offset;
+ unsigned int size = ctype->bit_size;
+ unsigned long long mask = ((1ULL << size) - 1);
+
+ val = add_cast(ep, btype, ctype, OP_ZEXT, val);
+ if (shift) {
+ val = add_binary_op(ep, btype, OP_SHL, val, value_pseudo(shift));
+ mask <<= shift;
+ }
+ ori = add_binary_op(ep, btype, OP_AND, ori, value_pseudo(~mask));
+ val = add_binary_op(ep, btype, OP_OR, ori, val);
+
+ return val;
+}
+
static pseudo_t linearize_store_gen(struct entrypoint *ep,
pseudo_t value,
struct access_data *ad)
@@ -985,18 +1003,8 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
return VOID;
if (type_size(btype) != type_size(ctype)) {
- unsigned int shift = ctype->bit_offset;
- unsigned int size = ctype->bit_size;
pseudo_t orig = add_load(ep, ad);
- unsigned long long mask = (1ULL << size) - 1;
-
- store = add_cast(ep, btype, ctype, OP_ZEXT, store);
- if (shift) {
- store = add_binary_op(ep, btype, OP_SHL, store, value_pseudo(shift));
- mask <<= shift;
- }
- orig = add_binary_op(ep, btype, OP_AND, orig, value_pseudo(~mask));
- store = add_binary_op(ep, btype, OP_OR, orig, store);
+ store = linearize_bitfield_insert(ep, orig, value, ctype, btype);
}
add_store(ep, ad, store);
return value;