Fix conflicts between caching and stopping slicing
[dyninst.git] / dataflowAPI / rose / x86_64InstructionSemantics.h
1 #ifndef ROSE_X86_64INSTRUCTIONSEMANTICS_H
2 #define ROSE_X86_64INSTRUCTIONSEMANTICS_H
3
4 //#include "rose.h"
5 #include "semanticsModule.h"
6 #include <cassert>
7 #include <cstdio>
8 #include <iostream>
9 #include "rose.h"
10
11 #include "integerOps.h"
12
13
14 #include "SgAsmx86Instruction.h"
15 #include "SgAsmExpression.h"
16 #include "conversions.h"
17
18 #ifndef ROSE_X86INSTRUCTIONSEMANTICS_H
19
20 /* Returns the segment register corresponding to the specified register reference address expression. */
21 static inline X86SegmentRegister getSegregFromMemoryReference(SgAsmMemoryReferenceExpression* mr) {
22     X86SegmentRegister segreg = x86_segreg_none;
23     SgAsmx86RegisterReferenceExpression* seg = isSgAsmx86RegisterReferenceExpression(mr->get_segment());
24     if (seg) {
25         ROSE_ASSERT(seg->get_register_class() == x86_regclass_segment);
26         segreg = (X86SegmentRegister)(seg->get_register_number());
27     } else {
28         ROSE_ASSERT(!"Bad segment expr");
29     }
30     if (segreg == x86_segreg_none) segreg = x86_segreg_ds;
31     return segreg;
32 }
33 #endif
34
35 template <typename Policy, template <size_t> class WordType>
36 struct X86_64InstructionSemantics {
37 #   ifdef Word
38 #       error "Having a macro called \"Word\" conflicts with x86InstructionSemantics.h"
39 #   else
40 #       define Word(Len) WordType<(Len)>
41 #   endif
42
43     Policy& policy;
44
45     X86_64InstructionSemantics(Policy& policy)
46         : policy(policy)
47         {}
48     virtual ~X86_64InstructionSemantics() {}
49
50     /* If the counter (cx register) is non-zero then decrement it. The return value is a flag indicating whether cx was
51      * originally non-zero. */
52     Word(1) stringop_setup_loop() {
53         Word(1) ecxNotZero = policy.invert(policy.equalToZero(policy.readGPR(x86_gpr_cx)));
54         policy.writeGPR(x86_gpr_cx,
55                         policy.add(policy.readGPR(x86_gpr_cx),
56                                    policy.ite(ecxNotZero, number<64>(-1), number<64>(0))));
57         return ecxNotZero;
58     }
59
60     /* Instruction semantics for rep_stosN where N is 1(b), 2(w), or 4(d).
61      * This method handles semantics for one iteration of stosN.
62      * See https://siyobik.info/index.php?module=x86&id=279 */
63     template<size_t N>
64     void rep_stos_semantics(SgAsmx86Instruction *insn) {
65         Word(1) ecxNotZero = policy.invert(policy.equalToZero(policy.readGPR(x86_gpr_cx)));
66
67         /* Fill memory pointed to by ES:[DI] with contents of AX register if counter was not zero. */
68         policy.writeMemory(x86_segreg_es,
69                            policy.readGPR(x86_gpr_di),
70                            extract<0, 8*N>(policy.readGPR(x86_gpr_ax)),
71                            ecxNotZero);
72
73         /* Update DI by incrementing or decrementing by number of bytes copied (only if counter is nonzero) */
74         policy.writeGPR(x86_gpr_di,
75                         policy.add(policy.readGPR(x86_gpr_di),
76                                    policy.ite(ecxNotZero,
77                                               policy.ite(policy.readFlag(x86_flag_df), number<64>(-N), number<64>(N)),
78                                               number<64>(0))));
79
80         /* Decrement the counter if not already zero. */
81         policy.writeGPR(x86_gpr_cx,
82                         policy.add(policy.readGPR(x86_gpr_cx),
83                                    policy.ite(ecxNotZero, number<64>(-1), number<64>(0))));
84
85         /* If counter is now nonzero then repeat this instruction, otherwise go to the next one. */
86         ecxNotZero = policy.invert(policy.equalToZero(policy.readGPR(x86_gpr_cx)));
87         policy.writeIP(policy.ite(ecxNotZero, number<64>((uint32_t)(insn->get_address())), policy.readIP()));
88     }
89
90     /* Instruction semantics for stosN where N is 1(b), 2(w), or 4(d) */
91     template<size_t N>
92     void stos_semantics(SgAsmx86Instruction *insn) {
93         const SgAsmExpressionPtrList& operands = insn->get_operandList()->get_operands();
94         ROSE_ASSERT(operands.size() == 0);
95         ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
96
97         /* Fill memory pointed to by ES:[DI] with contents of AX. */
98         policy.writeMemory(x86_segreg_es,
99                            policy.readGPR(x86_gpr_di),
100                            extract<0, 8*N>(policy.readGPR(x86_gpr_ax)),
101                            policy.true_());
102
103         /* Update DI */ /*FIXME: Is this correct? */
104         policy.writeGPR(x86_gpr_di,
105                         policy.add(policy.readGPR(x86_gpr_di),
106                                    policy.ite(policy.readFlag(x86_flag_df), number<64>(-N), number<64>(N))));
107     }
108     
109
110     template <typename W>
111     W invertMaybe(const W& w, bool inv) {
112         if (inv) {
113             return policy.invert(w);
114         } else {
115             return w;
116         }
117     }
118
119     template <size_t Len>
120     Word(Len) number(uintmax_t v) {
121         return policy.template number<Len>(v);
122     }
123
124     template <size_t From, size_t To, typename W>
125         Word(To - From) extract(W w) {
126         return policy.template extract<From, To>(w);
127     }
128
129     template <size_t From, size_t To>
130         Word(To) signExtend(Word(From) w) {
131         return policy.template signExtend<From, To>(w);
132     }
133
134     template <size_t Len>
135     Word(1) greaterOrEqualToTen(Word(Len) w) {
136         Word(Len) carries = number<Len>(0);
137         policy.addWithCarries(w, number<Len>(6), policy.false_(), carries);
138         return extract<Len - 1, Len>(carries);
139     }
140
141     Word(32) readEflags() {
142         return policy.concat(readFlags(), number<16>(0x0000));
143     }
144
145     Word(16) readFlags() {
146         return policy.concat(policy.readFlag((X86Flag)0 ),
147                              policy.concat(policy.readFlag((X86Flag)1 ),
148                              policy.concat(policy.readFlag((X86Flag)2 ),
149                              policy.concat(policy.readFlag((X86Flag)3 ),
150                              policy.concat(policy.readFlag((X86Flag)4 ),
151                              policy.concat(policy.readFlag((X86Flag)5 ),
152                              policy.concat(policy.readFlag((X86Flag)6 ),
153                              policy.concat(policy.readFlag((X86Flag)7 ),
154                              policy.concat(policy.readFlag((X86Flag)8 ),
155                              policy.concat(policy.readFlag((X86Flag)9 ),
156                              policy.concat(policy.readFlag((X86Flag)10),
157                              policy.concat(policy.readFlag((X86Flag)11),
158                              policy.concat(policy.readFlag((X86Flag)12),
159                              policy.concat(policy.readFlag((X86Flag)13),
160                              policy.concat(policy.readFlag((X86Flag)14),
161                                            policy.readFlag((X86Flag)15))))))))))))))));
162     }
163
164     template <size_t Len/*bits*/>
165     Word(Len) readMemory(X86SegmentRegister segreg, const Word(64)& addr, Word(1) cond) {
166         return policy.template readMemory<Len>(segreg, addr, cond);
167     }
168
169     Word(64) readEffectiveAddress(SgAsmExpression* expr) {
170       assert (isSgAsmMemoryReferenceExpression(expr));
171       return read64(isSgAsmMemoryReferenceExpression(expr)->get_address());
172     }
173
174     /* Returns an eight-bit value desribed by an instruction operand. */
175     Word(8) read8(SgAsmExpression* e) {
176         switch (e->variantT()) {
177             case V_SgAsmx86RegisterReferenceExpression: {
178                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
179                 switch (rre->get_register_class()) {
180                     case x86_regclass_gpr: {
181                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
182                         Word(64) rawValue = policy.readGPR(reg);
183                         switch (rre->get_position_in_register()) {
184                             case x86_regpos_low_byte: return extract<0, 8>(rawValue);
185                             case x86_regpos_high_byte: return extract<8, 16>(rawValue);
186                             default: ROSE_ASSERT(!"Bad position in register");
187                         }
188                     }
189                     default: {
190                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
191                         abort();
192                     }
193                 }
194                 break;
195             }
196             case V_SgAsmBinaryAdd: {
197                 return policy.add(read8(isSgAsmBinaryAdd(e)->get_lhs()), read8(isSgAsmBinaryAdd(e)->get_rhs()));
198             }
199             case V_SgAsmBinaryMultiply: {
200                 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
201                 ROSE_ASSERT(rhs);
202                 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
203                 return extract<0, 8>(policy.unsignedMultiply(read8(lhs), read8(rhs)));
204             }
205             case V_SgAsmMemoryReferenceExpression: {
206                 return readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
207                                      readEffectiveAddress(e), policy.true_());
208             }
209             case V_SgAsmByteValueExpression:
210             case V_SgAsmWordValueExpression:
211             case V_SgAsmDoubleWordValueExpression:
212             case V_SgAsmQuadWordValueExpression: {
213                 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
214                 return number<8>(val & 0xFFU);
215             }
216             default: {
217                 fprintf(stderr, "Bad variant %s in read8\n", e->class_name().c_str());
218                 abort();
219             }
220         }
221         return number<8>(0); // error case
222     }
223
224     /* Returns a 16-bit value described by an instruction operand. */
225     Word(16) read16(SgAsmExpression* e) {
226         switch (e->variantT()) {
227             case V_SgAsmx86RegisterReferenceExpression: {
228                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
229                 // Xiaozhu: Not sure why we 16-bit is different from other lengths of read,
230                 // but for read8 or read32, there is no such assert.
231                 // ROSE_ASSERT(rre->get_position_in_register() == x86_regpos_word);
232                 switch (rre->get_register_class()) {
233                     case x86_regclass_gpr: {
234                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
235                         Word(64) rawValue = policy.readGPR(reg);
236                         return extract<0, 16>(rawValue);
237                     }
238                     case x86_regclass_segment: {
239                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
240                         Word(16) value = extract<0,16>(policy.readSegreg(sr));
241                         return value;
242                     }
243                     default: {
244                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
245                         abort();
246                     }
247                 }
248                 break;
249             }
250             case V_SgAsmBinaryAdd: {
251                 return policy.add(read16(isSgAsmBinaryAdd(e)->get_lhs()), read16(isSgAsmBinaryAdd(e)->get_rhs()));
252             }
253             case V_SgAsmBinaryMultiply: {
254                 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
255                 ROSE_ASSERT(rhs);
256                 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
257                 return extract<0, 16>(policy.unsignedMultiply(read16(lhs), read8(rhs)));
258             }
259             case V_SgAsmMemoryReferenceExpression: {
260                 return readMemory<16>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
261                                       readEffectiveAddress(e), policy.true_());
262             }
263             case V_SgAsmByteValueExpression:
264             case V_SgAsmWordValueExpression:
265             case V_SgAsmDoubleWordValueExpression:
266             case V_SgAsmQuadWordValueExpression: {
267                 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
268                 return number<16>(val & 0xFFFFU);
269             }
270             default: {
271                 fprintf(stderr, "Bad variant %s in read16\n", e->class_name().c_str());
272                 abort();
273             }
274         }
275         return number<16>(0); //error case
276     }
277
278     /* Returns a 32-bit value described by an instruction operand. */
279     Word(32) read32(SgAsmExpression* e) {
280         switch (e->variantT()) {
281             case V_SgAsmx86RegisterReferenceExpression: {
282                SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
283                 switch (rre->get_register_class()) {
284                     case x86_regclass_gpr: {
285                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
286                         Word(64) rawValue = policy.readGPR(reg);
287                         switch (rre->get_position_in_register()) {
288                             case x86_regpos_dword:
289                             case x86_regpos_all:
290                                 return extract<0,32>(rawValue);
291                             case x86_regpos_word:
292                                 return policy.concat(extract<0, 16>(rawValue), number<16>(0));
293                             default:
294                               fprintf(stderr, "Error: position %d\n", rre->get_position_in_register());
295                               ROSE_ASSERT(!"bad position in register");
296                         }
297                     }
298                     case x86_regclass_segment: {
299                         ROSE_ASSERT(rre->get_position_in_register() == x86_regpos_dword ||
300                                     rre->get_position_in_register() == x86_regpos_all);
301                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
302                         Word(64) value = policy.readSegreg(sr);
303                         return extract<0,32>(value);
304                     }
305                     default: {
306                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
307                         abort();
308                     }
309                 }
310                 break;
311             }
312             case V_SgAsmBinaryAdd: {
313                 return policy.add(read32(isSgAsmBinaryAdd(e)->get_lhs()), read32(isSgAsmBinaryAdd(e)->get_rhs()));
314             }
315             case V_SgAsmBinaryMultiply: {
316                 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
317                 ROSE_ASSERT(rhs);
318                 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
319                 return extract<0, 32>(policy.unsignedMultiply(read32(lhs), read8(rhs)));
320             }
321             case V_SgAsmMemoryReferenceExpression: {
322                 return readMemory<32>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
323                                       readEffectiveAddress(e), policy.true_());
324             }
325             case V_SgAsmByteValueExpression:
326             case V_SgAsmWordValueExpression:
327             case V_SgAsmDoubleWordValueExpression:
328             case V_SgAsmQuadWordValueExpression: {
329                 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
330                 return number<32>(val & 0xFFFFFFFFU);
331             }
332             default: {
333                 fprintf(stderr, "Bad variant %s in read32\n", e->class_name().c_str());
334                 abort();
335             }
336         }
337         return number<32>(0); //error case
338     }
339
340     /* Returns a 64-bit value described by an instruction operand. */
341     Word(64) read64(SgAsmExpression* e) {
342         switch (e->variantT()) {
343             case V_SgAsmx86RegisterReferenceExpression: {
344                SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
345                 switch (rre->get_register_class()) {
346                     case x86_regclass_gpr: {
347                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
348                         Word(64) rawValue = policy.readGPR(reg);
349                         switch (rre->get_position_in_register()) {
350                             case x86_regpos_dword:
351                             case x86_regpos_all:
352                                 return policy.concat(extract<0, 32>(rawValue), number<32>(0));
353                             case x86_regpos_qword:
354                                 return rawValue;
355                             case x86_regpos_word:
356                                 return policy.concat(extract<0, 16>(rawValue), number<48>(0));
357                             default:
358                               fprintf(stderr, "Error: position %d\n", rre->get_position_in_register());
359                               ROSE_ASSERT(!"bad position in register");
360                         }
361                     }
362                     case x86_regclass_segment: {
363                         ROSE_ASSERT(rre->get_position_in_register() == x86_regpos_dword ||
364                                     rre->get_position_in_register() == x86_regpos_all);
365                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
366                         Word(64) value = policy.readSegreg(sr);
367                         return value;
368                     }
369                     default: {
370                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
371                         abort();
372                     }
373                 }
374                 break;
375             }
376             case V_SgAsmBinaryAdd: {
377                 return policy.add(read64(isSgAsmBinaryAdd(e)->get_lhs()), read64(isSgAsmBinaryAdd(e)->get_rhs()));
378             }
379             case V_SgAsmBinaryMultiply: {
380                 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
381                 ROSE_ASSERT(rhs);
382                 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
383                 //TODO: Ask Bill
384                 return extract<0, 64>(policy.unsignedMultiply(read64(lhs), read8(rhs)));
385             }
386             case V_SgAsmMemoryReferenceExpression: {
387                 return readMemory<64>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
388                                       readEffectiveAddress(e), policy.true_());
389             }
390             case V_SgAsmByteValueExpression:
391             case V_SgAsmWordValueExpression:
392             case V_SgAsmDoubleWordValueExpression:
393             case V_SgAsmQuadWordValueExpression: {
394                 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
395                 return number<64>(val & 0xFFFFFFFFFFFFFFFFLU);
396             }
397             default: {
398                 fprintf(stderr, "Bad variant %s in read32\n", e->class_name().c_str());
399                 abort();
400             }
401         }
402         return number<64>(0); //error case
403     }
404
405     /* Replaces the least significant byte of a general purpose register with a new value. */
406     void updateGPRLowByte(X86GeneralPurposeRegister reg, const Word(8)& value) {
407         Word(64) oldValue = policy.readGPR(reg);
408         policy.writeGPR(reg, policy.concat(value, extract<8, 64>(oldValue)));
409     }
410
411     /* Replaces bits 8 through 15 of a 32-bit register with the specified 8-bit value. */
412     void updateGPRHighByte(X86GeneralPurposeRegister reg, const Word(8)& value) {
413         Word(64) oldValue = policy.readGPR(reg);
414         policy.writeGPR(reg, policy.concat(extract<0, 8>(oldValue),
415                                            policy.concat(value, extract<16, 64>(oldValue))));
416     }
417
418     /* Replaces the least significant 16 bits of a general purpose register with a new value. */
419     void updateGPRLowWord(X86GeneralPurposeRegister reg, const Word(16)& value) {
420         Word(64) oldValue = policy.readGPR(reg);
421         policy.writeGPR(reg, policy.concat(value, extract<16, 64>(oldValue)));
422     }
423
424     /* Replaces the least significant 32 bits of a general purpose register with a new value. */
425     void updateGPRLowDWord(X86GeneralPurposeRegister reg, const Word(32)& value) {
426         Word(64) oldValue = policy.readGPR(reg);
427         policy.writeGPR(reg, policy.concat(value, extract<32, 64>(oldValue)));
428     }
429
430     /* Writes the specified eight-bit value to the location specified by an instruction operand. */
431     void write8(SgAsmExpression* e, const Word(8)& value) {
432         switch (e->variantT()) {
433             case V_SgAsmx86RegisterReferenceExpression: {
434                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
435                 switch (rre->get_register_class()) {
436                     case x86_regclass_gpr: {
437                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
438                         switch (rre->get_position_in_register()) {
439                             case x86_regpos_low_byte: updateGPRLowByte(reg, value); break;
440                             case x86_regpos_high_byte: updateGPRHighByte(reg, value); break;
441                             default: ROSE_ASSERT(!"Bad position in register");
442                         }
443                         break;
444                     }
445                     default: {
446                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
447                         abort();
448                     }
449                 }
450                 break;
451             }
452             case V_SgAsmMemoryReferenceExpression: {
453                 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
454                                    readEffectiveAddress(e), value, policy.true_());
455                 break;
456             }
457             default: {
458                 fprintf(stderr, "Bad variant %s in write8\n", e->class_name().c_str());
459                 abort();
460             }
461         }
462     }
463
464     /* Writes the specified 16-bit value to the location specified by an instruction operand. */
465     void write16(SgAsmExpression* e, const Word(16)& value) {
466         switch (e->variantT()) {
467             case V_SgAsmx86RegisterReferenceExpression: {
468                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
469                 switch (rre->get_register_class()) {
470                     case x86_regclass_gpr: {
471                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
472                         switch (rre->get_position_in_register()) {
473                             case x86_regpos_word: updateGPRLowWord(reg, value); break;
474                             default: ROSE_ASSERT(!"Bad position in register");
475                         }
476                         break;
477                     }
478                     // TODO: Ask Bill, not sure how segment registers can be accessed
479                     case x86_regclass_segment: {
480                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
481                         policy.writeSegreg(sr, value);
482                         break;
483                     }
484                     default: {
485                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
486                         abort();
487                     }
488                 }
489                 break;
490             }
491             case V_SgAsmMemoryReferenceExpression: {
492                 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
493                                    readEffectiveAddress(e), value, policy.true_());
494                 break;
495             }
496             default: {
497                 fprintf(stderr, "Bad variant %s in write16\n", e->class_name().c_str());
498                 abort();
499             }
500         }
501     }
502
503     /* Writes the specified 32-bit value to the location specified by an instruction operand. */
504     void write32(SgAsmExpression* e, const Word(32)& value) {
505         switch (e->variantT()) {
506             case V_SgAsmx86RegisterReferenceExpression: {
507                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
508                 switch (rre->get_register_class()) {
509                     case x86_regclass_gpr: {
510                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
511                         switch (rre->get_position_in_register()) {
512                             case x86_regpos_dword:
513                             case x86_regpos_all: updateGPRLowDWord(reg, value); break;
514                             default: ROSE_ASSERT(!"Bad position in register");
515                         }
516                         break;
517                     }
518                     case x86_regclass_segment: { // Used for pop of segment registers
519                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
520                         policy.writeSegreg(sr, extract<0, 16>(value));
521                         break;
522                     }
523                     default: {
524                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
525                         abort();
526                     }
527                 }
528                 break;
529             }
530             case V_SgAsmMemoryReferenceExpression: {
531                 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
532                                    readEffectiveAddress(e), value, policy.true_());
533                 break;
534             }
535             default: {
536                 fprintf(stderr, "Bad variant %s in write32\n", e->class_name().c_str());
537                 abort();
538             }
539         }
540     }
541
542     /* Writes the specified 64-bit value to the location specified by an instruction operand. */
543     void write64(SgAsmExpression* e, const Word(64)& value) {
544         switch (e->variantT()) {
545             case V_SgAsmx86RegisterReferenceExpression: {
546                 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
547                 switch (rre->get_register_class()) {
548                     case x86_regclass_gpr: {
549                         X86GeneralPurposeRegister reg = (X86GeneralPurposeRegister)(rre->get_register_number());
550                         switch (rre->get_position_in_register()) {
551                             case x86_regpos_qword: {
552                                 break;
553                             }
554                             default: ROSE_ASSERT(!"Bad position in register");
555                         }
556                         policy.writeGPR(reg, value);
557                         break;
558                     }
559                     case x86_regclass_segment: { // Used for pop of segment registers
560                         X86SegmentRegister sr = (X86SegmentRegister)(rre->get_register_number());
561                         policy.writeSegreg(sr, extract<0, 16>(value));
562                         break;
563                     }
564                     default: {
565                         fprintf(stderr, "Bad register class %s\n", regclassToString(rre->get_register_class()));
566                         abort();
567                     }
568                 }
569                 break;
570             }
571             case V_SgAsmMemoryReferenceExpression: {
572                 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
573                                    readEffectiveAddress(e), value, policy.true_());
574                 break;
575             }
576             default: {
577                 fprintf(stderr, "Bad variant %s in write32\n", e->class_name().c_str());
578                 abort();
579             }
580         }
581     }
582
583     /* Returns true if W has an even number of bits set; false for an odd number */
584     Word(1) parity(Word(8) w) {
585         Word(1) p01 = policy.xor_(extract<0, 1>(w), extract<1, 2>(w));
586         Word(1) p23 = policy.xor_(extract<2, 3>(w), extract<3, 4>(w));
587         Word(1) p45 = policy.xor_(extract<4, 5>(w), extract<5, 6>(w));
588         Word(1) p67 = policy.xor_(extract<6, 7>(w), extract<7, 8>(w));
589         Word(1) p0123 = policy.xor_(p01, p23);
590         Word(1) p4567 = policy.xor_(p45, p67);
591         return policy.invert(policy.xor_(p0123, p4567));
592     }
593
594     /* Sets flags: parity, sign, and zero */
595     template <size_t Len>
596     void setFlagsForResult(const Word(Len)& result) {
597         policy.writeFlag(x86_flag_pf, parity(extract<0, 8>(result)));
598         policy.writeFlag(x86_flag_sf, extract<Len - 1, Len>(result));
599         policy.writeFlag(x86_flag_zf, policy.equalToZero(result));
600     }
601
602     /* Sets flags conditionally. Sets parity, sign, and zero flags if COND is true. */
603     template <size_t Len>
604     void setFlagsForResult(const Word(Len)& result, Word(1) cond) {
605         policy.writeFlag(x86_flag_pf, policy.ite(cond, parity(extract<0, 8>(result)), policy.readFlag(x86_flag_pf)));
606         policy.writeFlag(x86_flag_sf, policy.ite(cond, extract<Len - 1, Len>(result), policy.readFlag(x86_flag_sf)));
607         policy.writeFlag(x86_flag_zf, policy.ite(cond, policy.equalToZero(result), policy.readFlag(x86_flag_zf)));
608     }
609
610     /* Adds A and B and adjusts condition flags. Can be used for subtraction if B is two's complement and invertCarries is set. */
611     template <size_t Len>
612     Word(Len) doAddOperation(const Word(Len)& a, const Word(Len)& b, bool invertCarries, Word(1) carryIn) {
613         Word(Len) carries = number<Len>(0);
614         Word(Len) result = policy.addWithCarries(a, b, invertMaybe(carryIn, invertCarries), carries/*out*/);
615         setFlagsForResult<Len>(result);
616         policy.writeFlag(x86_flag_af, invertMaybe(extract<3, 4>(carries), invertCarries));
617         policy.writeFlag(x86_flag_cf, invertMaybe(extract<Len - 1, Len>(carries), invertCarries));
618         policy.writeFlag(x86_flag_of, policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)));
619         return result;
620     }
621
622     /* Conditionally adds A and B and adjusts condition flags. Can be used for subtraction if B is two's complement and
623      * invertCarries is set. Does nothing if COND is false. */ 
624     template <size_t Len>
625     Word(Len) doAddOperation(const Word(Len)& a, const Word(Len)& b, bool invertCarries, Word(1) carryIn, Word(1) cond) {
626         Word(Len) carries = number<Len>(0);
627         Word(Len) result = policy.addWithCarries(a, b, invertMaybe(carryIn, invertCarries), carries/*out*/);
628         setFlagsForResult<Len>(result, cond);
629         policy.writeFlag(x86_flag_af,
630                          policy.ite(cond,
631                                     invertMaybe(extract<3, 4>(carries), invertCarries),
632                                     policy.readFlag(x86_flag_af)));
633         policy.writeFlag(x86_flag_cf,
634                          policy.ite(cond,
635                                     invertMaybe(extract<Len - 1, Len>(carries), invertCarries),
636                                     policy.readFlag(x86_flag_cf)));
637         policy.writeFlag(x86_flag_of,
638                          policy.ite(cond,
639                                     policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)),
640                                     policy.readFlag(x86_flag_of)));
641         return result;
642     }
643
644     /* Does increment (decrement with DEC set), and adjusts condition flags. */
645     template <size_t Len>
646     Word(Len) doIncOperation(const Word(Len)& a, bool dec, bool setCarry) {
647         Word(Len) carries = number<Len>(0);
648         Word(Len) result = policy.addWithCarries(a, number<Len>(dec ? -1 : 1), policy.false_(), carries/*out*/);
649         setFlagsForResult<Len>(result);
650         policy.writeFlag(x86_flag_af, invertMaybe(extract<3, 4>(carries), dec));
651         policy.writeFlag(x86_flag_of, policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)));
652         if (setCarry)
653             policy.writeFlag(x86_flag_cf, invertMaybe(extract<Len - 1, Len>(carries), dec));
654         return result;
655     }
656
657     /* Virtual so that we can subclass X86InstructionSemantics and have an opportunity to override the translation of any
658      * instruction. */
659     virtual void translate(SgAsmx86Instruction* insn) {
660       // BERNAT, 16MAR10 - keep the IP symbolic.
661       // PATCH
662       policy.writeIP(policy.add(policy.readIP(), number<64>(insn->get_raw_bytes().size())));
663       //policy.writeIP(number<32>((unsigned int)(insn->get_address() + insn->get_raw_bytes().size())));
664       // END PATCH
665         X86InstructionKind kind = insn->get_kind();
666         const SgAsmExpressionPtrList& operands = insn->get_operandList()->get_operands();
667         switch (kind) {
668
669             case x86_mov: {
670                 ROSE_ASSERT(operands.size() == 2);
671                 switch (numBytesInAsmType(operands[0]->get_type())) {
672                     case 1: write8(operands[0], read8(operands[1])); break;
673                     case 2: write16(operands[0], read16(operands[1])); break;
674                     case 4: write32(operands[0], read32(operands[1])); break;
675                     case 8: write64(operands[0], read64(operands[1])); break;
676                     default: ROSE_ASSERT("Bad size"); break;
677                 }
678                 break;
679             }
680
681             case x86_xchg: {
682                 ROSE_ASSERT(operands.size() == 2);
683                 switch (numBytesInAsmType(operands[0]->get_type())) {
684                     case 1: {
685                         Word(8) temp = read8(operands[1]);
686                         write8(operands[1], read8(operands[0]));
687                         write8(operands[0], temp);
688                         break;
689                     }
690                     case 2: {
691                         Word(16) temp = read16(operands[1]);
692                         write16(operands[1], read16(operands[0]));
693                         write16(operands[0], temp);
694                         break;
695                     }
696                     case 4: {
697                         Word(32) temp = read32(operands[1]);
698                         write32(operands[1], read32(operands[0]));
699                         write32(operands[0], temp);
700                         break;
701                     }
702                     case 8: {
703                         Word(64) temp = read64(operands[1]);
704                         write64(operands[1], read64(operands[0]));
705                         write64(operands[0], temp);
706                         break;
707                     }
708                     default:
709                         ROSE_ASSERT("Bad size");
710                         break;
711                 }
712                 break;
713             }
714             
715             case x86_movzx: {
716                 ROSE_ASSERT(operands.size() == 2);
717                 switch (numBytesInAsmType(operands[0]->get_type())) {
718                     case 2: {
719                         write16(operands[0], policy.concat(read8(operands[1]), number<8>(0)));
720                         break;
721                     }
722                     case 4: {
723                         switch (numBytesInAsmType(operands[1]->get_type())) {
724                             case 1: write32(operands[0], policy.concat(read8(operands[1]), number<24>(0))); break;
725                             case 2: write32(operands[0], policy.concat(read16(operands[1]), number<16>(0))); break;
726                             default: ROSE_ASSERT("Bad size");
727                         }
728                         break;
729                     }
730                     case 8: {
731                         switch (numBytesInAsmType(operands[1]->get_type())) {
732                             case 1: write64(operands[0], policy.concat(read8(operands[1]), number<56>(0))); break;
733                             case 2: write64(operands[0], policy.concat(read16(operands[1]), number<48>(0))); break;
734                             case 4: write64(operands[0], policy.concat(read32(operands[1]), number<32>(0))); break;
735
736                             default: ROSE_ASSERT("Bad size");
737                         }
738                         break;
739
740                     }
741                     default:
742                         ROSE_ASSERT("Bad size");
743                         break;
744                 }
745                 break;
746             }
747
748             case x86_movsx:
749             case x86_movsxd: {
750                 ROSE_ASSERT(operands.size() == 2);
751                 switch (numBytesInAsmType(operands[0]->get_type())) {
752                     case 2: {
753                         Word(8) op1 = read8(operands[1]);
754                         Word(16) result = signExtend<8, 16>(op1);
755                         write16(operands[0], result);
756                         break;
757                     }
758                     case 4: {
759                         switch (numBytesInAsmType(operands[1]->get_type())) {
760                             case 1: {
761                                 Word(8) op1 = read8(operands[1]);
762                                 Word(32) result = signExtend<8, 32>(op1);
763                                 write32(operands[0], result);
764                                 break;
765                             }
766                             case 2: {
767                                 Word(16) op1 = read16(operands[1]);
768                                 Word(32) result = signExtend<16, 32>(op1);
769                                 write32(operands[0], result);
770                                 break;
771                             }
772                             default:
773                                 break;
774 //                                ROSE_ASSERT(!"Bad size");
775                         }
776                         break;
777                     }
778                     case 8: {
779                         switch (numBytesInAsmType(operands[1]->get_type())) {
780                             case 1: {
781                                 Word(8) op1 = read8(operands[1]);
782                                 Word(64) result = signExtend<8, 64>(op1);
783                                 write64(operands[0], result);
784                                 break;
785                             }
786                             case 2: {
787                                 Word(16) op1 = read16(operands[1]);
788                                 Word(64) result = signExtend<16, 64>(op1);
789                                 write64(operands[0], result);
790                                 break;
791                             }
792                             case 4: {
793                                 Word(32) op1 = read32(operands[1]);
794                                 Word(64) result = signExtend<32, 64>(op1);
795                                 write64(operands[0], result);
796                                 break;
797                             }
798                             default:
799                                 ROSE_ASSERT(!"Bad size");
800                         }
801                         break;
802                     }
803
804                     default:
805                         ROSE_ASSERT(!"Bad size");
806                         break;
807                 }
808                 break;
809             }
810 /*
811             case x86_cbw: {
812                 ROSE_ASSERT(operands.size() == 0);
813                 updateGPRLowWord(x86_gpr_ax, signExtend<8, 16>(extract<0, 8>(policy.readGPR(x86_gpr_ax))));
814                 break;
815             }
816 */
817             case x86_cwde: {
818                 ROSE_ASSERT(operands.size() == 0);
819                 policy.writeGPR(x86_gpr_ax, signExtend<16, 64>(extract<0, 16>(policy.readGPR(x86_gpr_ax))));
820                 break;
821             }
822 /*
823             case x86_cwd: {
824                 ROSE_ASSERT(operands.size() == 0);
825                 updateGPRLowWord(x86_gpr_dx, extract<16, 32>(signExtend<16, 32>(extract<0, 16>(policy.readGPR(x86_gpr_ax)))));
826                 break;
827             }
828
829             case x86_cdq: {
830                 ROSE_ASSERT(operands.size() == 0);
831                 policy.writeGPR(x86_gpr_dx, extract<32, 64>(signExtend<32, 64>(policy.readGPR(x86_gpr_ax))));
832                 break;
833             }
834 */
835             case x86_lea: {
836                 ROSE_ASSERT(operands.size() == 2);
837                 switch (numBytesInAsmType(operands[0]->get_type())) {
838                     case 4: {
839                         write32(operands[0], extract<0,32>(readEffectiveAddress(operands[1])));
840                         break;
841                     }
842                     case 8: {
843                         write64(operands[0], readEffectiveAddress(operands[1]));
844                         break;
845                     }
846                     default:
847                         ROSE_ASSERT(!"Bad size!");
848                 }
849                 break;
850             }
851
852             case x86_and: {
853                 ROSE_ASSERT(operands.size() == 2);
854                 switch (numBytesInAsmType(operands[0]->get_type())) {
855                     case 1: {
856                         Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
857                         setFlagsForResult<8>(result);
858                         write8(operands[0], result);
859                         break;
860                     }
861                     case 2: {
862                         Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
863                         setFlagsForResult<16>(result);
864                         write16(operands[0], result);
865                         break;
866                     }
867                     case 4: {
868                         Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
869                         setFlagsForResult<32>(result);
870                         write32(operands[0], result);
871                         break;
872                     }
873                     case 8: {
874                         Word(64) result = policy.and_(read64(operands[0]), read64(operands[1]));
875                         setFlagsForResult<64>(result);
876                         write64(operands[0], result);
877                         break;
878                     }
879
880                     default:
881                         ROSE_ASSERT(!"Bad size");
882                         break;
883                 }
884                 policy.writeFlag(x86_flag_of, policy.false_());
885                 policy.writeFlag(x86_flag_af, policy.undefined_());
886                 policy.writeFlag(x86_flag_cf, policy.false_());
887                 break;
888             }
889
890             case x86_or: {
891                 ROSE_ASSERT(operands.size() == 2);
892                 switch (numBytesInAsmType(operands[0]->get_type())) {
893                     case 1: {
894                         Word(8) result = policy.or_(read8(operands[0]), read8(operands[1]));
895                         setFlagsForResult<8>(result);
896                         write8(operands[0], result);
897                         break;
898                     }
899                     case 2: {
900                         Word(16) result = policy.or_(read16(operands[0]), read16(operands[1]));
901                         setFlagsForResult<16>(result);
902                         write16(operands[0], result);
903                         break;
904                     }
905                     case 4: {
906                         Word(32) result = policy.or_(read32(operands[0]), read32(operands[1]));
907                         setFlagsForResult<32>(result);
908                         write32(operands[0], result);
909                         break;
910                     }
911                     case 8: {
912                         Word(64) result = policy.or_(read64(operands[0]), read64(operands[1]));
913                         setFlagsForResult<64>(result);
914                         write64(operands[0], result);
915                         break;
916                     }
917
918                     default:
919                         ROSE_ASSERT(!"Bad size");
920                         break;
921                 }
922                 policy.writeFlag(x86_flag_of, policy.false_());
923                 policy.writeFlag(x86_flag_af, policy.undefined_());
924                 policy.writeFlag(x86_flag_cf, policy.false_());
925                 break;
926             }
927
928             case x86_test: {
929                 ROSE_ASSERT(operands.size() == 2);
930                 switch (numBytesInAsmType(operands[0]->get_type())) {
931                     case 1: {
932                         Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
933                         setFlagsForResult<8>(result);
934                         break;
935                     }
936                     case 2: {
937                         Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
938                         setFlagsForResult<16>(result);
939                         break;
940                     }
941                     case 4: {
942                         Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
943                         setFlagsForResult<32>(result);
944                         break;
945                     }
946                     case 8: {
947                         Word(64) result = policy.and_(read64(operands[0]), read64(operands[1]));
948                         setFlagsForResult<64>(result);
949                         break;
950                     }
951  
952                     default:
953                         ROSE_ASSERT(!"Bad size");
954                         break;
955                 }
956                 policy.writeFlag(x86_flag_of, policy.false_());
957                 policy.writeFlag(x86_flag_af, policy.undefined_());
958                 policy.writeFlag(x86_flag_cf, policy.false_());
959                 break;
960             }
961
962             case x86_xor: {
963                 ROSE_ASSERT(operands.size() == 2);
964                 switch (numBytesInAsmType(operands[0]->get_type())) {
965                     case 1: {
966                         Word(8) result = policy.xor_(read8(operands[0]), read8(operands[1]));
967                         setFlagsForResult<8>(result);
968                         write8(operands[0], result);
969                         break;
970                     }
971                     case 2: {
972                         Word(16) result = policy.xor_(read16(operands[0]), read16(operands[1]));
973                         setFlagsForResult<16>(result);
974                         write16(operands[0], result);
975                         break;
976                     }
977                     case 4: {
978                         Word(32) result = policy.xor_(read32(operands[0]), read32(operands[1]));
979                         setFlagsForResult<32>(result);
980                         write32(operands[0], result);
981                         break;
982                     }
983                     case 8: {
984                         Word(64) result = policy.xor_(read64(operands[0]), read64(operands[1]));
985                         setFlagsForResult<64>(result);
986                         write64(operands[0], result);
987                         break;
988                     }
989
990                     default:
991                         ROSE_ASSERT(!"Bad size");
992                         break;
993                 }
994                 policy.writeFlag(x86_flag_of, policy.false_());
995                 policy.writeFlag(x86_flag_af, policy.undefined_());
996                 policy.writeFlag(x86_flag_cf, policy.false_());
997                 break;
998             }
999 /*
1000             case x86_not: {
1001                 ROSE_ASSERT(operands.size() == 1);
1002                 switch (numBytesInAsmType(operands[0]->get_type())) {
1003                     case 1: {
1004                         Word(8) result = policy.invert(read8(operands[0]));
1005                         write8(operands[0], result);
1006                         break;
1007                     }
1008                     case 2: {
1009                         Word(16) result = policy.invert(read16(operands[0]));
1010                         write16(operands[0], result);
1011                         break;
1012                     }
1013                     case 4: {
1014                         Word(32) result = policy.invert(read32(operands[0]));
1015                         write32(operands[0], result);
1016                         break;
1017                     }
1018                     default:
1019                         ROSE_ASSERT(!"Bad size");
1020                         break;
1021                 }
1022                 break;
1023             }
1024 */
1025             case x86_add: {
1026                 ROSE_ASSERT(operands.size() == 2);
1027                 switch (numBytesInAsmType(operands[0]->get_type())) {
1028                     case 1: {
1029                         Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false, policy.false_());
1030                         write8(operands[0], result);
1031                         break;
1032                     }
1033                     case 2: {
1034                         Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false, policy.false_());
1035                         write16(operands[0], result);
1036                         break;
1037                     }
1038                     case 4: {
1039                         Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false, policy.false_());
1040                         write32(operands[0], result);
1041                         break;
1042                     }
1043                     case 8: {
1044                         Word(64) result = doAddOperation<64>(read64(operands[0]), read64(operands[1]), false, policy.false_());
1045                         write64(operands[0], result);
1046                         break;
1047                     }
1048  
1049                     default:
1050                         ROSE_ASSERT(!"Bad size");
1051                         break;
1052                 }
1053                 break;
1054             }
1055 /*
1056             case x86_adc: {
1057                 ROSE_ASSERT(operands.size() == 2);
1058                 switch (numBytesInAsmType(operands[0]->get_type())) {
1059                     case 1: {
1060                         Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false,
1061                                                            policy.readFlag(x86_flag_cf));
1062                         write8(operands[0], result);
1063                         break;
1064                     }
1065                     case 2: {
1066                         Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false,
1067                                                              policy.readFlag(x86_flag_cf));
1068                         write16(operands[0], result);
1069                         break;
1070                     }
1071                     case 4: {
1072                         Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false,
1073                                                              policy.readFlag(x86_flag_cf));
1074                         write32(operands[0], result);
1075                         break;
1076                     }
1077                     default:
1078                         ROSE_ASSERT(!"Bad size");
1079                         break;
1080                 }
1081                 break;
1082             }
1083 */
1084             case x86_sub: {
1085                 ROSE_ASSERT(operands.size() == 2);
1086                 switch (numBytesInAsmType(operands[0]->get_type())) {
1087                     case 1: {
1088                         Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
1089                                                            policy.false_());
1090                         write8(operands[0], result);
1091                         break;
1092                     }
1093                     case 2: {
1094                         Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
1095                                                              policy.false_());
1096                         write16(operands[0], result);
1097                         break;
1098                     }
1099                     case 4: {
1100                         Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
1101                                                              policy.false_());
1102                         write32(operands[0], result);
1103                         break;
1104                     }
1105                     case 8: {
1106                         Word(64) result = doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true,
1107                                                              policy.false_());
1108                         write64(operands[0], result);
1109                         break;
1110                     }
1111
1112                     default:
1113                         ROSE_ASSERT(!"Bad size");
1114                         break;
1115                 }
1116                 break;
1117             }
1118
1119             case x86_sbb: {
1120                 ROSE_ASSERT(operands.size() == 2);
1121                 switch (numBytesInAsmType(operands[0]->get_type())) {
1122                     case 1: {
1123                         Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
1124                                                            policy.readFlag(x86_flag_cf));
1125                         write8(operands[0], result);
1126                         break;
1127                     }
1128                     case 2: {
1129                         Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
1130                                                              policy.readFlag(x86_flag_cf));
1131                         write16(operands[0], result);
1132                         break;
1133                     }
1134                     case 4: {
1135                         Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
1136                                                              policy.readFlag(x86_flag_cf));
1137                         write32(operands[0], result);
1138                         break;
1139                     }
1140                     case 8: {
1141                         Word(64) result = doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true,
1142                                                              policy.readFlag(x86_flag_cf));
1143                         write64(operands[0], result);
1144                         break;
1145                     }
1146
1147                     default:
1148                         ROSE_ASSERT(!"Bad size");
1149                         break;
1150                 }
1151                 break;
1152             }
1153
1154             case x86_cmp: {
1155                 ROSE_ASSERT(operands.size() == 2);
1156                 switch (numBytesInAsmType(operands[0]->get_type())) {
1157                     case 1: {
1158                         doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true, policy.false_());
1159                         break;
1160                     }
1161                     case 2: {
1162                         doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true, policy.false_());
1163                         break;
1164                     }
1165                     case 4: {
1166                         doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true, policy.false_());
1167                         break;
1168                     }
1169                     case 8: {
1170                         doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true, policy.false_());
1171                         break;
1172                     }
1173
1174                     default:
1175                         ROSE_ASSERT(!"Bad size");
1176                         break;
1177                 }
1178                 break;
1179             }
1180
1181             case x86_neg: {
1182                 ROSE_ASSERT(operands.size() == 1);
1183                 switch (numBytesInAsmType(operands[0]->get_type())) {
1184                     case 1: {
1185                         Word(8) result = doAddOperation<8>(number<8>(0), policy.invert(read8(operands[0])), true,
1186                                                            policy.false_());
1187                         write8(operands[0], result);
1188                         break;
1189                     }
1190                     case 2: {
1191                         Word(16) result = doAddOperation<16>(number<16>(0), policy.invert(read16(operands[0])), true,
1192                                                              policy.false_());
1193                         write16(operands[0], result);
1194                         break;
1195                     }
1196                     case 4: {
1197                         Word(32) result = doAddOperation<32>(number<32>(0), policy.invert(read32(operands[0])), true,
1198                                                              policy.false_());
1199                         write32(operands[0], result);
1200                         break;
1201                     }
1202                     case 8: {
1203                         Word(64) result = doAddOperation<64>(number<64>(0), policy.invert(read64(operands[0])), true,
1204                                                              policy.false_());
1205                         write64(operands[0], result);
1206                         break;
1207                     }
1208
1209                     default:
1210                         ROSE_ASSERT(!"Bad size");
1211                         break;
1212                 }
1213                 break;
1214             }
1215
1216             case x86_inc: {
1217                 ROSE_ASSERT(operands.size() == 1);
1218                 switch (numBytesInAsmType(operands[0]->get_type())) {
1219                     case 1: {
1220                         Word(8) result = doIncOperation<8>(read8(operands[0]), false, false);
1221                         write8(operands[0], result);
1222                         break;
1223                     }
1224                     case 2: {
1225                         Word(16) result = doIncOperation<16>(read16(operands[0]), false, false);
1226                         write16(operands[0], result);
1227                         break;
1228                     }
1229                     case 4: {
1230                         Word(32) result = doIncOperation<32>(read32(operands[0]), false, false);
1231                         write32(operands[0], result);
1232                         break;
1233                     }
1234                     case 8: {
1235                         Word(64) result = doIncOperation<64>(read64(operands[0]), false, false);
1236                         write64(operands[0], result);
1237                         break;
1238                     }
1239
1240                     default:
1241                         ROSE_ASSERT(!"Bad size");
1242                         break;
1243                 }
1244                 break;
1245             }
1246
1247             case x86_dec: {
1248                 ROSE_ASSERT(operands.size() == 1);
1249                 switch (numBytesInAsmType(operands[0]->get_type())) {
1250                     case 1: {
1251                         Word(8) result = doIncOperation<8>(read8(operands[0]), true, false);
1252                         write8(operands[0], result);
1253                         break;
1254                     }
1255                     case 2: {
1256                         Word(16) result = doIncOperation<16>(read16(operands[0]), true, false);
1257                         write16(operands[0], result);
1258                         break;
1259                     }
1260                     case 4: {
1261                         Word(32) result = doIncOperation<32>(read32(operands[0]), true, false);
1262                         write32(operands[0], result);
1263                         break;
1264                     }
1265                     case 8: {
1266                         Word(64) result = doIncOperation<64>(read64(operands[0]), true, false);
1267                         write64(operands[0], result);
1268                         break;
1269                     }
1270
1271                     default:
1272                         ROSE_ASSERT(!"Bad size");
1273                         break;
1274                 }
1275                 break;
1276             }
1277 /*
1278             case x86_cmpxchg: {
1279                 ROSE_ASSERT(operands.size() == 2);
1280                 switch (numBytesInAsmType(operands[0]->get_type())) {
1281                     case 1: {
1282                         Word(8) op0 = read8(operands[0]);
1283                         Word(8) oldAx = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1284                         doAddOperation<8>(oldAx, policy.invert(op0), true, policy.false_());
1285                         write8(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read8(operands[1]), op0));
1286                         updateGPRLowByte(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1287                         break;
1288                     }
1289                     case 2: {
1290                         Word(16) op0 = read16(operands[0]);
1291                         Word(16) oldAx = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1292                         doAddOperation<16>(oldAx, policy.invert(op0), true, policy.false_());
1293                         write16(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read16(operands[1]), op0));
1294                         updateGPRLowWord(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1295                         break;
1296                     }
1297                     case 4: {
1298                         Word(32) op0 = read32(operands[0]);
1299                         Word(32) oldAx = policy.readGPR(x86_gpr_ax);
1300                         doAddOperation<32>(oldAx, policy.invert(op0), true, policy.false_());
1301                         write32(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read32(operands[1]), op0));
1302                         policy.writeGPR(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1303                         break;
1304                     }
1305                     default:
1306                         ROSE_ASSERT(!"Bad size");
1307                         break;
1308                 }
1309                 break;
1310             }
1311 */
1312             case x86_shl: {
1313                 //TODO : ask bill, not sure about the shiftCount bound
1314                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1315                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1316                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1317                 switch (numBytesInAsmType(operands[0]->get_type())) {
1318                     case 1: {
1319                         Word(8) op = read8(operands[0]);
1320                         Word(8) output = policy.shiftLeft(op, shiftCount);
1321                         Word(1) newCf = policy.ite(shiftCountZero,
1322                                                    policy.readFlag(x86_flag_cf),
1323                                                    extract<7, 8>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(7)))));
1324                         policy.writeFlag(x86_flag_cf, newCf);
1325                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1326                                                                  policy.readFlag(x86_flag_of),
1327                                                                  policy.xor_(extract<7, 8>(output), newCf)));
1328                         write8(operands[0], output);
1329                         setFlagsForResult<8>(output, policy.invert(shiftCountZero));
1330                         break;
1331                     }
1332                     case 2: {
1333                         Word(16) op = read16(operands[0]);
1334                         Word(16) output = policy.shiftLeft(op, shiftCount);
1335                         Word(1) newCf = policy.ite(shiftCountZero,
1336                                                    policy.readFlag(x86_flag_cf),
1337                                                    extract<15, 16>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(15)))));
1338                         policy.writeFlag(x86_flag_cf, newCf);
1339                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1340                                                                  policy.readFlag(x86_flag_of),
1341                                                                  policy.xor_(extract<15, 16>(output), newCf)));
1342                         write16(operands[0], output);
1343                         setFlagsForResult<16>(output, policy.invert(shiftCountZero));
1344                         break;
1345                     }
1346                     case 4: {
1347                         Word(32) op = read32(operands[0]);
1348                         Word(32) output = policy.shiftLeft(op, shiftCount);
1349                         Word(1) newCf = policy.ite(shiftCountZero,
1350                                                    policy.readFlag(x86_flag_cf),
1351                                                    extract<31, 32>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(31)))));
1352                         policy.writeFlag(x86_flag_cf, newCf);
1353                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1354                                                                  policy.readFlag(x86_flag_of),
1355                                                                  policy.xor_(extract<31, 32>(output), newCf)));
1356                         write32(operands[0], output);
1357                         setFlagsForResult<32>(output, policy.invert(shiftCountZero));
1358                         break;
1359                     }
1360                     case 8: {
1361                         Word(64) op = read64(operands[0]);
1362                         Word(64) output = policy.shiftLeft(op, shiftCount);
1363                         Word(1) newCf = policy.ite(shiftCountZero,
1364                                                    policy.readFlag(x86_flag_cf),
1365                                                    extract<63, 64>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(63)))));
1366                         policy.writeFlag(x86_flag_cf, newCf);
1367                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1368                                                                  policy.readFlag(x86_flag_of),
1369                                                                  policy.xor_(extract<63, 64>(output), newCf)));
1370                         write64(operands[0], output);
1371                         setFlagsForResult<64>(output, policy.invert(shiftCountZero));
1372                         break;
1373                     }
1374
1375                     default:
1376                         ROSE_ASSERT(!"Bad size");
1377                 }
1378                 break;
1379             }
1380
1381             case x86_shr: {
1382                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1383                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1384                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1385                 switch (numBytesInAsmType(operands[0]->get_type())) {
1386                     case 1: {
1387                         Word(8) op = read8(operands[0]);
1388                         Word(8) output = policy.shiftRight(op, shiftCount);
1389                         Word(1) newCf = policy.ite(shiftCountZero,
1390                                                    policy.readFlag(x86_flag_cf),
1391                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(7)))));
1392                         policy.writeFlag(x86_flag_cf, newCf);
1393                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero, policy.readFlag(x86_flag_of), extract<7, 8>(op)));
1394                         write8(operands[0], output);
1395                         setFlagsForResult<8>(output, policy.invert(shiftCountZero));
1396                         break;
1397                     }
1398                     case 2: {
1399                         Word(16) op = read16(operands[0]);
1400                         Word(16) output = policy.shiftRight(op, shiftCount);
1401                         Word(1) newCf = policy.ite(shiftCountZero,
1402                                                    policy.readFlag(x86_flag_cf),
1403                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(15)))));
1404                         policy.writeFlag(x86_flag_cf, newCf);
1405                         policy.writeFlag(x86_flag_of,
1406                                          policy.ite(shiftCountZero, policy.readFlag(x86_flag_of), extract<15, 16>(op)));
1407                         write16(operands[0], output);
1408                         setFlagsForResult<16>(output, policy.invert(shiftCountZero));
1409                         break;
1410                     }
1411                     case 4: {
1412                         Word(32) op = read32(operands[0]);
1413                         Word(32) output = policy.shiftRight(op, shiftCount);
1414                         Word(1) newCf = policy.ite(shiftCountZero,
1415                                                    policy.readFlag(x86_flag_cf),
1416                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(31)))));
1417                         policy.writeFlag(x86_flag_cf, newCf);
1418                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1419                                                                  policy.readFlag(x86_flag_of),
1420                                                                  extract<31, 32>(op)));
1421                         write32(operands[0], output);
1422                         setFlagsForResult<32>(output, policy.invert(shiftCountZero));
1423                         break;
1424                     }
1425                     case 8: {
1426                         Word(64) op = read64(operands[0]);
1427                         Word(64) output = policy.shiftRight(op, shiftCount);
1428                         Word(1) newCf = policy.ite(shiftCountZero,
1429                                                    policy.readFlag(x86_flag_cf),
1430                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(63)))));
1431                         policy.writeFlag(x86_flag_cf, newCf);
1432                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1433                                                                  policy.readFlag(x86_flag_of),
1434                                                                  extract<63, 64>(op)));
1435                         write64(operands[0], output);
1436                         setFlagsForResult<64>(output, policy.invert(shiftCountZero));
1437                         break;
1438                     }
1439
1440                     default:
1441                         ROSE_ASSERT(!"Bad size");
1442                 }
1443                 break;
1444             }
1445
1446             case x86_sar: {
1447                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1448                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1449                 Word(1) shiftCountNotZero = policy.invert(shiftCountZero);
1450                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1451                 switch (numBytesInAsmType(operands[0]->get_type())) {
1452                     case 1: {
1453                         Word(8) op = read8(operands[0]);
1454                         Word(8) output = policy.shiftRightArithmetic(op, shiftCount);
1455                         Word(1) newCf = policy.ite(shiftCountZero,
1456                                                    policy.readFlag(x86_flag_cf),
1457                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(7)))));
1458                         policy.writeFlag(x86_flag_cf, newCf);
1459                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1460                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1461                                                                  policy.readFlag(x86_flag_of),
1462                                                                  policy.false_()));
1463                         write8(operands[0], output);
1464                         setFlagsForResult<8>(output, shiftCountNotZero);
1465                         break;
1466                     }
1467                     case 2: {
1468                         Word(16) op = read16(operands[0]);
1469                         Word(16) output = policy.shiftRightArithmetic(op, shiftCount);
1470                         Word(1) newCf = policy.ite(shiftCountZero,
1471                                                    policy.readFlag(x86_flag_cf),
1472                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(15)))));
1473                         policy.writeFlag(x86_flag_cf, newCf);
1474                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1475                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1476                                                                  policy.readFlag(x86_flag_of),
1477                                                                  policy.false_()));
1478                         write16(operands[0], output);
1479                         setFlagsForResult<16>(output, shiftCountNotZero);
1480                         break;
1481                     }
1482                     case 4: {
1483                         Word(32) op = read32(operands[0]);
1484                         Word(32) output = policy.shiftRightArithmetic(op, shiftCount);
1485                         Word(1) newCf = policy.ite(shiftCountZero,
1486                                                    policy.readFlag(x86_flag_cf),
1487                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(31)))));
1488                         policy.writeFlag(x86_flag_cf, newCf);
1489                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1490                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1491                                                                  policy.readFlag(x86_flag_of),
1492                                                                  policy.false_()));
1493                         write32(operands[0], output);
1494                         setFlagsForResult<32>(output, shiftCountNotZero);
1495                         break;
1496                     }
1497                     case 8: {
1498                         Word(64) op = read64(operands[0]);
1499                         Word(64) output = policy.shiftRightArithmetic(op, shiftCount);
1500                         Word(1) newCf = policy.ite(shiftCountZero,
1501                                                    policy.readFlag(x86_flag_cf),
1502                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(63)))));
1503                         policy.writeFlag(x86_flag_cf, newCf);
1504                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1505                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1506                                                                  policy.readFlag(x86_flag_of),
1507                                                                  policy.false_()));
1508                         write64(operands[0], output);
1509                         setFlagsForResult<64>(output, shiftCountNotZero);
1510                         break;
1511                     }
1512
1513                     default:
1514                         ROSE_ASSERT(!"Bad size");
1515                 }
1516                 break;
1517             }
1518 /*
1519             case x86_rol: {
1520                 switch (numBytesInAsmType(operands[0]->get_type())) {
1521                     case 1: {
1522                         Word(8) op = read8(operands[0]);
1523                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1524                         Word(8) output = policy.rotateLeft(op, shiftCount);
1525                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1526                                                                  policy.readFlag(x86_flag_cf),
1527                                                                  extract<0, 1>(output)));
1528                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1529                                                                  policy.readFlag(x86_flag_of),
1530                                                                  policy.xor_(extract<0, 1>(output), extract<7, 8>(output))));
1531                         write8(operands[0], output);
1532                         break;
1533                     }
1534                     case 2: {
1535                         Word(16) op = read16(operands[0]);
1536                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1537                         Word(16) output = policy.rotateLeft(op, shiftCount);
1538                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1539                                                                  policy.readFlag(x86_flag_cf),
1540                                                                  extract<0, 1>(output)));
1541                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1542                                                                  policy.readFlag(x86_flag_of),
1543                                                                  policy.xor_(extract<0, 1>(output), extract<15, 16>(output))));
1544                         write16(operands[0], output);
1545                         break;
1546                     }
1547                     case 4: {
1548                         Word(32) op = read32(operands[0]);
1549                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1550                         Word(32) output = policy.rotateLeft(op, shiftCount);
1551                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1552                                                                  policy.readFlag(x86_flag_cf),
1553                                                                  extract<0, 1>(output)));
1554                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1555                                                                  policy.readFlag(x86_flag_of),
1556                                                                  policy.xor_(extract<0, 1>(output), extract<31, 32>(output))));
1557                         write32(operands[0], output);
1558                         break;
1559                     }
1560                     default:
1561                         ROSE_ASSERT(!"Bad size");
1562                 }
1563                 break;
1564             }
1565 */
1566             case x86_ror: {
1567                 switch (numBytesInAsmType(operands[0]->get_type())) {
1568                     case 1: {
1569                         Word(8) op = read8(operands[0]);
1570                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1571                         Word(8) output = policy.rotateRight(op, shiftCount);
1572                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1573                                                                  policy.readFlag(x86_flag_cf),
1574                                                                  extract<7, 8>(output)));
1575                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1576                                                                  policy.readFlag(x86_flag_of),
1577                                                                  policy.xor_(extract<6, 7>(output), extract<7, 8>(output))));
1578                         write8(operands[0], output);
1579                         break;
1580                     }
1581                     case 2: {
1582                         Word(16) op = read16(operands[0]);
1583                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1584                         Word(16) output = policy.rotateRight(op, shiftCount);
1585                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1586                                                                  policy.readFlag(x86_flag_cf),
1587                                                                  extract<15, 16>(output)));
1588                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1589                                                                  policy.readFlag(x86_flag_of),
1590                                                                  policy.xor_(extract<14, 15>(output), extract<15, 16>(output))));
1591                         write16(operands[0], output);
1592                         break;
1593                     }
1594                     case 4: {
1595                         Word(32) op = read32(operands[0]);
1596                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1597                         Word(32) output = policy.rotateRight(op, shiftCount);
1598                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1599                                                                  policy.readFlag(x86_flag_cf),
1600                                                                  extract<31, 32>(output)));
1601                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1602                                                                  policy.readFlag(x86_flag_of),
1603                                                                  policy.xor_(extract<30, 31>(output), extract<31, 32>(output))));
1604                         write32(operands[0], output);
1605                         break;
1606                     }
1607                     case 8: {
1608                         Word(64) op = read64(operands[0]);
1609                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1610                         Word(64) output = policy.rotateRight(op, shiftCount);
1611                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1612                                                                  policy.readFlag(x86_flag_cf),
1613                                                                  extract<63, 64>(output)));
1614                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1615                                                                  policy.readFlag(x86_flag_of),
1616                                                                  policy.xor_(extract<62, 63>(output), extract<63, 64>(output))));
1617                         write64(operands[0], output);
1618                         break;
1619                     }
1620
1621                     default:
1622                         ROSE_ASSERT(!"Bad size");
1623                 }
1624                 break;
1625             }
1626 /*
1627             case x86_shld: {
1628                 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1629                 switch (numBytesInAsmType(operands[0]->get_type())) {
1630                     case 2: {
1631                         Word(16) op1 = read16(operands[0]);
1632                         Word(16) op2 = read16(operands[1]);
1633                         Word(16) output1 = policy.shiftLeft(op1, shiftCount);
1634                         Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
1635                                                       number<16>(0),
1636                                                       policy.shiftRight(op2, policy.negate(shiftCount)));
1637                         Word(16) output = policy.or_(output1, output2);
1638                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1639                                                    policy.readFlag(x86_flag_cf),
1640                                                    extract<15, 16>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(15)))));
1641                         policy.writeFlag(x86_flag_cf, newCf);
1642                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1643                                                    policy.readFlag(x86_flag_of), 
1644                                                    policy.xor_(extract<15, 16>(output), newCf));
1645                         policy.writeFlag(x86_flag_of, newOf);
1646                         write16(operands[0], output);
1647                         setFlagsForResult<16>(output);
1648                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1649                                                                  policy.readFlag(x86_flag_af),
1650                                                                  policy.undefined_()));
1651                         break;
1652                     }
1653                     case 4: {
1654                         Word(32) op1 = read32(operands[0]);
1655                         Word(32) op2 = read32(operands[1]);
1656                         Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1657                         Word(32) output1 = policy.shiftLeft(op1, shiftCount);
1658                         Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
1659                                                       number<32>(0),
1660                                                       policy.shiftRight(op2, policy.negate(shiftCount)));
1661                         Word(32) output = policy.or_(output1, output2);
1662                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1663                                                    policy.readFlag(x86_flag_cf),
1664                                                    extract<31, 32>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(31)))));
1665                         policy.writeFlag(x86_flag_cf, newCf);
1666                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1667                                                    policy.readFlag(x86_flag_of), 
1668                                                    policy.xor_(extract<31, 32>(output), newCf));
1669                         policy.writeFlag(x86_flag_of, newOf);
1670                         write32(operands[0], output);
1671                         setFlagsForResult<32>(output);
1672                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1673                                                                  policy.readFlag(x86_flag_af),
1674                                                                  policy.undefined_()));
1675                         break;
1676                     }
1677                     default:
1678                         ROSE_ASSERT(!"Bad size");
1679                 }
1680                 break;
1681             }
1682
1683             case x86_shrd: {
1684                 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1685                 switch (numBytesInAsmType(operands[0]->get_type())) {
1686                     case 2: {
1687                         Word(16) op1 = read16(operands[0]);
1688                         Word(16) op2 = read16(operands[1]);
1689                         Word(16) output1 = policy.shiftRight(op1, shiftCount);
1690                         Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
1691                                                       number<16>(0),
1692                                                       policy.shiftLeft(op2, policy.negate(shiftCount)));
1693                         Word(16) output = policy.or_(output1, output2);
1694                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1695                                                    policy.readFlag(x86_flag_cf),
1696                                                    extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(15)))));
1697                         policy.writeFlag(x86_flag_cf, newCf);
1698                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1699                                                    policy.readFlag(x86_flag_of), 
1700                                                    policy.xor_(extract<15, 16>(output),
1701                                                                extract<15, 16>(op1)));
1702                         policy.writeFlag(x86_flag_of, newOf);
1703                         write16(operands[0], output);
1704                         setFlagsForResult<16>(output);
1705                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1706                                                                  policy.readFlag(x86_flag_af),
1707                                                                  policy.undefined_()));
1708                         break;
1709                     }
1710                     case 4: {
1711                         Word(32) op1 = read32(operands[0]);
1712                         Word(32) op2 = read32(operands[1]);
1713                         Word(32) output1 = policy.shiftRight(op1, shiftCount);
1714                         Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
1715                                                       number<32>(0),
1716                                                       policy.shiftLeft(op2, policy.negate(shiftCount)));
1717                         Word(32) output = policy.or_(output1, output2);
1718                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1719                                                    policy.readFlag(x86_flag_cf),
1720                                                    extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(31)))));
1721                         policy.writeFlag(x86_flag_cf, newCf);
1722                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1723                                                    policy.readFlag(x86_flag_of), 
1724                                                    policy.xor_(extract<31, 32>(output),
1725                                                                extract<31, 32>(op1)));
1726                         policy.writeFlag(x86_flag_of, newOf);
1727                         write32(operands[0], output);
1728                         setFlagsForResult<32>(output);
1729                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1730                                                                  policy.readFlag(x86_flag_af),
1731                                                                  policy.undefined_()));
1732                         break;
1733                     }
1734                     default:
1735                         ROSE_ASSERT(!"Bad size");
1736                 }
1737                 break;
1738             }
1739             */
1740             case x86_bsf: {
1741                 policy.writeFlag(x86_flag_of, policy.undefined_());
1742                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1743                 policy.writeFlag(x86_flag_af, policy.undefined_());
1744                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1745                 policy.writeFlag(x86_flag_cf, policy.undefined_());
1746                 switch (numBytesInAsmType(operands[0]->get_type())) {
1747                     case 2: {
1748                         Word(16) op = read16(operands[1]);
1749                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1750                         Word(16) result = policy.ite(policy.readFlag(x86_flag_zf),
1751                                                      read16(operands[0]),
1752                                                      policy.leastSignificantSetBit(op));
1753                         write16(operands[0], result);
1754                         break;
1755                     }
1756                     case 4: {
1757                         Word(32) op = read32(operands[1]);
1758                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1759                         Word(32) result = policy.ite(policy.readFlag(x86_flag_zf),
1760                                                      read32(operands[0]),
1761                                                      policy.leastSignificantSetBit(op));
1762                         write32(operands[0], result);
1763                         break;
1764                     }
1765                     case 8: {
1766                         Word(64) op = read64(operands[1]);
1767                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1768                         Word(64) result = policy.ite(policy.readFlag(x86_flag_zf),
1769                                                      read64(operands[0]),
1770                                                      policy.leastSignificantSetBit(op));
1771                         write64(operands[0], result);
1772                         break;
1773                     }
1774                     default:
1775                         ROSE_ASSERT(!"Bad size");
1776                 }
1777                 break;
1778             }
1779
1780             case x86_bsr: {
1781                 policy.writeFlag(x86_flag_of, policy.undefined_());
1782                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1783                 policy.writeFlag(x86_flag_af, policy.undefined_());
1784                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1785                 policy.writeFlag(x86_flag_cf, policy.undefined_());
1786                 switch (numBytesInAsmType(operands[0]->get_type())) {
1787                     case 2: {
1788                         Word(16) op = read16(operands[1]);
1789                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1790                         Word(16) result = policy.ite(policy.readFlag(x86_flag_zf),
1791                                                      read16(operands[0]),
1792                                                      policy.mostSignificantSetBit(op));
1793                         write16(operands[0], result);
1794                         break;
1795                     }
1796                     case 4: {
1797                         Word(32) op = read32(operands[1]);
1798                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1799                         Word(32) result = policy.ite(policy.readFlag(x86_flag_zf),
1800                                                      read32(operands[0]),
1801                                                      policy.mostSignificantSetBit(op));
1802                         write32(operands[0], result);
1803                         break;
1804                     }
1805                     case 8: {
1806                         Word(64) op = read64(operands[1]);
1807                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1808                         Word(64) result = policy.ite(policy.readFlag(x86_flag_zf),
1809                                                      read64(operands[0]),
1810                                                      policy.mostSignificantSetBit(op));
1811                         write64(operands[0], result);
1812                         break;
1813                     }
1814                     default:
1815                         ROSE_ASSERT(!"Bad size");
1816                 }
1817                 break;
1818             }
1819             /*
1820             case x86_bts: {
1821                 ROSE_ASSERT(operands.size() == 2);
1822                 // All flags except CF are undefined 
1823                 policy.writeFlag(x86_flag_of, policy.undefined_());
1824                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1825                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1826                 policy.writeFlag(x86_flag_af, policy.undefined_());
1827                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1828                 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
1829                     // Special case allowing multi-word offsets into memory 
1830                     Word(32) addr = readEffectiveAddress(operands[0]);
1831                     int numBytes = numBytesInAsmType(operands[1]->get_type());
1832                     Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
1833                     Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
1834                     Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1835                                                 adjustedAddr, policy.true_());
1836                     Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
1837                     Word(8) result = policy.or_(val, policy.rotateLeft(number<8>(1), extract<0, 3>(bitnum)));
1838                     policy.writeFlag(x86_flag_cf, bitval);
1839                     policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1840                                        adjustedAddr, result, policy.true_());
1841                 } else {
1842                     // Simple case 
1843                     switch (numBytesInAsmType(operands[0]->get_type())) {
1844                         case 2: {
1845                             Word(16) op0 = read16(operands[0]);
1846                             Word(4) bitnum = extract<0, 4>(read16(operands[1]));
1847                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1848                             Word(16) result = policy.or_(op0, policy.rotateLeft(number<16>(1), bitnum));
1849                             policy.writeFlag(x86_flag_cf, bitval);
1850                             write16(operands[0], result);
1851                             break;
1852                         }
1853                         case 4: {
1854                             Word(32) op0 = read32(operands[0]);
1855                             Word(5) bitnum = extract<0, 5>(read32(operands[1]));
1856                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1857                             Word(32) result = policy.or_(op0, policy.rotateLeft(number<32>(1), bitnum));
1858                             policy.writeFlag(x86_flag_cf, bitval);
1859                             write32(operands[0], result);
1860                             break;
1861                         }
1862                         default:
1863                             ROSE_ASSERT(!"Bad size");
1864                     }
1865                 }
1866                 break;
1867             }
1868 */
1869             case x86_imul: {
1870                 switch (numBytesInAsmType(operands[0]->get_type())) {
1871                     case 1: {
1872                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1873                         Word(8) op1 = read8(operands[0]);
1874                         Word(16) mulResult = policy.signedMultiply(op0, op1);
1875                         updateGPRLowWord(x86_gpr_ax, mulResult);
1876                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 16>(mulResult))),
1877                                                                  policy.equalToZero(extract<7, 16>(mulResult))));
1878                         policy.writeFlag(x86_flag_cf, carry);
1879                         policy.writeFlag(x86_flag_of, carry);
1880                         break;
1881                     }
1882                     case 2: {
1883                         Word(16) op0 = operands.size() == 1 ?
1884                                        extract<0, 16>(policy.readGPR(x86_gpr_ax)) :
1885                                        read16(operands[operands.size() - 2]);
1886                         Word(16) op1 = read16(operands[operands.size() - 1]);
1887                         Word(32) mulResult = policy.signedMultiply(op0, op1);
1888                         if (operands.size() == 1) {
1889                             updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1890                             updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1891                         } else {
1892                             write16(operands[0], extract<0, 16>(mulResult));
1893                         }
1894                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 32>(mulResult))),
1895                                                                  policy.equalToZero(extract<7, 32>(mulResult))));
1896                         policy.writeFlag(x86_flag_cf, carry);
1897                         policy.writeFlag(x86_flag_of, carry);
1898                         break;
1899                     }
1900                     case 4: {
1901                         Word(32) op0 = (operands.size() == 1) ? extract<0,32>(policy.readGPR(x86_gpr_ax)) : read32(operands[operands.size() - 2]);
1902                         Word(32) op1 = read32(operands[operands.size() - 1]);
1903                         Word(64) mulResult = policy.signedMultiply(op0, op1);
1904                         if (operands.size() == 1) {
1905                             updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1906                             updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1907                         } else {
1908                             write32(operands[0], extract<0, 32>(mulResult));
1909                         }
1910                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 64>(mulResult))),
1911                                                                  policy.equalToZero(extract<7, 64>(mulResult))));
1912                         policy.writeFlag(x86_flag_cf, carry);
1913                         policy.writeFlag(x86_flag_of, carry);
1914                         break;
1915                     }
1916                     case 8: {
1917                         Word(64) op0 = operands.size() == 1 ? policy.readGPR(x86_gpr_ax) : read64(operands[operands.size() - 2]);
1918                         Word(64) op1 = read64(operands[operands.size() - 1]);
1919                         Word(128) mulResult = policy.signedMultiply(op0, op1);
1920                         if (operands.size() == 1) {
1921                             policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1922                             policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1923                         } else {
1924                             write64(operands[0], extract<0, 64>(mulResult));
1925                         }
1926                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 128>(mulResult))),
1927                                                                  policy.equalToZero(extract<7, 128>(mulResult))));
1928                         policy.writeFlag(x86_flag_cf, carry);
1929                         policy.writeFlag(x86_flag_of, carry);
1930                         break;
1931                     }
1932
1933                     default:
1934                         ROSE_ASSERT(!"Bad size");
1935                 }
1936                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1937                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1938                 policy.writeFlag(x86_flag_af, policy.undefined_());
1939                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1940                 break;
1941             }
1942
1943             case x86_mul: {
1944                 switch (numBytesInAsmType(operands[0]->get_type())) {
1945                     case 1: {
1946                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1947                         Word(8) op1 = read8(operands[0]);
1948                         Word(16) mulResult = policy.unsignedMultiply(op0, op1);
1949                         updateGPRLowWord(x86_gpr_ax, mulResult);
1950                         Word(1) carry = policy.invert(policy.equalToZero(extract<8, 16>(mulResult)));
1951                         policy.writeFlag(x86_flag_cf, carry);
1952                         policy.writeFlag(x86_flag_of, carry);
1953                         break;
1954                     }
1955                     case 2: {
1956                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1957                         Word(16) op1 = read16(operands[0]);
1958                         Word(32) mulResult = policy.unsignedMultiply(op0, op1);
1959                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1960                         updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1961                         Word(1) carry = policy.invert(policy.equalToZero(extract<16, 32>(mulResult)));
1962                         policy.writeFlag(x86_flag_cf, carry);
1963                         policy.writeFlag(x86_flag_of, carry);
1964                         break;
1965                     }
1966                     case 4: {
1967                         Word(32) op0 = extract<0,32>(policy.readGPR(x86_gpr_ax));
1968                         Word(32) op1 = read32(operands[0]);
1969                         Word(64) mulResult = policy.unsignedMultiply(op0, op1);
1970                         updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1971                         updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1972                         Word(1) carry = policy.invert(policy.equalToZero(extract<32, 64>(mulResult)));
1973                         policy.writeFlag(x86_flag_cf, carry);
1974                         policy.writeFlag(x86_flag_of, carry);
1975                         break;
1976                     }
1977                     case 8: {
1978                         Word(64) op0 = policy.readGPR(x86_gpr_ax);
1979                         Word(64) op1 = read64(operands[0]);
1980                         Word(128) mulResult = policy.unsignedMultiply(op0, op1);
1981                         policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1982                         policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1983                         Word(1) carry = policy.invert(policy.equalToZero(extract<64, 128>(mulResult)));
1984                         policy.writeFlag(x86_flag_cf, carry);
1985                         policy.writeFlag(x86_flag_of, carry);
1986                         break;
1987                     }
1988
1989                     default:
1990                         ROSE_ASSERT(!"Bad size");
1991                 }
1992                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1993                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1994                 policy.writeFlag(x86_flag_af, policy.undefined_());
1995                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1996                 break;
1997             }
1998 /*
1999             case x86_idiv: {
2000                 switch (numBytesInAsmType(operands[0]->get_type())) {
2001                     case 1: {
2002                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
2003                         Word(8) op1 = read8(operands[0]);
2004                         // if op1 == 0, we should trap 
2005                         Word(16) divResult = policy.signedDivide(op0, op1);
2006                         Word(8) modResult = policy.signedModulo(op0, op1);
2007                         // if result overflows, we should trap 
2008                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
2009                         break;
2010                     }
2011                     case 2: {
2012                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
2013                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
2014                         Word(16) op1 = read16(operands[0]);
2015                         // if op1 == 0, we should trap 
2016                         Word(32) divResult = policy.signedDivide(op0, op1);
2017                         Word(16) modResult = policy.signedModulo(op0, op1);
2018                         // if result overflows, we should trap 
2019                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2020                         updateGPRLowWord(x86_gpr_dx, modResult);
2021                         break;
2022                     }
2023                     case 4: {
2024                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2025                         Word(32) op1 = read32(operands[0]);
2026                         // if op1 == 0, we should trap
2027                         Word(64) divResult = policy.signedDivide(op0, op1);
2028                         Word(32) modResult = policy.signedModulo(op0, op1);
2029                         // if result overflows, we should trap
2030                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2031                         policy.writeGPR(x86_gpr_dx, modResult);
2032                         break;
2033                     }
2034                     default:
2035                         ROSE_ASSERT(!"Bad size");
2036                 }
2037                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2038                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2039                 policy.writeFlag(x86_flag_af, policy.undefined_());
2040                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2041                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2042                 policy.writeFlag(x86_flag_of, policy.undefined_());
2043                 break;
2044             }
2045
2046             case x86_div: {
2047                 switch (numBytesInAsmType(operands[0]->get_type())) {
2048                     case 1: {
2049                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
2050                         Word(8) op1 = read8(operands[0]);
2051                         // if op1 == 0, we should trap 
2052                         Word(16) divResult = policy.unsignedDivide(op0, op1);
2053                         Word(8) modResult = policy.unsignedModulo(op0, op1);
2054                         // if extract<8, 16> of divResult is non-zero (overflow), we should trap 
2055                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
2056                         break;
2057                     }
2058                     case 2: {
2059                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
2060                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
2061                         Word(16) op1 = read16(operands[0]);
2062                         // if op1 == 0, we should trap 
2063                         Word(32) divResult = policy.unsignedDivide(op0, op1);
2064                         Word(16) modResult = policy.unsignedModulo(op0, op1);
2065                         // if extract<16, 32> of divResult is non-zero (overflow), we should trap 
2066                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2067                         updateGPRLowWord(x86_gpr_dx, modResult);
2068                         break;
2069                     }
2070                     case 4: {
2071                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2072                         Word(32) op1 = read32(operands[0]);
2073                         // if op1 == 0, we should trap 
2074                         Word(64) divResult = policy.unsignedDivide(op0, op1);
2075                         Word(32) modResult = policy.unsignedModulo(op0, op1);
2076                         // if extract<32, 64> of divResult is non-zero (overflow), we should trap 
2077                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2078                         policy.writeGPR(x86_gpr_dx, modResult);
2079                         break;
2080                     }
2081                     default:
2082                         ROSE_ASSERT(!"Bad size");
2083                 }
2084                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2085                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2086                 policy.writeFlag(x86_flag_af, policy.undefined_());
2087                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2088                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2089                 policy.writeFlag(x86_flag_of, policy.undefined_());
2090                 break;
2091             }
2092
2093             case x86_aaa: {
2094                 ROSE_ASSERT(operands.size() == 0);
2095                 Word(1) incAh = policy.or_(policy.readFlag(x86_flag_af),
2096                                            greaterOrEqualToTen<4>(extract<0, 4>(policy.readGPR(x86_gpr_ax))));
2097                 updateGPRLowWord(x86_gpr_ax,
2098                                  policy.concat(policy.add(policy.ite(incAh, number<4>(6), number<4>(0)),
2099                                                           extract<0, 4>(policy.readGPR(x86_gpr_ax))),
2100                                                policy.concat(number<4>(0),
2101                                                              policy.add(policy.ite(incAh, number<8>(1), number<8>(0)),
2102                                                                         extract<8, 16>(policy.readGPR(x86_gpr_ax))))));
2103                 policy.writeFlag(x86_flag_of, policy.undefined_());
2104                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2105                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2106                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2107                 policy.writeFlag(x86_flag_af, incAh);
2108                 policy.writeFlag(x86_flag_cf, incAh);
2109                 break;
2110             }
2111
2112             case x86_aas: {
2113                 ROSE_ASSERT(operands.size() == 0);
2114                 Word(1) decAh = policy.or_(policy.readFlag(x86_flag_af),
2115                                            greaterOrEqualToTen<4>(extract<0, 4>(policy.readGPR(x86_gpr_ax))));
2116                 updateGPRLowWord(x86_gpr_ax,
2117                                  policy.concat(policy.add(policy.ite(decAh, number<4>(-6), number<4>(0)),
2118                                                           extract<0, 4>(policy.readGPR(x86_gpr_ax))),
2119                                                policy.concat(number<4>(0),
2120                                                              policy.add(policy.ite(decAh, number<8>(-1), number<8>(0)),
2121                                                                         extract<8, 16>(policy.readGPR(x86_gpr_ax))))));
2122                 policy.writeFlag(x86_flag_of, policy.undefined_());
2123                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2124                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2125                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2126                 policy.writeFlag(x86_flag_af, decAh);
2127                 policy.writeFlag(x86_flag_cf, decAh);
2128                 break;
2129             }
2130
2131             case x86_aam: {
2132                 ROSE_ASSERT(operands.size() == 1);
2133                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2134                 Word(8) divisor = read8(operands[0]);
2135                 Word(8) newAh = policy.unsignedDivide(al, divisor);
2136                 Word(8) newAl = policy.unsignedModulo(al, divisor);
2137                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, newAh));
2138                 policy.writeFlag(x86_flag_of, policy.undefined_());
2139                 policy.writeFlag(x86_flag_af, policy.undefined_());
2140                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2141                 setFlagsForResult<8>(newAl);
2142                 break;
2143             }
2144
2145             case x86_aad: {
2146                 ROSE_ASSERT(operands.size() == 1);
2147                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2148                 Word(8) ah = extract<8, 16>(policy.readGPR(x86_gpr_ax));
2149                 Word(8) divisor = read8(operands[0]);
2150                 Word(8) newAl = policy.add(al, extract<0, 8>(policy.unsignedMultiply(ah, divisor)));
2151                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, number<8>(0)));
2152                 policy.writeFlag(x86_flag_of, policy.undefined_());
2153                 policy.writeFlag(x86_flag_af, policy.undefined_());
2154                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2155                 setFlagsForResult<8>(newAl);
2156                 break;
2157             }
2158
2159             case x86_bswap: {
2160                 ROSE_ASSERT(operands.size() == 1);
2161                 Word(32) oldVal = read32(operands[0]);
2162                 Word(32) newVal = policy.concat(extract<24, 32>(oldVal),
2163                                                 policy.concat(extract<16, 24>(oldVal),
2164                                                               policy.concat(extract<8, 16>(oldVal),
2165                                                                             extract<0, 8>(oldVal))));
2166                 write32(operands[0], newVal);
2167                 break;
2168             }
2169 */
2170             case x86_push: {
2171                 ROSE_ASSERT(operands.size() == 1);
2172                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2173                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2174
2175                 // Override hack for push <segreg>
2176                 // TODO: ask bill
2177                 if (operands[0]->variantT() == V_SgAsmx86RegisterReferenceExpression) {
2178                    SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(operands[0]);
2179                    if (rre->get_register_class() == x86_regclass_segment) {
2180                       Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2181                       Word(64) newSp = policy.add(oldSp, number<64>(-2));
2182                       policy.writeMemory(x86_segreg_ss, newSp, read16(operands[0]), policy.true_());
2183                       policy.writeGPR(x86_gpr_sp, newSp);
2184                       break;
2185                    }
2186                 }
2187                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2188                 Word(64) newSp = policy.add(oldSp, number<64>(-8));
2189                 policy.writeMemory(x86_segreg_ss, newSp, read64(operands[0]), policy.true_());
2190                 policy.writeGPR(x86_gpr_sp, newSp);                      
2191
2192                 break;
2193             }
2194 /*
2195             case x86_pushad: {
2196                 ROSE_ASSERT(operands.size() == 0);
2197                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2198                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2199                 Word(32) newSp = policy.add(oldSp, number<32>(-32));
2200                 policy.writeMemory(x86_segreg_ss, newSp, policy.readGPR(x86_gpr_di), policy.true_());
2201                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(4)), policy.readGPR(x86_gpr_si), policy.true_());
2202                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(8)), policy.readGPR(x86_gpr_bp), policy.true_());
2203                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(12)), oldSp, policy.true_());
2204                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(16)), policy.readGPR(x86_gpr_bx), policy.true_());
2205                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(20)), policy.readGPR(x86_gpr_dx), policy.true_());
2206                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(24)), policy.readGPR(x86_gpr_cx), policy.true_());
2207                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(28)), policy.readGPR(x86_gpr_ax), policy.true_());
2208                 policy.writeGPR(x86_gpr_sp, newSp);
2209                 break;
2210             }
2211
2212             case x86_pushfd: {
2213                 ROSE_ASSERT(operands.size() == 0);
2214                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2215                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2216                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2217                 policy.writeMemory(x86_segreg_ss, newSp, readEflags(), policy.true_());
2218                 policy.writeGPR(x86_gpr_sp, newSp);
2219                 break;
2220             }
2221 */
2222
2223             case x86_pop: {
2224                 ROSE_ASSERT(operands.size() == 1);
2225                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2226                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2227                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2228                 Word(64) newSp = policy.add(oldSp, number<64>(8));
2229                 write64(operands[0], readMemory<64>(x86_segreg_ss, oldSp, policy.true_()));
2230                 policy.writeGPR(x86_gpr_sp, newSp);
2231                 break;
2232             }
2233 /*
2234             case x86_popad: {
2235                 ROSE_ASSERT(operands.size() == 0);
2236                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2237                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2238                 Word(32) newSp = policy.add(oldSp, number<32>(32));
2239                 policy.writeGPR(x86_gpr_di, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2240                 policy.writeGPR(x86_gpr_si, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(4)), policy.true_()));
2241                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(8)), policy.true_()));
2242                 policy.writeGPR(x86_gpr_bx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(16)), policy.true_()));
2243                 policy.writeGPR(x86_gpr_dx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(20)), policy.true_()));
2244                 policy.writeGPR(x86_gpr_cx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(24)), policy.true_()));
2245                 policy.writeGPR(x86_gpr_ax, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(28)), policy.true_()));
2246                 readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(12)), policy.true_());
2247                 policy.writeGPR(x86_gpr_sp, newSp);
2248                 break;
2249             }
2250
2251             case x86_leave: {
2252                 ROSE_ASSERT(operands.size() == 0);
2253                 policy.writeGPR(x86_gpr_sp, policy.readGPR(x86_gpr_bp));
2254                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2255                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2256                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2257                 Word(32) newSp = policy.add(oldSp, number<32>(4));
2258                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2259                 policy.writeGPR(x86_gpr_sp, newSp);
2260                 break;
2261             }
2262
2263             case x86_call: {
2264                 ROSE_ASSERT(operands.size() == 1);
2265                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2266                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2267                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2268                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2269                 policy.writeMemory(x86_segreg_ss, newSp, policy.readIP(), policy.true_());
2270                 policy.writeIP(policy.filterCallTarget(read32(operands[0])));
2271                 policy.writeGPR(x86_gpr_sp, newSp);
2272                 break;
2273             }
2274
2275             case x86_ret: {
2276                 ROSE_ASSERT(operands.size() <= 1);
2277                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2278                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2279                                 Word(32) extraBytes = (operands.size() == 1 ? read32(operands[0]) : number<32>(0));
2280                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2281                 Word(32) newSp = policy.add(oldSp, policy.add(number<32>(4), extraBytes));
2282                 policy.writeIP(policy.filterReturnTarget(readMemory<32>(x86_segreg_ss, oldSp, policy.true_())));
2283                 policy.writeGPR(x86_gpr_sp, newSp);
2284                 break;
2285             }
2286
2287             case x86_loop: {
2288                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2289                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2290                 ROSE_ASSERT(operands.size() == 1);
2291                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2292                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2293                 policy.writeGPR(x86_gpr_cx, newCx);
2294                 Word(1) doLoop = policy.invert(policy.equalToZero(newCx));
2295                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2296                 break;
2297             }
2298             case x86_loopz: {
2299                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2300                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2301                 ROSE_ASSERT(operands.size() == 1);
2302                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2303                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2304                 policy.writeGPR(x86_gpr_cx, newCx);
2305                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)), policy.readFlag(x86_flag_zf));
2306                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2307                 break;
2308             }
2309             case x86_loopnz: {
2310                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2311                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2312                 ROSE_ASSERT(operands.size() == 1);
2313                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2314                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2315                 policy.writeGPR(x86_gpr_cx, newCx);
2316                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)),
2317                                              policy.invert(policy.readFlag(x86_flag_zf)));
2318                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2319                 break;
2320             }
2321 */
2322             case x86_jmp: {
2323                 ROSE_ASSERT(operands.size() == 1);
2324                 policy.writeIP(policy.filterIndirectJumpTarget(read64(operands[0])));
2325                 break;
2326             }
2327
2328
2329             /* Flag expressions that must be true for a conditional jump to occur. */
2330 #           define FLAGCOMBO_ne    policy.invert(policy.readFlag(x86_flag_zf))
2331 #           define FLAGCOMBO_e     policy.readFlag(x86_flag_zf)
2332 #           define FLAGCOMBO_no    policy.invert(policy.readFlag(x86_flag_of))
2333 #           define FLAGCOMBO_o     policy.readFlag(x86_flag_of)
2334 #           define FLAGCOMBO_ns    policy.invert(policy.readFlag(x86_flag_sf))
2335 #           define FLAGCOMBO_s     policy.readFlag(x86_flag_sf)
2336 #           define FLAGCOMBO_po    policy.invert(policy.readFlag(x86_flag_pf))
2337 #           define FLAGCOMBO_pe    policy.readFlag(x86_flag_pf)
2338 #           define FLAGCOMBO_ae    policy.invert(policy.readFlag(x86_flag_cf))
2339 #           define FLAGCOMBO_b     policy.readFlag(x86_flag_cf)
2340 #           define FLAGCOMBO_be    policy.or_(FLAGCOMBO_b, FLAGCOMBO_e)
2341 #           define FLAGCOMBO_a     policy.and_(FLAGCOMBO_ae, FLAGCOMBO_ne)
2342 #           define FLAGCOMBO_l     policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of))
2343 #           define FLAGCOMBO_ge    policy.invert(policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of)))
2344 #           define FLAGCOMBO_le    policy.or_(FLAGCOMBO_e, FLAGCOMBO_l)
2345 #           define FLAGCOMBO_g     policy.and_(FLAGCOMBO_ge, FLAGCOMBO_ne)
2346 #           define FLAGCOMBO_cxz   policy.equalToZero(extract<0, 16>(policy.readGPR(x86_gpr_cx)))
2347 #           define FLAGCOMBO_ecxz  policy.equalToZero(policy.readGPR(x86_gpr_cx))
2348
2349 #           define JUMP(tag) {                                                                                                 \
2350                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2351                 policy.writeIP(policy.ite(FLAGCOMBO_##tag,                                                                     \
2352                                           read64(operands[0]),                                                                 \
2353                                           policy.readIP()));                                                                   \
2354             }
2355             case x86_jne:   JUMP(ne);   break;
2356             case x86_je:    JUMP(e);    break;
2357             case x86_jno:   JUMP(no);   break;
2358             case x86_jo:    JUMP(o);    break;
2359             case x86_jpo:   JUMP(po);   break;
2360             case x86_jpe:   JUMP(pe);   break;
2361             case x86_jns:   JUMP(ns);   break;
2362             case x86_js:    JUMP(s);    break;
2363             case x86_jae:   JUMP(ae);   break;
2364             case x86_jb:    JUMP(b);    break;
2365             case x86_jbe:   JUMP(be);   break;
2366             case x86_ja:    JUMP(a);    break;
2367             case x86_jle:   JUMP(le);   break;
2368             case x86_jg:    JUMP(g);    break;
2369             case x86_jge:   JUMP(ge);   break;
2370             case x86_jl:    JUMP(l);    break;
2371             case x86_jcxz:  JUMP(cxz);  break;
2372             case x86_jecxz: JUMP(ecxz); break;
2373 #           undef JUMP
2374
2375 #           define SET(tag) {                                                                                                  \
2376                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2377                 write8(operands[0], policy.concat(FLAGCOMBO_##tag, number<7>(0)));                                             \
2378             }
2379             case x86_setne: SET(ne); break;
2380             case x86_sete:  SET(e);  break;
2381             case x86_setno: SET(no); break;
2382             case x86_seto:  SET(o);  break;
2383             case x86_setpo: SET(po); break;
2384             case x86_setpe: SET(pe); break;
2385             case x86_setns: SET(ns); break;
2386             case x86_sets:  SET(s);  break;
2387             case x86_setae: SET(ae); break;
2388             case x86_setb:  SET(b);  break;
2389             case x86_setbe: SET(be); break;
2390             case x86_seta:  SET(a);  break;
2391             case x86_setle: SET(le); break;
2392             case x86_setg:  SET(g);  break;
2393             case x86_setge: SET(ge); break;
2394             case x86_setl:  SET(l);  break;
2395 #           undef SET
2396                 
2397 #           define CMOV(tag) {                                                                                                 \
2398                 ROSE_ASSERT(operands.size() == 2);                                                                             \
2399                 switch (numBytesInAsmType(operands[0]->get_type())) {                                                          \
2400                     case 2: write16(operands[0], policy.ite(FLAGCOMBO_##tag, read16(operands[1]), read16(operands[0]))); break; \
2401                     case 4: write32(operands[0], policy.ite(FLAGCOMBO_##tag, read32(operands[1]), read32(operands[0]))); break; \
2402                     case 8: write64(operands[0], policy.ite(FLAGCOMBO_##tag, read64(operands[1]), read64(operands[0]))); break; \
2403                     default: ROSE_ASSERT(!"Bad size"); break;                                                                   \
2404                 }                                                                                                              \
2405             }
2406 /*            case x86_cmovne:    CMOV(ne);       break;
2407             case x86_cmove:     CMOV(e);        break;
2408             case x86_cmovno:    CMOV(no);       break;
2409             case x86_cmovo:     CMOV(o);        break;
2410             case x86_cmovpo:    CMOV(po);       break;
2411             case x86_cmovpe:    CMOV(pe);       break;
2412             case x86_cmovns:    CMOV(ns);       break;
2413             case x86_cmovs:     CMOV(s);        break;
2414             case x86_cmovae:    CMOV(ae);       break;
2415             case x86_cmovb:     CMOV(b);        break;
2416             case x86_cmovbe:    CMOV(be);       break;
2417             case x86_cmova:     CMOV(a);        break;
2418             case x86_cmovle:    CMOV(le);       break;
2419             case x86_cmovg:     CMOV(g);        break;
2420             case x86_cmovge:    CMOV(ge);       break;
2421             case x86_cmovl:     CMOV(l);        break;
2422 */          
2423 #           undef CMOV
2424
2425             /* The flag expressions are no longer needed */
2426 #           undef FLAGCOMBO_ne
2427 #           undef FLAGCOMBO_e
2428 #           undef FLAGCOMBO_ns
2429 #           undef FLAGCOMBO_s
2430 #           undef FLAGCOMBO_ae
2431 #           undef FLAGCOMBO_b
2432 #           undef FLAGCOMBO_be
2433 #           undef FLAGCOMBO_a
2434 #           undef FLAGCOMBO_l
2435 #           undef FLAGCOMBO_ge
2436 #           undef FLAGCOMBO_le
2437 #           undef FLAGCOMBO_g
2438 #           undef FLAGCOMBO_cxz
2439 #           undef FLAGCOMBO_ecxz
2440
2441             case x86_cld: {
2442                 ROSE_ASSERT(operands.size() == 0);
2443                 policy.writeFlag(x86_flag_df, policy.false_());
2444                 break;
2445             }
2446
2447             case x86_std: {
2448                 ROSE_ASSERT(operands.size() == 0);
2449                 policy.writeFlag(x86_flag_df, policy.true_());
2450                 break;
2451             }
2452
2453             case x86_clc: {
2454                 ROSE_ASSERT(operands.size() == 0);
2455                 policy.writeFlag(x86_flag_cf, policy.false_());
2456                 break;
2457             }
2458
2459             case x86_stc: {
2460                 ROSE_ASSERT(operands.size() == 0);
2461                 policy.writeFlag(x86_flag_cf, policy.true_());
2462                 break;
2463             }
2464
2465             case x86_cmc: {
2466                 ROSE_ASSERT(operands.size() == 0);
2467                 policy.writeFlag(x86_flag_cf, policy.invert(policy.readFlag(x86_flag_cf)));
2468                 break;
2469             }
2470
2471             case x86_nop:
2472                 break;
2473
2474 #           define STRINGOP_LOAD_SI(len, cond)                                                                                 \
2475                 readMemory<(8 * (len))>((insn->get_segmentOverride() == x86_segreg_none ?                                      \
2476                                          x86_segreg_ds :                                                                       \
2477                                          insn->get_segmentOverride()),                                                         \
2478                                         policy.readGPR(x86_gpr_si),                                                            \
2479                                         (cond))
2480             
2481 #           define STRINGOP_LOAD_DI(len, cond)                                                                                 \
2482                 readMemory<(8 * (len))>(x86_segreg_es, policy.readGPR(x86_gpr_di), (cond))
2483
2484             /* If true, repeat this instruction, otherwise go to the next one */
2485 #           define STRINGOP_LOOP_E                                                                                             \
2486                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.readFlag(x86_flag_zf)),                               \
2487                                           number<64>((uint64_t)(insn->get_address())),                                         \
2488                                           policy.readIP()))
2489
2490             /* If true, repeat this instruction, otherwise go to the next one */
2491 #           define STRINGOP_LOOP_NE                                                                                            \
2492                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.invert(policy.readFlag(x86_flag_zf))),                \
2493                                           number<64>((uint64_t)(insn->get_address())),                                         \
2494                                           policy.readIP()))
2495
2496 #           define REP_SCAS(suffix, len, repsuffix, loopmacro) {                                                               \
2497                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2498                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2499                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2500                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2501                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2502                                           true,                                                                                \
2503                                           policy.false_(),                                                                     \
2504                                           ecxNotZero);                                                                         \
2505                 policy.writeGPR(x86_gpr_di,                                                                                    \
2506                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2507                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2508                 loopmacro;                                                                                                     \
2509             }
2510             case x86_repne_scasb: REP_SCAS(b, 1, ne, STRINGOP_LOOP_NE); break;
2511             case x86_repne_scasw: REP_SCAS(w, 2, ne, STRINGOP_LOOP_NE); break;
2512             case x86_repne_scasd: REP_SCAS(d, 4, ne, STRINGOP_LOOP_NE); break;
2513             case x86_repe_scasb:  REP_SCAS(b, 1, e,  STRINGOP_LOOP_E);  break;
2514             case x86_repe_scasw:  REP_SCAS(w, 2, e,  STRINGOP_LOOP_E);  break;
2515             case x86_repe_scasd:  REP_SCAS(d, 4, e,  STRINGOP_LOOP_E);  break;
2516 #           undef REP_SCAS
2517
2518 #           define SCAS(suffix, len) {                                                                                         \
2519                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2520                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2521                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2522                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2523                                           true,                                                                                \
2524                                           policy.false_(),                                                                     \
2525                                           policy.true_());                                                                     \
2526                 policy.writeGPR(x86_gpr_di,                                                                                    \
2527                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2528                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2529             }
2530             case x86_scasb: SCAS(b, 1); break;
2531             case x86_scasw: SCAS(w, 2); break;
2532             case x86_scasd: SCAS(d, 4); break;
2533 #           undef SCAS
2534
2535 #           define REP_CMPS(suffix, len, repsuffix, loopmacro) {                                                               \
2536                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2537                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2538                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2539                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, ecxNotZero),                                                   \
2540                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2541                                           true,                                                                                \
2542                                           policy.false_(),                                                                     \
2543                                           ecxNotZero);                                                                         \
2544                 policy.writeGPR(x86_gpr_si,                                                                                    \
2545                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2546                                            policy.ite(ecxNotZero,                                                              \
2547                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2548                                                                  number<64>(-(len)),                                           \
2549                                                                  number<64>(len)),                                             \
2550                                                       number<64>(0))));                                                        \
2551                 policy.writeGPR(x86_gpr_di,                                                                                    \
2552                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2553                                            policy.ite(ecxNotZero,                                                              \
2554                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2555                                                                  number<64>(-(len)),                                           \
2556                                                                  number<64>(len)),                                             \
2557                                                       number<64>(0))));                                                        \
2558                 loopmacro;                                                                                                     \
2559             }
2560             case x86_repne_cmpsb: REP_CMPS(b, 1, ne, STRINGOP_LOOP_NE); break;
2561             case x86_repne_cmpsw: REP_CMPS(w, 2, ne, STRINGOP_LOOP_NE); break;
2562             case x86_repne_cmpsd: REP_CMPS(d, 4, ne, STRINGOP_LOOP_NE); break;
2563             case x86_repe_cmpsb:  REP_CMPS(b, 1, e,  STRINGOP_LOOP_E);  break;
2564             case x86_repe_cmpsw:  REP_CMPS(w, 2, e,  STRINGOP_LOOP_E);  break;
2565             case x86_repe_cmpsd:  REP_CMPS(d, 4, e,  STRINGOP_LOOP_E);  break;
2566 #           undef REP_CMPS
2567
2568 #           define CMPS(suffix, len) {                                                                                         \
2569                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2570                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2571                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, policy.true_()),                                               \
2572                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2573                                           true,                                                                                \
2574                                           policy.false_(),                                                                     \
2575                                           policy.true_());                                                                     \
2576                 policy.writeGPR(x86_gpr_si,                                                                                    \
2577                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2578                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2579                 policy.writeGPR(x86_gpr_di,                                                                                    \
2580                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2581                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2582             }
2583             case x86_cmpsb: CMPS(b, 1); break;
2584             case x86_cmpsw: CMPS(w, 2); break;
2585             case x86_cmpsd: CMPS(d, 4); break;
2586 #           undef CMPS
2587
2588 #           define MOVS(suffix, len) {                                                                                         \
2589                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2590                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2591                 policy.writeMemory(x86_segreg_es,                                                                              \
2592                                    policy.readGPR(x86_gpr_di),                                                                 \
2593                                    STRINGOP_LOAD_SI(len, policy.true_()),                                                      \
2594                                    policy.true_());                                                                            \
2595                 policy.writeGPR(x86_gpr_si,                                                                                    \
2596                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2597                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2598                 policy.writeGPR(x86_gpr_di,                                                                                    \
2599                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2600                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2601             }
2602             case x86_movsb: MOVS(b, 1); break;
2603             case x86_movsw: MOVS(w, 2); break;
2604             case x86_movsd: MOVS(d, 4); break;
2605 #           undef MOVS
2606
2607 #           define REP_MOVS(suffix, len) {                                                                                     \
2608                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2609                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2610                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2611                 policy.writeMemory(x86_segreg_es, policy.readGPR(x86_gpr_di), STRINGOP_LOAD_SI(len, ecxNotZero), ecxNotZero);  \
2612                 policy.writeGPR(x86_gpr_si,                                                                                    \
2613                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2614                                            policy.ite(ecxNotZero,                                                              \
2615                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2616                                                                  number<64>(-(len)),                                           \
2617                                                                  number<64>(len)),                                             \
2618                                                       number<64>(0))));                                                        \
2619                 policy.writeGPR(x86_gpr_di,                                                                                    \
2620                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2621                                            policy.ite(ecxNotZero,                                                              \
2622                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2623                                                                  number<64>(-(len)),                                           \
2624                                                                  number<64>(len)),                                             \
2625                                                       number<64>(0))));                                                        \
2626                 policy.writeIP(policy.ite(ecxNotZero, /* If true, repeat this instruction, otherwise go to the next one */     \
2627                                           number<64>((uint32_t)(insn->get_address())),                                         \
2628                                           policy.readIP()));                                                                   \
2629             }
2630             case x86_rep_movsb: REP_MOVS(b, 1); break;
2631             case x86_rep_movsw: REP_MOVS(w, 2); break;
2632             case x86_rep_movsd: REP_MOVS(d, 4); break;
2633 #           undef REP_MOVS
2634
2635             case x86_stosb: {
2636                 stos_semantics<1>(insn);
2637                 break;
2638             }
2639
2640             case x86_rep_stosb: {
2641                 rep_stos_semantics<1>(insn);
2642                 break;
2643             }
2644
2645             case x86_stosw: {
2646                 stos_semantics<2>(insn);
2647                 break;
2648             }
2649
2650             case x86_rep_stosw: {
2651                 rep_stos_semantics<2>(insn);
2652                 break;
2653             }
2654
2655             case x86_stosd: {
2656                 stos_semantics<4>(insn);
2657                 break;
2658             }
2659
2660             case x86_rep_stosd: {
2661                 rep_stos_semantics<4>(insn);
2662                 break;
2663             }
2664
2665 #           define LODS(suffix, len, regupdate) {                                                                              \
2666                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2667                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2668                 regupdate(x86_gpr_ax, STRINGOP_LOAD_SI(len, policy.true_()));                                                  \
2669                 policy.writeGPR(x86_gpr_si,                                                                                    \
2670                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2671                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2672             }
2673             case x86_lodsb: LODS(b, 1, updateGPRLowByte); break;
2674             case x86_lodsw: LODS(w, 2, updateGPRLowWord); break;
2675             case x86_lodsd: LODS(d, 4, updateGPRLowDWord);  break;
2676 #           undef LODS
2677
2678 #undef STRINGOP_LOAD_SI
2679 #undef STRINGOP_LOAD_DI
2680 #undef STRINGOP_UPDATE_CX
2681 #undef STRINGOP_LOOP_E
2682 #undef STRINGOP_LOOP_NE
2683
2684             case x86_hlt: {
2685                 ROSE_ASSERT(operands.size() == 0);
2686                 policy.hlt();
2687                 policy.writeIP(number<64>((uint64_t)(insn->get_address())));
2688                 break;
2689             }
2690 /*
2691             case x86_rdtsc: {
2692                 ROSE_ASSERT(operands.size() == 0);
2693                 Word(64) tsc = policy.rdtsc();
2694                 policy.writeGPR(x86_gpr_ax, extract<0, 32>(tsc));
2695                 policy.writeGPR(x86_gpr_dx, extract<32, 64>(tsc));
2696                 break;
2697             }
2698
2699             case x86_int: {
2700                 ROSE_ASSERT(operands.size() == 1);
2701                 SgAsmByteValueExpression* bv = isSgAsmByteValueExpression(operands[0]);
2702                 ROSE_ASSERT(bv);
2703                 policy.interrupt(bv->get_value());
2704                 break;
2705             }
2706 */
2707                 /* This is a dummy version that should be replaced later FIXME */
2708 /*            case x86_fnstcw: {
2709                 ROSE_ASSERT(operands.size() == 1);
2710                 write16(operands[0], number<16>(0x37f));
2711                 break;
2712             }
2713
2714             case x86_fldcw: {
2715                 ROSE_ASSERT(operands.size() == 1);
2716                 read16(operands[0]); // To catch access control violations 
2717                 break;
2718             }
2719 */
2720             default: {
2721
2722 //                std::cerr <<"Bad instruction [0x" <<std::hex <<insn->get_address() <<": "// <<unparseInstruction(insn) <<"]"
2723 //                          <<" (skipping semantic analysis)\n";
2724                 break;
2725             }
2726         }
2727     }
2728
2729     void processInstruction(SgAsmx86Instruction* insn) {
2730         ROSE_ASSERT(insn);
2731         policy.startInstruction(insn);
2732         translate(insn);
2733         policy.finishInstruction(insn);
2734     }
2735
2736     /*
2737     void processBlock(const SgAsmStatementPtrList& stmts, size_t begin, size_t end) {
2738         if (begin == end) return;
2739         policy.startBlock(stmts[begin]->get_address());
2740         for (size_t i = begin; i < end; ++i) {
2741             processInstruction(isSgAsmx86Instruction(stmts[i]));
2742         }
2743         policy.finishBlock(stmts[begin]->get_address());
2744     }
2745     */
2746
2747     static bool isRepeatedStringOp(SgAsmx86Instruction* insn) {
2748         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2749         if (!insn) return false;
2750         switch (insn->get_kind()) {
2751             case x86_repe_cmpsb: return true;
2752             case x86_repe_cmpsd: return true;
2753             case x86_repe_cmpsq: return true;
2754             case x86_repe_cmpsw: return true;
2755             case x86_repe_scasb: return true;
2756             case x86_repe_scasd: return true;
2757             case x86_repe_scasq: return true;
2758             case x86_repe_scasw: return true;
2759             case x86_rep_insb: return true;
2760             case x86_rep_insd: return true;
2761             case x86_rep_insw: return true;
2762             case x86_rep_lodsb: return true;
2763             case x86_rep_lodsd: return true;
2764             case x86_rep_lodsq: return true;
2765             case x86_rep_lodsw: return true;
2766             case x86_rep_movsb: return true;
2767             case x86_rep_movsd: return true;
2768             case x86_rep_movsq: return true;
2769             case x86_rep_movsw: return true;
2770             case x86_repne_cmpsb: return true;
2771             case x86_repne_cmpsd: return true;
2772             case x86_repne_cmpsq: return true;
2773             case x86_repne_cmpsw: return true;
2774             case x86_repne_scasb: return true;
2775             case x86_repne_scasd: return true;
2776             case x86_repne_scasq: return true;
2777             case x86_repne_scasw: return true;
2778             case x86_rep_outsb: return true;
2779             case x86_rep_outsd: return true;
2780             case x86_rep_outsw: return true;
2781             case x86_rep_stosb: return true;
2782             case x86_rep_stosd: return true;
2783             case x86_rep_stosq: return true;
2784             case x86_rep_stosw: return true;
2785             default: return false;
2786         }
2787     }
2788
2789     static bool isHltOrInt(SgAsmx86Instruction* insn) {
2790         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2791         if (!insn) return false;
2792         switch (insn->get_kind()) {
2793             case x86_hlt: return true;
2794             case x86_int: return true;
2795             default: return false;
2796         }
2797     }
2798
2799 #if 0
2800     void processBlock(SgAsmBlock* b) {
2801         const SgAsmStatementPtrList& stmts = b->get_statementList();
2802         if (stmts.empty()) return;
2803         if (!isSgAsmInstruction(stmts[0])) return; /* A block containing functions or something */
2804         size_t i = 0;
2805         while (i < stmts.size()) {
2806             size_t oldI = i;
2807             /* Advance until either i points to a repeated string op or it is just after a hlt or int */
2808             while (i < stmts.size() && !isRepeatedStringOp(stmts[i]) && (i == oldI || !isHltOrInt(stmts[i - 1]))) ++i;
2809             processBlock(stmts, oldI, i);
2810             if (i >= stmts.size()) break;
2811             if (isRepeatedStringOp(stmts[i])) {
2812                 processBlock(stmts, i, i + 1);
2813                 ++i;
2814             }
2815             ROSE_ASSERT(i != oldI);
2816         }
2817     }
2818 #endif
2819
2820 };
2821
2822 #undef Word
2823
2824 #endif // ROSE_X86_64INSTRUCTIONSEMANTICS_H