aboutsummaryrefslogtreecommitdiff
path: root/lib/dis.h
diff options
context:
space:
mode:
authorcomex2015-01-11 02:28:37 -0500
committercomex2015-01-11 02:28:37 -0500
commitc14ecd8759c2b84e9c82fdf27b70f5847aa9a82d (patch)
treebe432adb27ab9d5d5a6e323fbacc05d03fcbace6 /lib/dis.h
parent*sigh* (diff)
downloadsubstitute-c14ecd8759c2b84e9c82fdf27b70f5847aa9a82d.tar.gz
yay?
Diffstat (limited to 'lib/dis.h')
-rw-r--r--lib/dis.h58
1 files changed, 37 insertions, 21 deletions
diff --git a/lib/dis.h b/lib/dis.h
index 8063235..a45e5d0 100644
--- a/lib/dis.h
+++ b/lib/dis.h
@@ -1,8 +1,7 @@
#pragma once
+#include <stdbool.h>
-static inline int sext(unsigned val, int bits) {
- return val & (1 << (bits - 1)) ? ((int)val - (1 << bits)) : (int)val;
-}
+#define UNUSED __attribute__((unused))
struct bitslice_run {
int inpos, outpos, len;
@@ -13,35 +12,52 @@ struct bitslice {
const struct bitslice_run *runs;
};
-__attribute__((always_inline))
+struct dis_data_operand {
+ struct bitslice n;
+ bool out;
+};
+
+static inline int sext(unsigned val, int bits) {
+ return val & (1 << (bits - 1)) ? ((int)val - (1 << bits)) : (int)val;
+}
+
static inline unsigned bs_get(struct bitslice bs, unsigned op) {
unsigned ret = 0;
for(int i = 0; i < bs.nruns; i++) {
const struct bitslice_run *run = &bs.runs[i];
- unsigned masked = op & ((1 << run->len) - 1);
- if (run->outpos < run->inpos)
- masked >>= run->inpos - run->outpos;
- else if (run->outpos > run->inpos)
- masked <<= run->outpos - run->inpos;
- ret |= masked;
+ unsigned val = (op >> run->inpos) & ((1 << run->len) - 1);
+ ret |= val << run->outpos;
}
return ret;
}
-__attribute__((always_inline))
-static inline unsigned bs_set(struct bitslice bs, unsigned val, unsigned op) {
+static inline unsigned bs_set(struct bitslice bs, unsigned new, unsigned op) {
for(int i = 0; i < bs.nruns; i++) {
const struct bitslice_run *run = &bs.runs[i];
unsigned mask = (1 << run->len) - 1;
- unsigned masked = val & mask;
- if (run->outpos < run->inpos) {
- masked <<= run->inpos - run->outpos;
- mask <<= run->inpos - run->outpos;
- } else if (run->outpos > run->inpos) {
- masked >>= run->outpos - run->inpos;
- mask >>= run->outpos - run->inpos;
- }
- op = (op & ~mask) | masked;
+ unsigned val = (new >> run->outpos) & mask;
+ op = (op & ~(mask << run->inpos)) | (val << run->inpos);
}
return op;
}
+
+static inline struct bitslice bs_slice_(struct bitslice bs, struct bitslice_run *runs, int lo, int size) {
+ int nruns = 0;
+ for(int i = 0; i < bs.nruns; i++) {
+ struct bitslice_run inr = bs.runs[i];
+ inr.outpos -= lo;
+ if(inr.outpos < 0) {
+ inr.len += inr.outpos;
+ inr.inpos -= inr.outpos;
+ inr.outpos = 0;
+ }
+ if(inr.outpos + inr.len > size)
+ inr.len = size - inr.outpos;
+ if(inr.len > 0)
+ runs[nruns++] = (struct bitslice_run) {inr.inpos, inr.outpos, inr.len};
+ }
+ return (struct bitslice) {nruns, runs};
+}
+#define bs_slice(bs, lo, size) \
+ bs_slice_(bs, alloca((bs).nruns * sizeof(struct bitslice_run)), lo, size)
+