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