Semantics for load/store acquire/release instructions (non-SIMD)
[dyninst.git] / dataflowAPI / rose / semantics / DispatcherARM64.C
1 #include "../util/StringUtility.h"
2 //#include "sage3basic.h"
3 #include "BaseSemantics2.h"
4 //#include "Diagnostics.h"
5 #include "DispatcherARM64.h"
6 #include "../integerOps.h"
7 #include "SymEvalSemantics.h"
8
9 #include "../SgAsmExpression.h"
10 #include "../conversions.h"
11
12 #undef si_value                                         // name pollution from siginfo.h
13
14 namespace rose {
15     namespace BinaryAnalysis {
16         namespace InstructionSemantics2 {
17
18 #define EXTR(lo, hi)    IntegerOps::extract2<B>(lo, hi, raw)
19
20 /*******************************************************************************************************************************
21  *                                      Support functions
22  *******************************************************************************************************************************/
23
24             static inline size_t asm_type_width(SgAsmType *ty) {
25                 ASSERT_not_null(ty);
26                 return ty->get_nBits();
27             }
28
29 /*******************************************************************************************************************************
30  *                                      Base ARM64 instruction processor
31  *******************************************************************************************************************************/
32             namespace ARM64 {
33
34                 void
35                 InsnProcessor::process(const BaseSemantics::DispatcherPtr &dispatcher_, SgAsmInstruction *insn_) {
36                     DispatcherARM64Ptr dispatcher = DispatcherARM64::promote(dispatcher_);
37                     BaseSemantics::RiscOperatorsPtr operators = dispatcher->get_operators();
38                     SgAsmArmv8Instruction *insn = isSgAsmArmv8Instruction(insn_);
39                     ASSERT_require(insn != NULL && insn == operators->currentInstruction());
40                     dispatcher->advanceInstructionPointer(insn);
41                     SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands();
42                     //check_arg_width(dispatcher.get(), insn, operands);
43
44                     uint32_t raw = 0;
45                     std::vector<unsigned char> rawBytes = insn->get_raw_bytes();
46                     for (int idx = 0; idx < rawBytes.size(); idx++) {
47                         raw |= (rawBytes[idx] << (8 * idx));
48                     }
49                     p(dispatcher.get(), operators.get(), insn, operands, raw);
50                 }
51
52                 void
53                 InsnProcessor::assert_args(I insn, A args, size_t nargs) {
54                     if (args.size() != nargs) {
55                         std::string mesg = "instruction has incorrect number of args";
56                         throw BaseSemantics::Exception(mesg, insn);
57                     }
58                 }
59
60 /*******************************************************************************************************************************
61  *                                      Functors that handle individual ARM64 instructions kinds
62  *******************************************************************************************************************************/
63                 typedef InsnProcessor P;
64
65                 struct IP_add_addsub_imm_execute : P {
66                     void p(D d, Ops ops, I insn, A args, B raw) {
67                         BaseSemantics::SValuePtr result;
68                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
69                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
70                         BaseSemantics::SValuePtr n, z, c, v;
71                         bool carry_in;
72
73                         if ((EXTR(30, 30) == 1)) {
74                             operand2 = d->NOT(operand2);
75                             carry_in = true;
76                         } else {
77                             carry_in = false;
78                         }
79                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
80
81                         if ((EXTR(29, 29) == 1)) {
82                             d->writeRegister(d->REG_N, n);
83                             d->writeRegister(d->REG_Z, z);
84                             d->writeRegister(d->REG_C, c);
85                             d->writeRegister(d->REG_V, v);
86                         }
87
88                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
89                             d->writeRegister(d->REG_SP, result);
90                         } else {
91                             d->write(args[0], result);
92                         }
93
94                     }
95                 };
96
97                 struct IP_adds_addsub_imm_execute : P {
98                     void p(D d, Ops ops, I insn, A args, B raw) {
99                         BaseSemantics::SValuePtr result;
100                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
101                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
102                         BaseSemantics::SValuePtr n, z, c, v;
103                         bool carry_in;
104
105                         if ((EXTR(30, 30) == 1)) {
106                             operand2 = d->NOT(operand2);
107                             carry_in = true;
108                         } else {
109                             carry_in = false;
110                         }
111                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
112
113                         if ((EXTR(29, 29) == 1)) {
114                             d->writeRegister(d->REG_N, n);
115                             d->writeRegister(d->REG_Z, z);
116                             d->writeRegister(d->REG_C, c);
117                             d->writeRegister(d->REG_V, v);
118                         }
119
120                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
121                             d->writeRegister(d->REG_SP, result);
122                         } else {
123                             d->write(args[0], result);
124                         }
125
126                     }
127                 };
128
129                 struct IP_sub_addsub_imm_execute : P {
130                     void p(D d, Ops ops, I insn, A args, B raw) {
131                         BaseSemantics::SValuePtr result;
132                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
133                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
134                         BaseSemantics::SValuePtr n, z, c, v;
135                         bool carry_in;
136
137                         if ((EXTR(30, 30) == 1)) {
138                             operand2 = d->NOT(operand2);
139                             carry_in = true;
140                         } else {
141                             carry_in = false;
142                         }
143                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
144
145                         if ((EXTR(29, 29) == 1)) {
146                             d->writeRegister(d->REG_N, n);
147                             d->writeRegister(d->REG_Z, z);
148                             d->writeRegister(d->REG_C, c);
149                             d->writeRegister(d->REG_V, v);
150                         }
151
152                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
153                             d->writeRegister(d->REG_SP, result);
154                         } else {
155                             d->write(args[0], result);
156                         }
157
158                     }
159                 };
160
161                 struct IP_subs_addsub_imm_execute : P {
162                     void p(D d, Ops ops, I insn, A args, B raw) {
163                         BaseSemantics::SValuePtr result;
164                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
165                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
166                         BaseSemantics::SValuePtr n, z, c, v;
167                         bool carry_in;
168
169                         if ((EXTR(30, 30) == 1)) {
170                             operand2 = d->NOT(operand2);
171                             carry_in = true;
172                         } else {
173                             carry_in = false;
174                         }
175                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
176
177                         if ((EXTR(29, 29) == 1)) {
178                             d->writeRegister(d->REG_N, n);
179                             d->writeRegister(d->REG_Z, z);
180                             d->writeRegister(d->REG_C, c);
181                             d->writeRegister(d->REG_V, v);
182                         }
183
184                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
185                             d->writeRegister(d->REG_SP, result);
186                         } else {
187                             d->write(args[0], result);
188                         }
189
190                     }
191                 };
192
193                 struct IP_add_addsub_ext_execute : P {
194                     void p(D d, Ops ops, I insn, A args, B raw) {
195                         BaseSemantics::SValuePtr result;
196                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
197                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
198                         BaseSemantics::SValuePtr n, z, c, v;
199                         bool carry_in;
200
201                         if ((EXTR(30, 30) == 1)) {
202                             operand2 = d->NOT(operand2);
203                             carry_in = true;
204                         } else {
205                             carry_in = false;
206                         }
207                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
208
209                         if ((EXTR(29, 29) == 1)) {
210                             d->writeRegister(d->REG_N, n);
211                             d->writeRegister(d->REG_Z, z);
212                             d->writeRegister(d->REG_C, c);
213                             d->writeRegister(d->REG_V, v);
214                         }
215
216                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
217                             d->writeRegister(d->REG_SP, result);
218                         } else {
219                             d->write(args[0], result);
220                         }
221
222                     }
223                 };
224
225                 struct IP_adds_addsub_ext_execute : P {
226                     void p(D d, Ops ops, I insn, A args, B raw) {
227                         BaseSemantics::SValuePtr result;
228                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
229                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
230                         BaseSemantics::SValuePtr n, z, c, v;
231                         bool carry_in;
232
233                         if ((EXTR(30, 30) == 1)) {
234                             operand2 = d->NOT(operand2);
235                             carry_in = true;
236                         } else {
237                             carry_in = false;
238                         }
239                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
240
241                         if ((EXTR(29, 29) == 1)) {
242                             d->writeRegister(d->REG_N, n);
243                             d->writeRegister(d->REG_Z, z);
244                             d->writeRegister(d->REG_C, c);
245                             d->writeRegister(d->REG_V, v);
246                         }
247
248                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
249                             d->writeRegister(d->REG_SP, result);
250                         } else {
251                             d->write(args[0], result);
252                         }
253
254                     }
255                 };
256
257                 struct IP_sub_addsub_ext_execute : P {
258                     void p(D d, Ops ops, I insn, A args, B raw) {
259                         BaseSemantics::SValuePtr result;
260                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
261                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
262                         BaseSemantics::SValuePtr n, z, c, v;
263                         bool carry_in;
264
265                         if ((EXTR(30, 30) == 1)) {
266                             operand2 = d->NOT(operand2);
267                             carry_in = true;
268                         } else {
269                             carry_in = false;
270                         }
271                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
272
273                         if ((EXTR(29, 29) == 1)) {
274                             d->writeRegister(d->REG_N, n);
275                             d->writeRegister(d->REG_Z, z);
276                             d->writeRegister(d->REG_C, c);
277                             d->writeRegister(d->REG_V, v);
278                         }
279
280                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
281                             d->writeRegister(d->REG_SP, result);
282                         } else {
283                             d->write(args[0], result);
284                         }
285
286                     }
287                 };
288
289                 struct IP_subs_addsub_ext_execute : P {
290                     void p(D d, Ops ops, I insn, A args, B raw) {
291                         BaseSemantics::SValuePtr result;
292                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
293                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
294                         BaseSemantics::SValuePtr n, z, c, v;
295                         bool carry_in;
296
297                         if ((EXTR(30, 30) == 1)) {
298                             operand2 = d->NOT(operand2);
299                             carry_in = true;
300                         } else {
301                             carry_in = false;
302                         }
303                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
304
305                         if ((EXTR(29, 29) == 1)) {
306                             d->writeRegister(d->REG_N, n);
307                             d->writeRegister(d->REG_Z, z);
308                             d->writeRegister(d->REG_C, c);
309                             d->writeRegister(d->REG_V, v);
310                         }
311
312                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
313                             d->writeRegister(d->REG_SP, result);
314                         } else {
315                             d->write(args[0], result);
316                         }
317
318                     }
319                 };
320
321                 struct IP_add_addsub_shift_execute : P {
322                     void p(D d, Ops ops, I insn, A args, B raw) {
323                         BaseSemantics::SValuePtr result;
324                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
325                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
326                         BaseSemantics::SValuePtr n, z, c, v;
327                         bool carry_in;
328
329                         if ((EXTR(30, 30) == 1)) {
330                             operand2 = d->NOT(operand2);
331                             carry_in = true;
332                         } else {
333                             carry_in = false;
334                         }
335                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
336
337                         if ((EXTR(29, 29) == 1)) {
338                             d->writeRegister(d->REG_N, n);
339                             d->writeRegister(d->REG_Z, z);
340                             d->writeRegister(d->REG_C, c);
341                             d->writeRegister(d->REG_V, v);
342                         }
343                         d->write(args[0], result);
344
345                     }
346                 };
347
348                 struct IP_adds_addsub_shift_execute : P {
349                     void p(D d, Ops ops, I insn, A args, B raw) {
350                         BaseSemantics::SValuePtr result;
351                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
352                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
353                         BaseSemantics::SValuePtr n, z, c, v;
354                         bool carry_in;
355
356                         if ((EXTR(30, 30) == 1)) {
357                             operand2 = d->NOT(operand2);
358                             carry_in = true;
359                         } else {
360                             carry_in = false;
361                         }
362                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
363
364                         if ((EXTR(29, 29) == 1)) {
365                             d->writeRegister(d->REG_N, n);
366                             d->writeRegister(d->REG_Z, z);
367                             d->writeRegister(d->REG_C, c);
368                             d->writeRegister(d->REG_V, v);
369                         }
370                         d->write(args[0], result);
371
372                     }
373                 };
374
375                 struct IP_sub_addsub_shift_execute : P {
376                     void p(D d, Ops ops, I insn, A args, B raw) {
377                         BaseSemantics::SValuePtr result;
378                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
379                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
380                         BaseSemantics::SValuePtr n, z, c, v;
381                         bool carry_in;
382
383                         if ((EXTR(30, 30) == 1)) {
384                             operand2 = d->NOT(operand2);
385                             carry_in = true;
386                         } else {
387                             carry_in = false;
388                         }
389                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
390
391                         if ((EXTR(29, 29) == 1)) {
392                             d->writeRegister(d->REG_N, n);
393                             d->writeRegister(d->REG_Z, z);
394                             d->writeRegister(d->REG_C, c);
395                             d->writeRegister(d->REG_V, v);
396                         }
397                         d->write(args[0], result);
398
399                     }
400                 };
401
402                 struct IP_subs_addsub_shift_execute : P {
403                     void p(D d, Ops ops, I insn, A args, B raw) {
404                         BaseSemantics::SValuePtr result;
405                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
406                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
407                         BaseSemantics::SValuePtr n, z, c, v;
408                         bool carry_in;
409
410                         if ((EXTR(30, 30) == 1)) {
411                             operand2 = d->NOT(operand2);
412                             carry_in = true;
413                         } else {
414                             carry_in = false;
415                         }
416                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
417
418                         if ((EXTR(29, 29) == 1)) {
419                             d->writeRegister(d->REG_N, n);
420                             d->writeRegister(d->REG_Z, z);
421                             d->writeRegister(d->REG_C, c);
422                             d->writeRegister(d->REG_V, v);
423                         }
424                         d->write(args[0], result);
425
426                     }
427                 };
428
429                 struct IP_adc_execute : P {                                    //
430                     void p(D d, Ops ops, I insn, A args, B raw) {
431                         BaseSemantics::SValuePtr result;
432                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
433                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
434                         BaseSemantics::SValuePtr n, z, c, v;
435
436                         if ((EXTR(30, 30) == 1)) {
437                             operand2 = d->NOT(operand2);
438                         }
439                         result = d->doAddOperation(operand1, operand2, false,
440                                                    d->readRegister(d->REG_C)/*, ops->boolean_(false)*/,
441                                                    n, z, c, v);
442
443                         if ((EXTR(29, 29) == 1)) {
444                             d->writeRegister(d->REG_N, n);
445                             d->writeRegister(d->REG_Z, z);
446                             d->writeRegister(d->REG_C, c);
447                             d->writeRegister(d->REG_V, v);
448                         }
449                         d->write(args[0], result);
450
451                     }
452                 };
453
454                 struct IP_adcs_execute : P {                                    //
455                     void p(D d, Ops ops, I insn, A args, B raw) {
456                         BaseSemantics::SValuePtr result;
457                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
458                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
459                         BaseSemantics::SValuePtr n, z, c, v;
460
461                         if ((EXTR(30, 30) == 1)) {
462                             operand2 = d->NOT(operand2);
463                         }
464                         result = d->doAddOperation(operand1, operand2, false,
465                                                    d->readRegister(d->REG_C)/*, ops->boolean_(false)*/,
466                                                    n, z, c, v);
467
468                         if ((EXTR(29, 29) == 1)) {
469                             d->writeRegister(d->REG_N, n);
470                             d->writeRegister(d->REG_Z, z);
471                             d->writeRegister(d->REG_C, c);
472                             d->writeRegister(d->REG_V, v);
473                         }
474                         d->write(args[0], result);
475
476                     }
477                 };
478
479                 struct IP_adr_execute : P {
480                     void p(D d, Ops ops, I insn, A args, B raw) {
481
482                         BaseSemantics::SValuePtr base = d->readRegister(d->REG_PC);
483
484                         if ((EXTR (31, 31) == 1)) {
485                             base =
486                                     ops->or_(ops->and_(base, ops->number_(64, 0xfffffffffffff000)),
487                                              d->Zeros(12));
488                         }
489
490                         d->write(args[0], ops->add(base, d->read(args[1])));
491                     }
492                 };
493
494                 struct IP_adrp_execute : P {
495                     void p(D d, Ops ops, I insn, A args, B raw) {
496
497                         BaseSemantics::SValuePtr base = d->readRegister(d->REG_PC);
498
499                         if ((EXTR (31, 31) == 1)) {
500                             base =
501                                     ops->or_(ops->and_(base, ops->number_(64, 0xfffffffffffff000)),
502                                              d->Zeros(12));
503                         }
504
505                         d->write(args[0], ops->add(base, d->read(args[1])));
506                     }
507                 };
508
509                 struct IP_b_cond_execute : P {
510                     void p(D d, Ops ops, I insn, A args, B raw) {
511                         d->BranchTo(ops->ite(
512                                 ops->isEqual(d->ConditionHolds(ops->number_(4, EXTR (0, 4))), ops->boolean_(true)),
513                                 d->read(args[0]), d->readRegister(d->REG_PC)));
514                     }
515                 };
516
517                 struct IP_b_uncond_execute : P {
518                     void p(D d, Ops ops, I insn, A args, B raw) {
519                         if (EXTR(31, 31) == 1)
520                             d->writeRegister(d->findRegister("x30", 64),
521                                              ops->add(d->readRegister(d->REG_PC), ops->number_(32, 4)));
522                         d->BranchTo(d->read(args[0]));
523                     }
524                 };
525
526                 struct IP_br_execute : P {
527                     void p(D d, Ops ops, I insn, A args, B raw) {
528
529                         BaseSemantics::SValuePtr target = d->read(args[0]);
530                         if (EXTR (31, 31) == 1)
531                             d->writeRegister(d->findRegister("x30", 64),
532                                              ops->add(d->readRegister(d->REG_PC),
533                                                       ops->number_(32, 4)));
534
535                         d->BranchTo(target);
536                     }
537                 };
538
539                 struct IP_blr_execute : P {
540                     void p(D d, Ops ops, I insn, A args, B raw) {
541
542                         BaseSemantics::SValuePtr target = d->read(args[0]);
543                         if (EXTR (31, 31) == 1)
544                             d->writeRegister(d->findRegister("x30", 64),
545                                              ops->add(d->readRegister(d->REG_PC),
546                                                       ops->number_(32, 4)));
547
548                         d->BranchTo(target);
549                     }
550                 };
551
552                 struct IP_bl_execute : P {
553                     void p(D d, Ops ops, I insn, A args, B raw) {
554
555                         if (EXTR (31, 31) == 1)
556                             d->writeRegister(d->findRegister("x30", 64),
557                                              ops->add(d->readRegister(d->REG_PC),
558                                                       ops->number_(32, 4)));
559
560                         d->BranchTo(d->read(args[0]));
561                     }
562                 };
563
564                 struct IP_cbz_execute : P {                      //
565                     void p(D d, Ops ops, I insn, A args, B raw) {
566
567                         BaseSemantics::SValuePtr operand1 = d->read(args[0]);
568                         d->BranchTo(ops->ite(ops->isEqual(d->isZero(operand1), ops->boolean_(EXTR (24, 24) == 0)),
569                                              d->read(args[1]), d->readRegister(d->REG_PC)));
570                     }
571                 };
572
573                 struct IP_cbnz_execute : P {                      //
574                     void p(D d, Ops ops, I insn, A args, B raw) {
575
576                         BaseSemantics::SValuePtr operand1 = d->read(args[0]);
577                         d->BranchTo(ops->ite(ops->isEqual(d->isZero(operand1), ops->boolean_(EXTR (24, 24) == 0)),
578                                              d->read(args[1]), d->readRegister(d->REG_PC)));
579                     }
580                 };
581
582                 struct IP_tbz_execute : P {                      //
583                     void p(D d, Ops ops, I insn, A args, B raw) {
584
585                         BaseSemantics::SValuePtr operand = d->read(args[0]);
586                         d->BranchTo(ops->ite(ops->isEqual(
587                                 ops->and_(ops->shiftRight(operand, d->read(args[1])), ops->number_(1, 1)),
588                                 ops->number_(1, EXTR (24, 24))),
589                                              d->read(args[2]), d->readRegister(d->REG_PC)));
590                     }
591                 };
592
593                 struct IP_tbnz_execute : P {                      //
594                     void p(D d, Ops ops, I insn, A args, B raw) {
595
596                         BaseSemantics::SValuePtr operand = d->read(args[0]);
597                         d->BranchTo(ops->ite(ops->isEqual(
598                                 ops->and_(ops->shiftRight(operand, d->read(args[1])), ops->number_(1, 1)),
599                                 ops->number_(1, EXTR (24, 24))),
600                                              d->read(args[2]), d->readRegister(d->REG_PC)));
601                     }
602                 };
603
604                 struct IP_cmp_subs_addsub_imm_execute : P {
605                     void p(D d, Ops ops, I insn, A args, B raw) {
606                         BaseSemantics::SValuePtr result;
607                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
608                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
609                         BaseSemantics::SValuePtr n, z, c, v;
610                         bool carry_in;
611
612                         if ((EXTR(30, 30) == 1)) {
613                             operand2 = d->NOT(operand2);
614                             carry_in = true;
615                         } else {
616                             carry_in = false;
617                         }
618                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
619
620                         if ((EXTR(29, 29) == 1)) {
621                             d->writeRegister(d->REG_N, n);
622                             d->writeRegister(d->REG_Z, z);
623                             d->writeRegister(d->REG_C, c);
624                             d->writeRegister(d->REG_V, v);
625                         }
626
627                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
628                             d->writeRegister(d->REG_SP, result);
629                         } else {
630                             d->write(args[0], result);
631                         }
632
633                     }
634                 };
635
636                 struct IP_cmp_subs_addsub_ext_execute : P {
637                     void p(D d, Ops ops, I insn, A args, B raw) {
638                         BaseSemantics::SValuePtr result;
639                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
640                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
641                         BaseSemantics::SValuePtr n, z, c, v;
642                         bool carry_in;
643
644                         if ((EXTR(30, 30) == 1)) {
645                             operand2 = d->NOT(operand2);
646                             carry_in = true;
647                         } else {
648                             carry_in = false;
649                         }
650                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
651
652                         if ((EXTR(29, 29) == 1)) {
653                             d->writeRegister(d->REG_N, n);
654                             d->writeRegister(d->REG_Z, z);
655                             d->writeRegister(d->REG_C, c);
656                             d->writeRegister(d->REG_V, v);
657                         }
658
659                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
660                             d->writeRegister(d->REG_SP, result);
661                         } else {
662                             d->write(args[0], result);
663                         }
664
665                     }
666                 };
667
668                 struct IP_cmp_subs_addsub_shift_execute : P {
669                     void p(D d, Ops ops, I insn, A args, B raw) {
670                         BaseSemantics::SValuePtr result;
671                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
672                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
673                         BaseSemantics::SValuePtr n, z, c, v;
674                         bool carry_in;
675
676                         if ((EXTR(30, 30) == 1)) {
677                             operand2 = d->NOT(operand2);
678                             carry_in = true;
679                         } else {
680                             carry_in = false;
681                         }
682                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
683
684                         if ((EXTR(29, 29) == 1)) {
685                             d->writeRegister(d->REG_N, n);
686                             d->writeRegister(d->REG_Z, z);
687                             d->writeRegister(d->REG_C, c);
688                             d->writeRegister(d->REG_V, v);
689                         }
690                         d->write(args[0], result);
691
692                     }
693                 };
694
695                 struct IP_cmn_adds_addsub_imm_execute : P {
696                     void p(D d, Ops ops, I insn, A args, B raw) {
697                         BaseSemantics::SValuePtr result;
698                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
699                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
700                         BaseSemantics::SValuePtr n, z, c, v;
701                         bool carry_in;
702
703                         if ((EXTR(30, 30) == 1)) {
704                             operand2 = d->NOT(operand2);
705                             carry_in = true;
706                         } else {
707                             carry_in = false;
708                         }
709                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
710
711                         if ((EXTR(29, 29) == 1)) {
712                             d->writeRegister(d->REG_N, n);
713                             d->writeRegister(d->REG_Z, z);
714                             d->writeRegister(d->REG_C, c);
715                             d->writeRegister(d->REG_V, v);
716                         }
717
718                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
719                             d->writeRegister(d->REG_SP, result);
720                         } else {
721                             d->write(args[0], result);
722                         }
723
724                     }
725                 };
726
727                 struct IP_cmn_adds_addsub_ext_execute : P {
728                     void p(D d, Ops ops, I insn, A args, B raw) {
729                         BaseSemantics::SValuePtr result;
730                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
731                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
732                         BaseSemantics::SValuePtr n, z, c, v;
733                         bool carry_in;
734
735                         if ((EXTR(30, 30) == 1)) {
736                             operand2 = d->NOT(operand2);
737                             carry_in = true;
738                         } else {
739                             carry_in = false;
740                         }
741                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
742
743                         if ((EXTR(29, 29) == 1)) {
744                             d->writeRegister(d->REG_N, n);
745                             d->writeRegister(d->REG_Z, z);
746                             d->writeRegister(d->REG_C, c);
747                             d->writeRegister(d->REG_V, v);
748                         }
749
750                         if (EXTR(0, 4) == 31 && !(EXTR(29, 29) == 1)) {
751                             d->writeRegister(d->REG_SP, result);
752                         } else {
753                             d->write(args[0], result);
754                         }
755
756                     }
757                 };
758
759                 struct IP_cmn_adds_addsub_shift_execute : P {
760                     void p(D d, Ops ops, I insn, A args, B raw) {
761                         BaseSemantics::SValuePtr result;
762                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
763                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
764                         BaseSemantics::SValuePtr n, z, c, v;
765                         bool carry_in;
766
767                         if ((EXTR(30, 30) == 1)) {
768                             operand2 = d->NOT(operand2);
769                             carry_in = true;
770                         } else {
771                             carry_in = false;
772                         }
773                         result = d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v);
774
775                         if ((EXTR(29, 29) == 1)) {
776                             d->writeRegister(d->REG_N, n);
777                             d->writeRegister(d->REG_Z, z);
778                             d->writeRegister(d->REG_C, c);
779                             d->writeRegister(d->REG_V, v);
780                         }
781                         d->write(args[0], result);
782
783                     }
784                 };
785
786                 struct IP_ccmn_reg_execute : P {                      //
787                     void p(D d, Ops ops, I insn, A args, B raw) {
788
789                         BaseSemantics::SValuePtr operand1 = d->read(args[0]);
790                         BaseSemantics::SValuePtr operand2 = d->read(args[1]);
791                         BaseSemantics::SValuePtr nzcv = d->read(args[2]);
792                         bool carry_in = false;
793
794                         BaseSemantics::SValuePtr n = ops->extract(nzcv, 3, 4);
795                         BaseSemantics::SValuePtr z = ops->extract(nzcv, 2, 3);
796                         BaseSemantics::SValuePtr c = ops->extract(nzcv, 1, 2);
797                         BaseSemantics::SValuePtr v = ops->extract(nzcv, 0, 1);
798
799                         /*if (d->read(args[3])) {
800                             if ((EXTR (30, 30) == 1)) {
801                                 operand2 = d->NOT(operand2);
802
803                                 carry_in = true;
804
805                             }
806
807                             d->doAddOperation(operand1, operand2, carry_in,
808                                               ops->boolean_(false), nzcv);
809
810                         }*/
811
812                         operand2 = ops->ite(ops->isEqual(d->ConditionHolds(d->read(args[3])), ops->boolean_(true)),
813                                             (EXTR (30, 30) == 1 ? (carry_in = true, d->NOT(operand2)) : operand2),
814                                             operand2);
815                         ops->ite(ops->isEqual(d->ConditionHolds(d->read(args[3])), ops->boolean_(true)),
816                                  d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v),
817                                  ops->unspecified_(1));
818
819                         d->writeRegister(d->REG_N, n);
820                         d->writeRegister(d->REG_Z, z);
821                         d->writeRegister(d->REG_C, c);
822                         d->writeRegister(d->REG_V, v);
823                     }
824                 };
825
826                 struct IP_ccmn_imm_execute : P {                      //
827                     void p(D d, Ops ops, I insn, A args, B raw) {
828
829                         BaseSemantics::SValuePtr operand1 = d->read(args[0]);
830                         BaseSemantics::SValuePtr operand2 = d->read(args[1]);
831                         BaseSemantics::SValuePtr nzcv = d->read(args[2]);
832                         bool carry_in = false;
833
834                         BaseSemantics::SValuePtr n = ops->extract(nzcv, 3, 4);
835                         BaseSemantics::SValuePtr z = ops->extract(nzcv, 2, 3);
836                         BaseSemantics::SValuePtr c = ops->extract(nzcv, 1, 2);
837                         BaseSemantics::SValuePtr v = ops->extract(nzcv, 0, 1);
838
839                         /*if (d->read(args[3])) {
840                             if ((EXTR (30, 30) == 1)) {
841                                 operand2 = d->NOT(operand2);
842
843                                 carry_in = true;
844
845                             }
846
847                             d->doAddOperation(operand1, operand2, carry_in,
848                                               ops->boolean_(false), nzcv);
849
850                         }*/
851
852                         operand2 = ops->ite(ops->isEqual(d->ConditionHolds(d->read(args[3])), ops->boolean_(true)),
853                                             (EXTR (30, 30) == 1 ? (carry_in = true, d->NOT(operand2)) : operand2),
854                                             operand2);
855                         ops->ite(ops->isEqual(d->ConditionHolds(d->read(args[3])), ops->boolean_(true)),
856                                  d->doAddOperation(operand1, operand2, carry_in, ops->boolean_(false), n, z, c, v),
857                                  ops->unspecified_(1));
858
859                         d->writeRegister(d->REG_N, n);
860                         d->writeRegister(d->REG_Z, z);
861                         d->writeRegister(d->REG_C, c);
862                         d->writeRegister(d->REG_V, v);
863                     }
864                 };
865
866                 struct IP_ldr_imm_gen_execute : P {
867                     void p(D d, Ops ops, I insn, A args, B raw) {
868                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
869                         BaseSemantics::SValuePtr data;
870                         bool wb_unknown = false;
871                         bool rt_unknown = false;
872
873                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
874                             address = ops->add(address, d->read(args[2]));
875                         }*/
876
877                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
878                             case MemOp_STORE: {
879
880                                 if (rt_unknown) {
881                                     data = ops->unspecified_(1);
882                                 } else {
883                                     data = d->read(args[0]);
884                                 }
885                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
886                             }
887                                 break;
888                             case MemOp_LOAD: {
889                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
890
891                                 if ((EXTR(23, 23) == 1)) {
892                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
893                                 } else {
894                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
895                                 }
896                             }
897                                 break;
898                         }
899
900                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
901
902                             if (wb_unknown) {
903                                 address = ops->unspecified_(1);
904                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
905                                 address = ops->add(address, d->read(args[2]));
906                             }
907
908                             if (EXTR(5, 9) == 31) {
909                                 d->writeRegister(d->REG_SP, address);
910                             } else {
911                                 d->write(d->getWriteBackTarget(args[1]), address);
912                             }
913                         }
914
915                     }
916                 };
917
918                 struct IP_str_imm_gen_execute : P {
919                     void p(D d, Ops ops, I insn, A args, B raw) {
920                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
921                         BaseSemantics::SValuePtr data;
922                         bool wb_unknown = false;
923                         bool rt_unknown = false;
924
925                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
926                             address = ops->add(address, d->read(args[2]));
927                         }*/
928
929                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
930                             case MemOp_STORE: {
931
932                                 if (rt_unknown) {
933                                     data = ops->unspecified_(1);
934                                 } else {
935                                     data = d->read(args[0]);
936                                 }
937                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
938                             }
939                                 break;
940                             case MemOp_LOAD: {
941                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
942
943                                 if ((EXTR(23, 23) == 1)) {
944                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
945                                 } else {
946                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
947                                 }
948                             }
949                                 break;
950                         }
951
952                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
953
954                             if (wb_unknown) {
955                                 address = ops->unspecified_(1);
956                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
957                                 address = ops->add(address, d->read(args[2]));
958                             }
959
960                             if (EXTR(5, 9) == 31) {
961                                 d->writeRegister(d->REG_SP, address);
962                             } else {
963                                 d->write(d->getWriteBackTarget(args[1]), address);
964                             }
965                         }
966
967                     }
968                 };
969
970                 struct IP_ldrb_imm_execute : P {
971                     void p(D d, Ops ops, I insn, A args, B raw) {
972                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
973                         BaseSemantics::SValuePtr data;
974                         bool wb_unknown = false;
975                         bool rt_unknown = false;
976
977                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
978                             address = ops->add(address, d->read(args[2]));
979                         }*/
980
981                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
982                             case MemOp_STORE: {
983
984                                 if (rt_unknown) {
985                                     data = ops->unspecified_(1);
986                                 } else {
987                                     data = d->read(args[0]);
988                                 }
989                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
990                             }
991                                 break;
992                             case MemOp_LOAD: {
993                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
994
995                                 if ((EXTR(23, 23) == 1)) {
996                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
997                                 } else {
998                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
999                                 }
1000                             }
1001                                 break;
1002                         }
1003
1004                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1005
1006                             if (wb_unknown) {
1007                                 address = ops->unspecified_(1);
1008                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1009                                 address = ops->add(address, d->read(args[2]));
1010                             }
1011
1012                             if (EXTR(5, 9) == 31) {
1013                                 d->writeRegister(d->REG_SP, address);
1014                             } else {
1015                                 d->write(d->getWriteBackTarget(args[1]), address);
1016                             }
1017                         }
1018
1019                     }
1020                 };
1021
1022                 struct IP_strb_imm_execute : P {
1023                     void p(D d, Ops ops, I insn, A args, B raw) {
1024                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1025                         BaseSemantics::SValuePtr data;
1026                         bool wb_unknown = false;
1027                         bool rt_unknown = false;
1028
1029                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1030                             address = ops->add(address, d->read(args[2]));
1031                         }*/
1032
1033                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1034                             case MemOp_STORE: {
1035
1036                                 if (rt_unknown) {
1037                                     data = ops->unspecified_(1);
1038                                 } else {
1039                                     data = d->read(args[0]);
1040                                 }
1041                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1042                             }
1043                                 break;
1044                             case MemOp_LOAD: {
1045                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1046
1047                                 if ((EXTR(23, 23) == 1)) {
1048                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1049                                 } else {
1050                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1051                                 }
1052                             }
1053                                 break;
1054                         }
1055
1056                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1057
1058                             if (wb_unknown) {
1059                                 address = ops->unspecified_(1);
1060                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1061                                 address = ops->add(address, d->read(args[2]));
1062                             }
1063
1064                             if (EXTR(5, 9) == 31) {
1065                                 d->writeRegister(d->REG_SP, address);
1066                             } else {
1067                                 d->write(d->getWriteBackTarget(args[1]), address);
1068                             }
1069                         }
1070
1071                     }
1072                 };
1073
1074                 struct IP_ldrh_imm_execute : P {
1075                     void p(D d, Ops ops, I insn, A args, B raw) {
1076                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1077                         BaseSemantics::SValuePtr data;
1078                         bool wb_unknown = false;
1079                         bool rt_unknown = false;
1080
1081                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1082                             address = ops->add(address, d->read(args[2]));
1083                         }*/
1084
1085                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1086                             case MemOp_STORE: {
1087
1088                                 if (rt_unknown) {
1089                                     data = ops->unspecified_(1);
1090                                 } else {
1091                                     data = d->read(args[0]);
1092                                 }
1093                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1094                             }
1095                                 break;
1096                             case MemOp_LOAD: {
1097                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1098
1099                                 if ((EXTR(23, 23) == 1)) {
1100                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1101                                 } else {
1102                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1103                                 }
1104                             }
1105                                 break;
1106                         }
1107
1108                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1109
1110                             if (wb_unknown) {
1111                                 address = ops->unspecified_(1);
1112                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1113                                 address = ops->add(address, d->read(args[2]));
1114                             }
1115
1116                             if (EXTR(5, 9) == 31) {
1117                                 d->writeRegister(d->REG_SP, address);
1118                             } else {
1119                                 d->write(d->getWriteBackTarget(args[1]), address);
1120                             }
1121                         }
1122
1123                     }
1124                 };
1125
1126                 struct IP_ldrsb_imm_execute : P {
1127                     void p(D d, Ops ops, I insn, A args, B raw) {
1128                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1129                         BaseSemantics::SValuePtr data;
1130                         bool wb_unknown = false;
1131                         bool rt_unknown = false;
1132
1133                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1134                             address = ops->add(address, d->read(args[2]));
1135                         }*/
1136
1137                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1138                             case MemOp_STORE: {
1139
1140                                 if (rt_unknown) {
1141                                     data = ops->unspecified_(1);
1142                                 } else {
1143                                     data = d->read(args[0]);
1144                                 }
1145                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1146                             }
1147                                 break;
1148                             case MemOp_LOAD: {
1149                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1150
1151                                 if ((EXTR(23, 23) == 1)) {
1152                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1153                                 } else {
1154                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1155                                 }
1156                             }
1157                                 break;
1158                         }
1159
1160                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1161
1162                             if (wb_unknown) {
1163                                 address = ops->unspecified_(1);
1164                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1165                                 address = ops->add(address, d->read(args[2]));
1166                             }
1167
1168                             if (EXTR(5, 9) == 31) {
1169                                 d->writeRegister(d->REG_SP, address);
1170                             } else {
1171                                 d->write(d->getWriteBackTarget(args[1]), address);
1172                             }
1173                         }
1174
1175                     }
1176                 };
1177
1178                 struct IP_ldrsh_imm_execute : P {
1179                     void p(D d, Ops ops, I insn, A args, B raw) {
1180                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1181                         BaseSemantics::SValuePtr data;
1182                         bool wb_unknown = false;
1183                         bool rt_unknown = false;
1184
1185                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1186                             address = ops->add(address, d->read(args[2]));
1187                         }*/
1188
1189                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1190                             case MemOp_STORE: {
1191
1192                                 if (rt_unknown) {
1193                                     data = ops->unspecified_(1);
1194                                 } else {
1195                                     data = d->read(args[0]);
1196                                 }
1197                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1198                             }
1199                                 break;
1200                             case MemOp_LOAD: {
1201                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1202
1203                                 if ((EXTR(23, 23) == 1)) {
1204                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1205                                 } else {
1206                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1207                                 }
1208                             }
1209                                 break;
1210                         }
1211
1212                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1213
1214                             if (wb_unknown) {
1215                                 address = ops->unspecified_(1);
1216                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1217                                 address = ops->add(address, d->read(args[2]));
1218                             }
1219
1220                             if (EXTR(5, 9) == 31) {
1221                                 d->writeRegister(d->REG_SP, address);
1222                             } else {
1223                                 d->write(d->getWriteBackTarget(args[1]), address);
1224                             }
1225                         }
1226
1227                     }
1228                 };
1229
1230                 struct IP_ldrsw_imm_execute : P {
1231                     void p(D d, Ops ops, I insn, A args, B raw) {
1232                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1233                         BaseSemantics::SValuePtr data;
1234                         bool wb_unknown = false;
1235                         bool rt_unknown = false;
1236
1237                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1238                             address = ops->add(address, d->read(args[2]));
1239                         }*/
1240
1241                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1242                             case MemOp_STORE: {
1243
1244                                 if (rt_unknown) {
1245                                     data = ops->unspecified_(1);
1246                                 } else {
1247                                     data = d->read(args[0]);
1248                                 }
1249                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1250                             }
1251                                 break;
1252                             case MemOp_LOAD: {
1253 //                                               fprintf(stderr, "xxx %d %d\n", 0x8 << EXTR(30, 31), EXTR(30, 31));
1254                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1255
1256                                 if ((EXTR(23, 23) == 1)) {
1257                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1258                                 } else {
1259                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1260                                 }
1261                             }
1262                                 break;
1263                         }
1264
1265                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1266
1267                             if (wb_unknown) {
1268                                 address = ops->unspecified_(1);
1269                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1270                                 address = ops->add(address, d->read(args[2]));
1271                             }
1272
1273                             if (EXTR(5, 9) == 31) {
1274                                 d->writeRegister(d->REG_SP, address);
1275                             } else {
1276                                 d->write(d->getWriteBackTarget(args[1]), address);
1277                             }
1278                         }
1279
1280                     }
1281                 };
1282
1283                 struct IP_strh_imm_execute : P {
1284                     void p(D d, Ops ops, I insn, A args, B raw) {
1285                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1286                         BaseSemantics::SValuePtr data;
1287                         bool wb_unknown = false;
1288                         bool rt_unknown = false;
1289
1290                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1291                             address = ops->add(address, d->read(args[2]));
1292                         }*/
1293
1294                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1295                             case MemOp_STORE: {
1296
1297                                 if (rt_unknown) {
1298                                     data = ops->unspecified_(1);
1299                                 } else {
1300                                     data = d->read(args[0]);
1301                                 }
1302                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1303                             }
1304                                 break;
1305                             case MemOp_LOAD: {
1306                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1307
1308                                 if ((EXTR(23, 23) == 1)) {
1309                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1310                                 } else {
1311                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1312                                 }
1313                             }
1314                                 break;
1315                         }
1316
1317                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1318
1319                             if (wb_unknown) {
1320                                 address = ops->unspecified_(1);
1321                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1322                                 address = ops->add(address, d->read(args[2]));
1323                             }
1324
1325                             if (EXTR(5, 9) == 31) {
1326                                 d->writeRegister(d->REG_SP, address);
1327                             } else {
1328                                 d->write(d->getWriteBackTarget(args[1]), address);
1329                             }
1330                         }
1331
1332                     }
1333                 };
1334
1335                 struct IP_ldr_reg_gen_execute : P {
1336                     void p(D d, Ops ops, I insn, A args, B raw) {
1337                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1338                         BaseSemantics::SValuePtr data;
1339                         bool wb_unknown = false;
1340                         bool rt_unknown = false;
1341
1342                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1343                             address = ops->add(address, d->read(args[2]));
1344                         }*/
1345
1346                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1347                             case MemOp_STORE: {
1348
1349                                 if (rt_unknown) {
1350                                     data = ops->unspecified_(1);
1351                                 } else {
1352                                     data = d->read(args[0]);
1353                                 }
1354                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1355                             }
1356                                 break;
1357                             case MemOp_LOAD: {
1358                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1359
1360                                 if ((EXTR(23, 23) == 1)) {
1361                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1362                                 } else {
1363                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1364                                 }
1365                             }
1366                                 break;
1367                         }
1368
1369                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1370
1371                             if (wb_unknown) {
1372                                 address = ops->unspecified_(1);
1373                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1374                                 address = ops->add(address, d->read(args[2]));
1375                             }
1376
1377                             if (EXTR(5, 9) == 31) {
1378                                 d->writeRegister(d->REG_SP, address);
1379                             } else {
1380                                 d->write(d->getWriteBackTarget(args[1]), address);
1381                             }
1382                         }
1383
1384                     }
1385                 };
1386
1387                 struct IP_ldrb_reg_execute : P {
1388                     void p(D d, Ops ops, I insn, A args, B raw) {
1389                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1390                         BaseSemantics::SValuePtr data;
1391                         bool wb_unknown = false;
1392                         bool rt_unknown = false;
1393
1394                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1395                             address = ops->add(address, d->read(args[2]));
1396                         }*/
1397
1398                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1399                             case MemOp_STORE: {
1400
1401                                 if (rt_unknown) {
1402                                     data = ops->unspecified_(1);
1403                                 } else {
1404                                     data = d->read(args[0]);
1405                                 }
1406                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1407                             }
1408                                 break;
1409                             case MemOp_LOAD: {
1410                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1411
1412                                 if ((EXTR(23, 23) == 1)) {
1413                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1414                                 } else {
1415                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1416                                 }
1417                             }
1418                                 break;
1419                         }
1420
1421                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1422
1423                             if (wb_unknown) {
1424                                 address = ops->unspecified_(1);
1425                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1426                                 address = ops->add(address, d->read(args[2]));
1427                             }
1428
1429                             if (EXTR(5, 9) == 31) {
1430                                 d->writeRegister(d->REG_SP, address);
1431                             } else {
1432                                 d->write(d->getWriteBackTarget(args[1]), address);
1433                             }
1434                         }
1435
1436                     }
1437                 };
1438
1439                 struct IP_ldrh_reg_execute : P {
1440                     void p(D d, Ops ops, I insn, A args, B raw) {
1441                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1442                         BaseSemantics::SValuePtr data;
1443                         bool wb_unknown = false;
1444                         bool rt_unknown = false;
1445
1446                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1447                             address = ops->add(address, d->read(args[2]));
1448                         }*/
1449
1450                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1451                             case MemOp_STORE: {
1452
1453                                 if (rt_unknown) {
1454                                     data = ops->unspecified_(1);
1455                                 } else {
1456                                     data = d->read(args[0]);
1457                                 }
1458                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1459                             }
1460                                 break;
1461                             case MemOp_LOAD: {
1462                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1463
1464                                 if ((EXTR(23, 23) == 1)) {
1465                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1466                                 } else {
1467                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1468                                 }
1469                             }
1470                                 break;
1471                         }
1472
1473                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1474
1475                             if (wb_unknown) {
1476                                 address = ops->unspecified_(1);
1477                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1478                                 address = ops->add(address, d->read(args[2]));
1479                             }
1480
1481                             if (EXTR(5, 9) == 31) {
1482                                 d->writeRegister(d->REG_SP, address);
1483                             } else {
1484                                 d->write(d->getWriteBackTarget(args[1]), address);
1485                             }
1486                         }
1487
1488                     }
1489                 };
1490
1491                 struct IP_ldrsb_reg_execute : P {
1492                     void p(D d, Ops ops, I insn, A args, B raw) {
1493                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1494                         BaseSemantics::SValuePtr data;
1495                         bool wb_unknown = false;
1496                         bool rt_unknown = false;
1497
1498                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1499                             address = ops->add(address, d->read(args[2]));
1500                         }*/
1501
1502                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1503                             case MemOp_STORE: {
1504
1505                                 if (rt_unknown) {
1506                                     data = ops->unspecified_(1);
1507                                 } else {
1508                                     data = d->read(args[0]);
1509                                 }
1510                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1511                             }
1512                                 break;
1513                             case MemOp_LOAD: {
1514                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1515
1516                                 if ((EXTR(23, 23) == 1)) {
1517                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1518                                 } else {
1519                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1520                                 }
1521                             }
1522                                 break;
1523                         }
1524
1525                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1526
1527                             if (wb_unknown) {
1528                                 address = ops->unspecified_(1);
1529                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1530                                 address = ops->add(address, d->read(args[2]));
1531                             }
1532
1533                             if (EXTR(5, 9) == 31) {
1534                                 d->writeRegister(d->REG_SP, address);
1535                             } else {
1536                                 d->write(d->getWriteBackTarget(args[1]), address);
1537                             }
1538                         }
1539
1540                     }
1541                 };
1542
1543                 struct IP_ldrsh_reg_execute : P {
1544                     void p(D d, Ops ops, I insn, A args, B raw) {
1545                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1546                         BaseSemantics::SValuePtr data;
1547                         bool wb_unknown = false;
1548                         bool rt_unknown = false;
1549
1550                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1551                             address = ops->add(address, d->read(args[2]));
1552                         }*/
1553
1554                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1555                             case MemOp_STORE: {
1556
1557                                 if (rt_unknown) {
1558                                     data = ops->unspecified_(1);
1559                                 } else {
1560                                     data = d->read(args[0]);
1561                                 }
1562                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1563                             }
1564                                 break;
1565                             case MemOp_LOAD: {
1566                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1567
1568                                 if ((EXTR(23, 23) == 1)) {
1569                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1570                                 } else {
1571                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1572                                 }
1573                             }
1574                                 break;
1575                         }
1576
1577                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1578
1579                             if (wb_unknown) {
1580                                 address = ops->unspecified_(1);
1581                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1582                                 address = ops->add(address, d->read(args[2]));
1583                             }
1584
1585                             if (EXTR(5, 9) == 31) {
1586                                 d->writeRegister(d->REG_SP, address);
1587                             } else {
1588                                 d->write(d->getWriteBackTarget(args[1]), address);
1589                             }
1590                         }
1591
1592                     }
1593                 };
1594
1595                 struct IP_ldrsw_reg_execute : P {
1596                     void p(D d, Ops ops, I insn, A args, B raw) {
1597                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1598                         BaseSemantics::SValuePtr data;
1599                         bool wb_unknown = false;
1600                         bool rt_unknown = false;
1601
1602                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1603                             address = ops->add(address, d->read(args[2]));
1604                         }*/
1605
1606                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1607                             case MemOp_STORE: {
1608
1609                                 if (rt_unknown) {
1610                                     data = ops->unspecified_(1);
1611                                 } else {
1612                                     data = d->read(args[0]);
1613                                 }
1614                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1615                             }
1616                                 break;
1617                             case MemOp_LOAD: {
1618                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1619
1620                                 if ((EXTR(23, 23) == 1)) {
1621                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1622                                 } else {
1623                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1624                                 }
1625                             }
1626                                 break;
1627                         }
1628
1629                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1630
1631                             if (wb_unknown) {
1632                                 address = ops->unspecified_(1);
1633                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1634                                 address = ops->add(address, d->read(args[2]));
1635                             }
1636
1637                             if (EXTR(5, 9) == 31) {
1638                                 d->writeRegister(d->REG_SP, address);
1639                             } else {
1640                                 d->write(d->getWriteBackTarget(args[1]), address);
1641                             }
1642                         }
1643
1644                     }
1645                 };
1646
1647                 struct IP_str_reg_gen_execute : P {
1648                     void p(D d, Ops ops, I insn, A args, B raw) {
1649                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1650                         BaseSemantics::SValuePtr data;
1651                         bool wb_unknown = false;
1652                         bool rt_unknown = false;
1653
1654                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1655                             address = ops->add(address, d->read(args[2]));
1656                         }*/
1657
1658                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1659                             case MemOp_STORE: {
1660
1661                                 if (rt_unknown) {
1662                                     data = ops->unspecified_(1);
1663                                 } else {
1664                                     data = d->read(args[0]);
1665                                 }
1666                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1667                             }
1668                                 break;
1669                             case MemOp_LOAD: {
1670                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1671
1672                                 if ((EXTR(23, 23) == 1)) {
1673                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1674                                 } else {
1675                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1676                                 }
1677                             }
1678                                 break;
1679                         }
1680
1681                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1682
1683                             if (wb_unknown) {
1684                                 address = ops->unspecified_(1);
1685                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1686                                 address = ops->add(address, d->read(args[2]));
1687                             }
1688
1689                             if (EXTR(5, 9) == 31) {
1690                                 d->writeRegister(d->REG_SP, address);
1691                             } else {
1692                                 d->write(d->getWriteBackTarget(args[1]), address);
1693                             }
1694                         }
1695
1696                     }
1697                 };
1698
1699                 struct IP_strb_reg_execute : P {
1700                     void p(D d, Ops ops, I insn, A args, B raw) {
1701                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1702                         BaseSemantics::SValuePtr data;
1703                         bool wb_unknown = false;
1704                         bool rt_unknown = false;
1705
1706                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1707                             address = ops->add(address, d->read(args[2]));
1708                         }*/
1709
1710                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1711                             case MemOp_STORE: {
1712
1713                                 if (rt_unknown) {
1714                                     data = ops->unspecified_(1);
1715                                 } else {
1716                                     data = d->read(args[0]);
1717                                 }
1718                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1719                             }
1720                                 break;
1721                             case MemOp_LOAD: {
1722                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1723
1724                                 if ((EXTR(23, 23) == 1)) {
1725                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1726                                 } else {
1727                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1728                                 }
1729                             }
1730                                 break;
1731                         }
1732
1733                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1734
1735                             if (wb_unknown) {
1736                                 address = ops->unspecified_(1);
1737                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1738                                 address = ops->add(address, d->read(args[2]));
1739                             }
1740
1741                             if (EXTR(5, 9) == 31) {
1742                                 d->writeRegister(d->REG_SP, address);
1743                             } else {
1744                                 d->write(d->getWriteBackTarget(args[1]), address);
1745                             }
1746                         }
1747
1748                     }
1749                 };
1750
1751                 struct IP_strh_reg_execute : P {
1752                     void p(D d, Ops ops, I insn, A args, B raw) {
1753                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1754                         BaseSemantics::SValuePtr data;
1755                         bool wb_unknown = false;
1756                         bool rt_unknown = false;
1757
1758                         /*if (!(EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1759                             address = ops->add(address, d->read(args[2]));
1760                         }*/
1761
1762                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1763                             case MemOp_STORE: {
1764
1765                                 if (rt_unknown) {
1766                                     data = ops->unspecified_(1);
1767                                 } else {
1768                                     data = d->read(args[0]);
1769                                 }
1770                                 d->writeMemory(address, 0x8 << EXTR(30, 31), data);
1771                             }
1772                                 break;
1773                             case MemOp_LOAD: {
1774                                 data = d->readMemory(address, 0x8 << EXTR(30, 31));
1775
1776                                 if ((EXTR(23, 23) == 1)) {
1777                                     d->write(args[0], d->SignExtend(data, d->getRegSize(raw)));
1778                                 } else {
1779                                     d->write(args[0], d->ZeroExtend(data, d->getRegSize(raw)));
1780                                 }
1781                             }
1782                                 break;
1783                         }
1784
1785                         if (((EXTR(24, 24) == 0) && EXTR(21, 21) == 0)) {
1786
1787                             if (wb_unknown) {
1788                                 address = ops->unspecified_(1);
1789                             } else if ((EXTR(11, 11) == 0 && EXTR(24, 24) == 0)) {
1790                                 address = ops->add(address, d->read(args[2]));
1791                             }
1792
1793                             if (EXTR(5, 9) == 31) {
1794                                 d->writeRegister(d->REG_SP, address);
1795                             } else {
1796                                 d->write(d->getWriteBackTarget(args[1]), address);
1797                             }
1798                         }
1799
1800                     }
1801                 };
1802
1803                 struct IP_ldr_lit_gen_execute : P {
1804                     void p(D d, Ops ops, I insn, A args, B raw) {
1805                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1806                         BaseSemantics::SValuePtr data;
1807
1808                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1809                             case MemOp_LOAD: {
1810                                 data = d->readMemory(address, d->ldStrLiteralAccessSize(raw));
1811
1812                                 if ((EXTR(23, 23) == 1)) {
1813                                     d->write(args[0], d->SignExtend(data, 64));
1814                                 } else {
1815                                     d->write(args[0], data);
1816                                 }
1817                             }
1818                                 break;
1819                         }
1820
1821                     }
1822                 };
1823
1824                 struct IP_ldrsw_lit_execute : P {
1825                     void p(D d, Ops ops, I insn, A args, B raw) {
1826                         BaseSemantics::SValuePtr address = d->effectiveAddress(args[1]);
1827                         BaseSemantics::SValuePtr data;
1828
1829                         switch ((EXTR(22, 22) ^ EXTR(23, 23))) {
1830                             case MemOp_LOAD: {
1831                                 data = d->readMemory(address, d->ldStrLiteralAccessSize(raw));
1832
1833                                 if ((EXTR(23, 23) == 1)) {
1834                                     d->write(args[0], d->SignExtend(data, 64));
1835                                 } else {
1836                                     d->write(args[0], data);
1837                                 }
1838                             }
1839                                 break;
1840                         }
1841
1842                     }
1843                 };
1844
1845                 //TODO: For ubfm/sbfm based instructions, update the grammar to declare variables for imms/immr and wmask/tmask instead of reading/calculating them twice
1846                 struct IP_ubfm_execute : P {
1847                     void p(D d, Ops ops, I insn, A args, B raw) {
1848                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1849                                                                             false, (EXTR(31, 31) + 1) * 32);
1850                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1851                                                                             true, (EXTR(31, 31) + 1) * 32);
1852                         BaseSemantics::SValuePtr dst;
1853                         if (d->inzero(raw))
1854                             dst = d->Zeros(64);
1855                         else
1856                             dst = d->read(args[0]);
1857                         BaseSemantics::SValuePtr src = d->read(args[1]);
1858                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
1859                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
1860                         BaseSemantics::SValuePtr top;
1861                         if (d->extend(raw))
1862                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
1863                         else
1864                             top = dst;
1865                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1866
1867                     }
1868                 };
1869
1870                 //TODO modified manually for jump table analysis
1871                 struct IP_uxtb_ubfm_execute : P {
1872                     void p(D d, Ops ops, I insn, A args, B raw) {
1873                         /*BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22), false, (EXTR(31, 31) + 1) * 32);
1874                             BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22), true, (EXTR(31, 31) + 1) * 32);
1875                             BaseSemantics::SValuePtr dst;
1876                             if (d->inzero(raw))
1877                             dst = d->Zeros(64);
1878                             else
1879                             dst = d->read(args[0]);
1880                             BaseSemantics::SValuePtr src = d->read(args[1]);
1881                             BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)), ops->and_(d->ROR(src, ops->number_(32, EXTR(16, 21))), wmask));
1882                             BaseSemantics::SValuePtr top;
1883                             if (d->extend(raw))
1884                             top = d->Replicate(ops->and_(ops->shiftRight(src, ops->number_(32, EXTR(10, 15))), ops->number_(1, 1)));
1885                             else
1886                             top = dst;
1887                             d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1888                             */
1889                         BaseSemantics::SValuePtr src = d->read(args[1]);
1890                         BaseSemantics::SValuePtr writeVal = ops->extract(src, 0, 8);
1891                         d->write(args[0], ops->unsignedExtend(writeVal, 32));
1892                     }
1893                 };
1894
1895                 struct IP_uxth_ubfm_execute : P {
1896                     void p(D d, Ops ops, I insn, A args, B raw) {
1897                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1898                                                                             false, (EXTR(31, 31) + 1) * 32);
1899                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1900                                                                             true, (EXTR(31, 31) + 1) * 32);
1901                         BaseSemantics::SValuePtr dst;
1902                         if (d->inzero(raw))
1903                             dst = d->Zeros(64);
1904                         else
1905                             dst = d->read(args[0]);
1906                         BaseSemantics::SValuePtr src = d->read(args[1]);
1907                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
1908                                                                 ops->and_(d->ROR(src, ops->number_(32, EXTR(16, 21))),
1909                                                                           wmask));
1910                         BaseSemantics::SValuePtr top;
1911                         if (d->extend(raw))
1912                             top = d->Replicate(ops->and_(ops->shiftRight(src, ops->number_(32, EXTR(10, 15))),
1913                                                          ops->number_(1, 1)));
1914                         else
1915                             top = dst;
1916                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1917
1918                     }
1919                 };
1920
1921                 struct IP_ubfiz_ubfm_execute : P {
1922                     void p(D d, Ops ops, I insn, A args, B raw) {
1923                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1924                                                                             false, (EXTR(31, 31) + 1) * 32);
1925                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1926                                                                             true, (EXTR(31, 31) + 1) * 32);
1927                         BaseSemantics::SValuePtr dst;
1928                         if (d->inzero(raw))
1929                             dst = d->Zeros(64);
1930                         else
1931                             dst = d->read(args[0]);
1932                         BaseSemantics::SValuePtr src = d->read(args[1]);
1933                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
1934                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
1935                         BaseSemantics::SValuePtr top;
1936                         if (d->extend(raw))
1937                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
1938                         else
1939                             top = dst;
1940                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1941
1942                     }
1943                 };
1944
1945                 struct IP_ubfx_ubfm_execute : P {
1946                     void p(D d, Ops ops, I insn, A args, B raw) {
1947                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1948                                                                             false, (EXTR(31, 31) + 1) * 32);
1949                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1950                                                                             true, (EXTR(31, 31) + 1) * 32);
1951                         BaseSemantics::SValuePtr dst;
1952                         if (d->inzero(raw))
1953                             dst = d->Zeros(64);
1954                         else
1955                             dst = d->read(args[0]);
1956                         BaseSemantics::SValuePtr src = d->read(args[1]);
1957                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
1958                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
1959                         BaseSemantics::SValuePtr top;
1960                         if (d->extend(raw))
1961                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
1962                         else
1963                             top = dst;
1964                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1965
1966                     }
1967                 };
1968
1969                 struct IP_sbfm_execute : P {
1970                     void p(D d, Ops ops, I insn, A args, B raw) {
1971                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1972                                                                             false, (EXTR(31, 31) + 1) * 32);
1973                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1974                                                                             true, (EXTR(31, 31) + 1) * 32);
1975                         BaseSemantics::SValuePtr dst;
1976                         if (d->inzero(raw))
1977                             dst = d->Zeros(64);
1978                         else
1979                             dst = d->read(args[0]);
1980                         BaseSemantics::SValuePtr src = d->read(args[1]);
1981                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
1982                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
1983                         BaseSemantics::SValuePtr top;
1984                         if (d->extend(raw))
1985                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
1986                         else
1987                             top = dst;
1988                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
1989
1990                     }
1991                 };
1992
1993                 struct IP_sxth_sbfm_execute : P {
1994                     void p(D d, Ops ops, I insn, A args, B raw) {
1995                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1996                                                                             false, (EXTR(31, 31) + 1) * 32);
1997                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
1998                                                                             true, (EXTR(31, 31) + 1) * 32);
1999                         BaseSemantics::SValuePtr dst;
2000                         if (d->inzero(raw))
2001                             dst = d->Zeros(64);
2002                         else
2003                             dst = d->read(args[0]);
2004                         BaseSemantics::SValuePtr src = d->read(args[1]);
2005                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
2006                                                                 ops->and_(d->ROR(src, ops->number_(32, EXTR(16, 21))),
2007                                                                           wmask));
2008                         BaseSemantics::SValuePtr top;
2009                         if (d->extend(raw))
2010                             top = d->Replicate(ops->and_(ops->shiftRight(src, ops->number_(32, EXTR(10, 15))),
2011                                                          ops->number_(1, 1)));
2012                         else
2013                             top = dst;
2014                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
2015
2016                     }
2017                 };
2018
2019                 struct IP_sxtb_sbfm_execute : P {
2020                     void p(D d, Ops ops, I insn, A args, B raw) {
2021                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2022                                                                             false, (EXTR(31, 31) + 1) * 32);
2023                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2024                                                                             true, (EXTR(31, 31) + 1) * 32);
2025                         BaseSemantics::SValuePtr dst;
2026                         if (d->inzero(raw))
2027                             dst = d->Zeros(64);
2028                         else
2029                             dst = d->read(args[0]);
2030                         BaseSemantics::SValuePtr src = d->read(args[1]);
2031                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
2032                                                                 ops->and_(d->ROR(src, ops->number_(32, EXTR(16, 21))),
2033                                                                           wmask));
2034                         BaseSemantics::SValuePtr top;
2035                         if (d->extend(raw))
2036                             top = d->Replicate(ops->and_(ops->shiftRight(src, ops->number_(32, EXTR(10, 15))),
2037                                                          ops->number_(1, 1)));
2038                         else
2039                             top = dst;
2040                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
2041
2042                     }
2043                 };
2044
2045                 struct IP_sxtw_sbfm_execute : P {
2046                     void p(D d, Ops ops, I insn, A args, B raw) {
2047                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2048                                                                             false, (EXTR(31, 31) + 1) * 32);
2049                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2050                                                                             true, (EXTR(31, 31) + 1) * 32);
2051                         BaseSemantics::SValuePtr dst;
2052                         if (d->inzero(raw))
2053                             dst = d->Zeros(64);
2054                         else
2055                             dst = d->read(args[0]);
2056                         BaseSemantics::SValuePtr src = d->read(args[1]);
2057                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
2058                                                                 ops->and_(d->ROR(src, ops->number_(32, EXTR(16, 21))),
2059                                                                           wmask));
2060                         BaseSemantics::SValuePtr top;
2061                         if (d->extend(raw))
2062                             top = d->Replicate(ops->and_(ops->shiftRight(src, ops->number_(32, EXTR(10, 15))),
2063                                                          ops->number_(1, 1)));
2064                         else
2065                             top = dst;
2066                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
2067
2068                     }
2069                 };
2070
2071                 struct IP_sbfiz_sbfm_execute : P {
2072                     void p(D d, Ops ops, I insn, A args, B raw) {
2073                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2074                                                                             false, (EXTR(31, 31) + 1) * 32);
2075                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2076                                                                             true, (EXTR(31, 31) + 1) * 32);
2077                         BaseSemantics::SValuePtr dst;
2078                         if (d->inzero(raw))
2079                             dst = d->Zeros(64);
2080                         else
2081                             dst = d->read(args[0]);
2082                         BaseSemantics::SValuePtr src = d->read(args[1]);
2083                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
2084                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
2085                         BaseSemantics::SValuePtr top;
2086                         if (d->extend(raw))
2087                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
2088                         else
2089                             top = dst;
2090                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
2091
2092                     }
2093                 };
2094
2095                 struct IP_sbfx_sbfm_execute : P {
2096                     void p(D d, Ops ops, I insn, A args, B raw) {
2097                         BaseSemantics::SValuePtr tmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2098                                                                             false, (EXTR(31, 31) + 1) * 32);
2099                         BaseSemantics::SValuePtr wmask = d->getBitfieldMask(EXTR(16, 21), EXTR(10, 15), EXTR(22, 22),
2100                                                                             true, (EXTR(31, 31) + 1) * 32);
2101                         BaseSemantics::SValuePtr dst;
2102                         if (d->inzero(raw))
2103                             dst = d->Zeros(64);
2104                         else
2105                             dst = d->read(args[0]);
2106                         BaseSemantics::SValuePtr src = d->read(args[1]);
2107                         BaseSemantics::SValuePtr bot = ops->or_(ops->and_(dst, d->NOT(wmask)),
2108                                                                 ops->and_(d->ROR(src, d->read(args[2])), wmask));
2109                         BaseSemantics::SValuePtr top;
2110                         if (d->extend(raw))
2111                             top = d->Replicate(ops->and_(ops->shiftRight(src, d->read(args[3])), ops->number_(1, 1)));
2112                         else
2113                             top = dst;
2114                         d->write(args[0], ops->or_(ops->and_(top, d->NOT(tmask)), ops->and_(bot, tmask)));
2115
2116                     }
2117                 };
2118
2119                 struct IP_movz_execute : P {
2120                     void p(D d, Ops ops, I insn, A args, B raw) {
2121                         BaseSemantics::SValuePtr result;
2122
2123                         if (d->opcode(raw) == MoveWideOp_K) {
2124                             result = d->read(args[0]);
2125                         } else {
2126                             result = d->Zeros(64);
2127                         }
2128                         result = ops->or_(ops->extract(result, 0, (EXTR(21, 22) << 4)), ops->or_(
2129                                 ops->shiftLeft(d->read(args[1]), ops->number_(32, (EXTR(21, 22) << 4))),
2130                                 ops->shiftLeft(ops->extract(result, (EXTR(21, 22) << 4) + 15 + 1, result->get_width()),
2131                                                ops->number_(32, (EXTR(21, 22) << 4) + 15 + 1))));
2132
2133                         if (d->opcode(raw) == MoveWideOp_N) {
2134                             result = d->NOT(result);
2135                         }
2136                         d->write(args[0], result);
2137
2138                     }
2139                 };
2140
2141                 struct IP_mov_movz_execute : P {
2142                     void p(D d, Ops ops, I insn, A args, B raw) {
2143                         BaseSemantics::SValuePtr result;
2144
2145                         if (d->opcode(raw) == MoveWideOp_K) {
2146                             result = d->read(args[0]);
2147                         } else {
2148                             result = d->Zeros(64);
2149                         }
2150                         result = ops->or_(ops->extract(result, 0, (EXTR(21, 22) << 4)), ops->or_(
2151                                 ops->shiftLeft(d->read(args[1]), ops->number_(32, (EXTR(21, 22) << 4))),
2152                                 ops->shiftLeft(ops->extract(result, (EXTR(21, 22) << 4) + 15 + 1, result->get_width()),
2153                                                ops->number_(32, (EXTR(21, 22) << 4) + 15 + 1))));
2154
2155                         if (d->opcode(raw) == MoveWideOp_N) {
2156                             result = d->NOT(result);
2157                         }
2158                         d->write(args[0], result);
2159
2160                     }
2161                 };
2162
2163                 struct IP_movn_execute : P {
2164                     void p(D d, Ops ops, I insn, A args, B raw) {
2165                         BaseSemantics::SValuePtr result;
2166
2167                         if (d->opcode(raw) == MoveWideOp_K) {
2168                             result = d->read(args[0]);
2169                         } else {
2170                             result = d->Zeros(64);
2171                         }
2172                         result = ops->or_(ops->extract(result, 0, (EXTR(21, 22) << 4)), ops->or_(
2173                                 ops->shiftLeft(d->read(args[1]), ops->number_(32, (EXTR(21, 22) << 4))),
2174                                 ops->shiftLeft(ops->extract(result, (EXTR(21, 22) << 4) + 15 + 1, result->get_width()),
2175                                                ops->number_(32, (EXTR(21, 22) << 4) + 15 + 1))));
2176
2177                         if (d->opcode(raw) == MoveWideOp_N) {
2178                             result = d->NOT(result);
2179                         }
2180                         d->write(args[0], result);
2181
2182                     }
2183                 };
2184
2185                 struct IP_mov_movn_execute : P {
2186                     void p(D d, Ops ops, I insn, A args, B raw) {
2187                         BaseSemantics::SValuePtr result;
2188
2189                         if (d->opcode(raw) == MoveWideOp_K) {
2190                             result = d->read(args[0]);
2191                         } else {
2192                             result = d->Zeros(64);
2193                         }
2194                         result = ops->or_(ops->extract(result, 0, (EXTR(21, 22) << 4)), ops->or_(
2195                                 ops->shiftLeft(d->read(args[1]), ops->number_(32, (EXTR(21, 22) << 4))),
2196                                 ops->shiftLeft(ops->extract(result, (EXTR(21, 22) << 4) + 15 + 1, result->get_width()),
2197                                                ops->number_(32, (EXTR(21, 22) << 4) + 15 + 1))));
2198
2199                         if (d->opcode(raw) == MoveWideOp_N) {
2200                             result = d->NOT(result);
2201                         }
2202                         d->write(args[0], result);
2203
2204                     }
2205                 };
2206
2207                 struct IP_movk_execute : P {
2208                     void p(D d, Ops ops, I insn, A args, B raw) {
2209                         BaseSemantics::SValuePtr result;
2210
2211                         if (d->opcode(raw) == MoveWideOp_K) {
2212                             result = d->read(args[0]);
2213                         } else {
2214                             result = d->Zeros(64);
2215                         }
2216                         result = ops->or_(ops->extract(result, 0, (EXTR(21, 22) << 4)), ops->or_(
2217                                 ops->shiftLeft(d->read(args[1]), ops->number_(32, (EXTR(21, 22) << 4))),
2218                                 ops->shiftLeft(ops->extract(result, (EXTR(21, 22) << 4) + 15 + 1, result->get_width()),
2219                                                ops->number_(32, (EXTR(21, 22) << 4) + 15 + 1))));
2220
2221                         if (d->opcode(raw) == MoveWideOp_N) {
2222                             result = d->NOT(result);
2223                         }
2224                         d->write(args[0], result);
2225
2226                     }
2227                 };
2228
2229                 struct IP_fmov_float_gen_execute : P {
2230                     void p(D d, Ops ops, I insn, A args, B raw) {
2231                         BaseSemantics::SValuePtr srcVal = d->read(args[1]);
2232                         d->write(args[0], srcVal);
2233                     }
2234                 };
2235
2236                 struct IP_orr_log_shift_execute : P {
2237                     void p(D d, Ops ops, I insn, A args, B raw) {
2238                         BaseSemantics::SValuePtr result;
2239                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2240                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2241
2242                         if ((EXTR(21, 21) == 1)) {
2243                             operand2 = d->NOT(operand2);
2244                         }
2245
2246                         switch (d->op(raw)) {
2247                             case LogicalOp_AND: {
2248                                 result = ops->and_(operand1, operand2);
2249                             }
2250                                 break;
2251                             case LogicalOp_ORR: {
2252                                 result = ops->or_(operand1, operand2);
2253                             }
2254                                 break;
2255                             case LogicalOp_EOR: {
2256                                 result = ops->xor_(operand1, operand2);
2257                             }
2258                                 break;
2259                         }
2260
2261                         if (d->setflags(raw)) {
2262                             d->writeRegister(d->REG_N,
2263                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2264                             d->writeRegister(d->REG_Z, d->isZero(result));
2265                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2266                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2267                         }
2268                         d->write(args[0], result);
2269
2270                     }
2271                 };
2272
2273                 struct IP_orn_log_shift_execute : P {
2274                     void p(D d, Ops ops, I insn, A args, B raw) {
2275                         BaseSemantics::SValuePtr result;
2276                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2277                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2278
2279                         if ((EXTR(21, 21) == 1)) {
2280                             operand2 = d->NOT(operand2);
2281                         }
2282
2283                         switch (d->op(raw)) {
2284                             case LogicalOp_AND: {
2285                                 result = ops->and_(operand1, operand2);
2286                             }
2287                                 break;
2288                             case LogicalOp_ORR: {
2289                                 result = ops->or_(operand1, operand2);
2290                             }
2291                                 break;
2292                             case LogicalOp_EOR: {
2293                                 result = ops->xor_(operand1, operand2);
2294                             }
2295                                 break;
2296                         }
2297
2298                         if (d->setflags(raw)) {
2299                             d->writeRegister(d->REG_N,
2300                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2301                             d->writeRegister(d->REG_Z, d->isZero(result));
2302                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2303                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2304                         }
2305                         d->write(args[0], result);
2306
2307                     }
2308                 };
2309
2310                 struct IP_orr_log_imm_execute : P {
2311                     void p(D d, Ops ops, I insn, A args, B raw) {
2312                         BaseSemantics::SValuePtr result;
2313                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2314                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2315
2316                         switch (d->op(raw)) {
2317                             case LogicalOp_AND: {
2318                                 result = ops->and_(operand1, operand2);
2319                             }
2320                                 break;
2321                             case LogicalOp_ORR: {
2322                                 result = ops->or_(operand1, operand2);
2323                             }
2324                                 break;
2325                             case LogicalOp_EOR: {
2326                                 result = ops->xor_(operand1, operand2);
2327                             }
2328                                 break;
2329                         }
2330
2331                         if (d->setflags(raw)) {
2332                             d->writeRegister(d->REG_N,
2333                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2334                             d->writeRegister(d->REG_Z, d->isZero(result));
2335                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2336                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2337                         }
2338
2339                         if (EXTR(0, 4) == 31 && !d->setflags(raw)) {
2340                             d->writeRegister(d->REG_SP, result);
2341                         } else {
2342                             d->write(args[0], result);
2343                         }
2344
2345                     }
2346                 };
2347
2348                 struct IP_and_log_imm_execute : P {
2349                     void p(D d, Ops ops, I insn, A args, B raw) {
2350                         BaseSemantics::SValuePtr result;
2351                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2352                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2353
2354                         switch (d->op(raw)) {
2355                             case LogicalOp_AND: {
2356                                 result = ops->and_(operand1, operand2);
2357                             }
2358                                 break;
2359                             case LogicalOp_ORR: {
2360                                 result = ops->or_(operand1, operand2);
2361                             }
2362                                 break;
2363                             case LogicalOp_EOR: {
2364                                 result = ops->xor_(operand1, operand2);
2365                             }
2366                                 break;
2367                         }
2368
2369                         if (d->setflags(raw)) {
2370                             d->writeRegister(d->REG_N,
2371                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2372                             d->writeRegister(d->REG_Z, d->isZero(result));
2373                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2374                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2375                         }
2376
2377                         if (EXTR(0, 4) == 31 && !d->setflags(raw)) {
2378                             d->writeRegister(d->REG_SP, result);
2379                         } else {
2380                             d->write(args[0], result);
2381                         }
2382
2383                     }
2384                 };
2385
2386                 struct IP_and_log_shift_execute : P {
2387                     void p(D d, Ops ops, I insn, A args, B raw) {
2388                         BaseSemantics::SValuePtr result;
2389                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2390                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2391
2392                         if ((EXTR(21, 21) == 1)) {
2393                             operand2 = d->NOT(operand2);
2394                         }
2395
2396                         switch (d->op(raw)) {
2397                             case LogicalOp_AND: {
2398                                 result = ops->and_(operand1, operand2);
2399                             }
2400                                 break;
2401                             case LogicalOp_ORR: {
2402                                 result = ops->or_(operand1, operand2);
2403                             }
2404                                 break;
2405                             case LogicalOp_EOR: {
2406                                 result = ops->xor_(operand1, operand2);
2407                             }
2408                                 break;
2409                         }
2410
2411                         if (d->setflags(raw)) {
2412                             d->writeRegister(d->REG_N,
2413                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2414                             d->writeRegister(d->REG_Z, d->isZero(result));
2415                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2416                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2417                         }
2418                         d->write(args[0], result);
2419
2420                     }
2421                 };
2422
2423                 struct IP_ands_log_imm_execute : P {
2424                     void p(D d, Ops ops, I insn, A args, B raw) {
2425                         BaseSemantics::SValuePtr result;
2426                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2427                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2428
2429                         switch (d->op(raw)) {
2430                             case LogicalOp_AND: {
2431                                 result = ops->and_(operand1, operand2);
2432                             }
2433                                 break;
2434                             case LogicalOp_ORR: {
2435                                 result = ops->or_(operand1, operand2);
2436                             }
2437                                 break;
2438                             case LogicalOp_EOR: {
2439                                 result = ops->xor_(operand1, operand2);
2440                             }
2441                                 break;
2442                         }
2443
2444                         if (d->setflags(raw)) {
2445                             d->writeRegister(d->REG_N,
2446                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2447                             d->writeRegister(d->REG_Z, d->isZero(result));
2448                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2449                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2450                         }
2451
2452                         if (EXTR(0, 4) == 31 && !d->setflags(raw)) {
2453                             d->writeRegister(d->REG_SP, result);
2454                         } else {
2455                             d->write(args[0], result);
2456                         }
2457
2458                     }
2459                 };
2460
2461                 struct IP_ands_log_shift_execute : P {
2462                     void p(D d, Ops ops, I insn, A args, B raw) {
2463                         BaseSemantics::SValuePtr result;
2464                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2465                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2466
2467                         if ((EXTR(21, 21) == 1)) {
2468                             operand2 = d->NOT(operand2);
2469                         }
2470
2471                         switch (d->op(raw)) {
2472                             case LogicalOp_AND: {
2473                                 result = ops->and_(operand1, operand2);
2474                             }
2475                                 break;
2476                             case LogicalOp_ORR: {
2477                                 result = ops->or_(operand1, operand2);
2478                             }
2479                                 break;
2480                             case LogicalOp_EOR: {
2481                                 result = ops->xor_(operand1, operand2);
2482                             }
2483                                 break;
2484                         }
2485
2486                         if (d->setflags(raw)) {
2487                             d->writeRegister(d->REG_N,
2488                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2489                             d->writeRegister(d->REG_Z, d->isZero(result));
2490                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2491                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2492                         }
2493                         d->write(args[0], result);
2494
2495                     }
2496                 };
2497
2498                 struct IP_eor_log_shift_execute : P {
2499                     void p(D d, Ops ops, I insn, A args, B raw) {
2500                         BaseSemantics::SValuePtr result;
2501                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2502                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2503
2504                         if ((EXTR(21, 21) == 1)) {
2505                             operand2 = d->NOT(operand2);
2506                         }
2507
2508                         switch (d->op(raw)) {
2509                             case LogicalOp_AND: {
2510                                 result = ops->and_(operand1, operand2);
2511                             }
2512                                 break;
2513                             case LogicalOp_ORR: {
2514                                 result = ops->or_(operand1, operand2);
2515                             }
2516                                 break;
2517                             case LogicalOp_EOR: {
2518                                 result = ops->xor_(operand1, operand2);
2519                             }
2520                                 break;
2521                         }
2522
2523                         if (d->setflags(raw)) {
2524                             d->writeRegister(d->REG_N,
2525                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2526                             d->writeRegister(d->REG_Z, d->isZero(result));
2527                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2528                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2529                         }
2530                         d->write(args[0], result);
2531
2532                     }
2533                 };
2534
2535                 struct IP_eor_log_imm_execute : P {
2536                     void p(D d, Ops ops, I insn, A args, B raw) {
2537                         BaseSemantics::SValuePtr result;
2538                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2539                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2540
2541                         switch (d->op(raw)) {
2542                             case LogicalOp_AND: {
2543                                 result = ops->and_(operand1, operand2);
2544                             }
2545                                 break;
2546                             case LogicalOp_ORR: {
2547                                 result = ops->or_(operand1, operand2);
2548                             }
2549                                 break;
2550                             case LogicalOp_EOR: {
2551                                 result = ops->xor_(operand1, operand2);
2552                             }
2553                                 break;
2554                         }
2555
2556                         if (d->setflags(raw)) {
2557                             d->writeRegister(d->REG_N,
2558                                              ops->extract(result, result->get_width() - 1, result->get_width()));
2559                             d->writeRegister(d->REG_Z, d->isZero(result));
2560                             d->writeRegister(d->REG_C, ops->number_(1, 0));
2561                             d->writeRegister(d->REG_V, ops->number_(1, 0));
2562                         }
2563
2564                         if (EXTR(0, 4) == 31 && !d->setflags(raw)) {
2565                             d->writeRegister(d->REG_SP, result);
2566                         } else {
2567                             d->write(args[0], result);
2568                         }
2569
2570                     }
2571                 };
2572
2573                 struct IP_eon_execute : P {
2574                     void p(D d, Ops ops, I insn, A args, B raw) {
2575                         BaseSemantics::SValuePtr result;
2576                         BaseSemantics::SValuePtr operand1 = d->read(args[1]);
2577                         BaseSemantics::SValuePtr operand2 = d->read(args[2]);
2578
2579                         if ((EXTR(21, 21) == 1)) {
2580                             operand2 = d->NOT(operand2);
2581                         }
2582
2583                         switch (d->op(raw)) {
2584                             case LogicalOp_AND: {
2585