1. Add inc, dec, neg instruction semantics for x86-64
[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                                 ROSE_ASSERT(!"Bad size");
774                         }
775                         break;
776                     }
777                     case 8: {
778                         switch (numBytesInAsmType(operands[1]->get_type())) {
779                             case 1: {
780                                 Word(8) op1 = read8(operands[1]);
781                                 Word(64) result = signExtend<8, 64>(op1);
782                                 write64(operands[0], result);
783                                 break;
784                             }
785                             case 2: {
786                                 Word(16) op1 = read16(operands[1]);
787                                 Word(64) result = signExtend<16, 64>(op1);
788                                 write64(operands[0], result);
789                                 break;
790                             }
791                             case 4: {
792                                 Word(32) op1 = read32(operands[1]);
793                                 Word(64) result = signExtend<32, 64>(op1);
794                                 write64(operands[0], result);
795                                 break;
796                             }
797                             default:
798                                 ROSE_ASSERT(!"Bad size");
799                         }
800                         break;
801                     }
802
803                     default:
804                         ROSE_ASSERT(!"Bad size");
805                         break;
806                 }
807                 break;
808             }
809 /*
810             case x86_cbw: {
811                 ROSE_ASSERT(operands.size() == 0);
812                 updateGPRLowWord(x86_gpr_ax, signExtend<8, 16>(extract<0, 8>(policy.readGPR(x86_gpr_ax))));
813                 break;
814             }
815 */
816             case x86_cwde: {
817                 ROSE_ASSERT(operands.size() == 0);
818                 policy.writeGPR(x86_gpr_ax, signExtend<16, 64>(extract<0, 16>(policy.readGPR(x86_gpr_ax))));
819                 break;
820             }
821 /*
822             case x86_cwd: {
823                 ROSE_ASSERT(operands.size() == 0);
824                 updateGPRLowWord(x86_gpr_dx, extract<16, 32>(signExtend<16, 32>(extract<0, 16>(policy.readGPR(x86_gpr_ax)))));
825                 break;
826             }
827
828             case x86_cdq: {
829                 ROSE_ASSERT(operands.size() == 0);
830                 policy.writeGPR(x86_gpr_dx, extract<32, 64>(signExtend<32, 64>(policy.readGPR(x86_gpr_ax))));
831                 break;
832             }
833 */
834             case x86_lea: {
835                 ROSE_ASSERT(operands.size() == 2);
836                 switch (numBytesInAsmType(operands[0]->get_type())) {
837                     case 4: {
838                         write32(operands[0], extract<0,32>(readEffectiveAddress(operands[1])));
839                         break;
840                     }
841                     case 8: {
842                         write64(operands[0], readEffectiveAddress(operands[1]));
843                         break;
844                     }
845                     default:
846                         ROSE_ASSERT(!"Bad size!");
847                 }
848                 break;
849             }
850
851             case x86_and: {
852                 ROSE_ASSERT(operands.size() == 2);
853                 switch (numBytesInAsmType(operands[0]->get_type())) {
854                     case 1: {
855                         Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
856                         setFlagsForResult<8>(result);
857                         write8(operands[0], result);
858                         break;
859                     }
860                     case 2: {
861                         Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
862                         setFlagsForResult<16>(result);
863                         write16(operands[0], result);
864                         break;
865                     }
866                     case 4: {
867                         Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
868                         setFlagsForResult<32>(result);
869                         write32(operands[0], result);
870                         break;
871                     }
872                     case 8: {
873                         Word(64) result = policy.and_(read64(operands[0]), read64(operands[1]));
874                         setFlagsForResult<64>(result);
875                         write64(operands[0], result);
876                         break;
877                     }
878
879                     default:
880                         ROSE_ASSERT(!"Bad size");
881                         break;
882                 }
883                 policy.writeFlag(x86_flag_of, policy.false_());
884                 policy.writeFlag(x86_flag_af, policy.undefined_());
885                 policy.writeFlag(x86_flag_cf, policy.false_());
886                 break;
887             }
888
889             case x86_or: {
890                 ROSE_ASSERT(operands.size() == 2);
891                 switch (numBytesInAsmType(operands[0]->get_type())) {
892                     case 1: {
893                         Word(8) result = policy.or_(read8(operands[0]), read8(operands[1]));
894                         setFlagsForResult<8>(result);
895                         write8(operands[0], result);
896                         break;
897                     }
898                     case 2: {
899                         Word(16) result = policy.or_(read16(operands[0]), read16(operands[1]));
900                         setFlagsForResult<16>(result);
901                         write16(operands[0], result);
902                         break;
903                     }
904                     case 4: {
905                         Word(32) result = policy.or_(read32(operands[0]), read32(operands[1]));
906                         setFlagsForResult<32>(result);
907                         write32(operands[0], result);
908                         break;
909                     }
910                     case 8: {
911                         Word(64) result = policy.or_(read64(operands[0]), read64(operands[1]));
912                         setFlagsForResult<64>(result);
913                         write64(operands[0], result);
914                         break;
915                     }
916
917                     default:
918                         ROSE_ASSERT(!"Bad size");
919                         break;
920                 }
921                 policy.writeFlag(x86_flag_of, policy.false_());
922                 policy.writeFlag(x86_flag_af, policy.undefined_());
923                 policy.writeFlag(x86_flag_cf, policy.false_());
924                 break;
925             }
926
927             case x86_test: {
928                 ROSE_ASSERT(operands.size() == 2);
929                 switch (numBytesInAsmType(operands[0]->get_type())) {
930                     case 1: {
931                         Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
932                         setFlagsForResult<8>(result);
933                         break;
934                     }
935                     case 2: {
936                         Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
937                         setFlagsForResult<16>(result);
938                         break;
939                     }
940                     case 4: {
941                         Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
942                         setFlagsForResult<32>(result);
943                         break;
944                     }
945                     case 8: {
946                         Word(64) result = policy.and_(read64(operands[0]), read64(operands[1]));
947                         setFlagsForResult<64>(result);
948                         break;
949                     }
950  
951                     default:
952                         ROSE_ASSERT(!"Bad size");
953                         break;
954                 }
955                 policy.writeFlag(x86_flag_of, policy.false_());
956                 policy.writeFlag(x86_flag_af, policy.undefined_());
957                 policy.writeFlag(x86_flag_cf, policy.false_());
958                 break;
959             }
960
961             case x86_xor: {
962                 ROSE_ASSERT(operands.size() == 2);
963                 switch (numBytesInAsmType(operands[0]->get_type())) {
964                     case 1: {
965                         Word(8) result = policy.xor_(read8(operands[0]), read8(operands[1]));
966                         setFlagsForResult<8>(result);
967                         write8(operands[0], result);
968                         break;
969                     }
970                     case 2: {
971                         Word(16) result = policy.xor_(read16(operands[0]), read16(operands[1]));
972                         setFlagsForResult<16>(result);
973                         write16(operands[0], result);
974                         break;
975                     }
976                     case 4: {
977                         Word(32) result = policy.xor_(read32(operands[0]), read32(operands[1]));
978                         setFlagsForResult<32>(result);
979                         write32(operands[0], result);
980                         break;
981                     }
982                     case 8: {
983                         Word(64) result = policy.xor_(read64(operands[0]), read64(operands[1]));
984                         setFlagsForResult<64>(result);
985                         write64(operands[0], result);
986                         break;
987                     }
988
989                     default:
990                         ROSE_ASSERT(!"Bad size");
991                         break;
992                 }
993                 policy.writeFlag(x86_flag_of, policy.false_());
994                 policy.writeFlag(x86_flag_af, policy.undefined_());
995                 policy.writeFlag(x86_flag_cf, policy.false_());
996                 break;
997             }
998 /*
999             case x86_not: {
1000                 ROSE_ASSERT(operands.size() == 1);
1001                 switch (numBytesInAsmType(operands[0]->get_type())) {
1002                     case 1: {
1003                         Word(8) result = policy.invert(read8(operands[0]));
1004                         write8(operands[0], result);
1005                         break;
1006                     }
1007                     case 2: {
1008                         Word(16) result = policy.invert(read16(operands[0]));
1009                         write16(operands[0], result);
1010                         break;
1011                     }
1012                     case 4: {
1013                         Word(32) result = policy.invert(read32(operands[0]));
1014                         write32(operands[0], result);
1015                         break;
1016                     }
1017                     default:
1018                         ROSE_ASSERT(!"Bad size");
1019                         break;
1020                 }
1021                 break;
1022             }
1023 */
1024             case x86_add: {
1025                 ROSE_ASSERT(operands.size() == 2);
1026                 switch (numBytesInAsmType(operands[0]->get_type())) {
1027                     case 1: {
1028                         Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false, policy.false_());
1029                         write8(operands[0], result);
1030                         break;
1031                     }
1032                     case 2: {
1033                         Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false, policy.false_());
1034                         write16(operands[0], result);
1035                         break;
1036                     }
1037                     case 4: {
1038                         Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false, policy.false_());
1039                         write32(operands[0], result);
1040                         break;
1041                     }
1042                     case 8: {
1043                         Word(64) result = doAddOperation<64>(read64(operands[0]), read64(operands[1]), false, policy.false_());
1044                         write64(operands[0], result);
1045                         break;
1046                     }
1047  
1048                     default:
1049                         ROSE_ASSERT(!"Bad size");
1050                         break;
1051                 }
1052                 break;
1053             }
1054 /*
1055             case x86_adc: {
1056                 ROSE_ASSERT(operands.size() == 2);
1057                 switch (numBytesInAsmType(operands[0]->get_type())) {
1058                     case 1: {
1059                         Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false,
1060                                                            policy.readFlag(x86_flag_cf));
1061                         write8(operands[0], result);
1062                         break;
1063                     }
1064                     case 2: {
1065                         Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false,
1066                                                              policy.readFlag(x86_flag_cf));
1067                         write16(operands[0], result);
1068                         break;
1069                     }
1070                     case 4: {
1071                         Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false,
1072                                                              policy.readFlag(x86_flag_cf));
1073                         write32(operands[0], result);
1074                         break;
1075                     }
1076                     default:
1077                         ROSE_ASSERT(!"Bad size");
1078                         break;
1079                 }
1080                 break;
1081             }
1082 */
1083             case x86_sub: {
1084                 ROSE_ASSERT(operands.size() == 2);
1085                 switch (numBytesInAsmType(operands[0]->get_type())) {
1086                     case 1: {
1087                         Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
1088                                                            policy.false_());
1089                         write8(operands[0], result);
1090                         break;
1091                     }
1092                     case 2: {
1093                         Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
1094                                                              policy.false_());
1095                         write16(operands[0], result);
1096                         break;
1097                     }
1098                     case 4: {
1099                         Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
1100                                                              policy.false_());
1101                         write32(operands[0], result);
1102                         break;
1103                     }
1104                     case 8: {
1105                         Word(64) result = doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true,
1106                                                              policy.false_());
1107                         write64(operands[0], result);
1108                         break;
1109                     }
1110
1111                     default:
1112                         ROSE_ASSERT(!"Bad size");
1113                         break;
1114                 }
1115                 break;
1116             }
1117
1118             case x86_sbb: {
1119                 ROSE_ASSERT(operands.size() == 2);
1120                 switch (numBytesInAsmType(operands[0]->get_type())) {
1121                     case 1: {
1122                         Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
1123                                                            policy.readFlag(x86_flag_cf));
1124                         write8(operands[0], result);
1125                         break;
1126                     }
1127                     case 2: {
1128                         Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
1129                                                              policy.readFlag(x86_flag_cf));
1130                         write16(operands[0], result);
1131                         break;
1132                     }
1133                     case 4: {
1134                         Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
1135                                                              policy.readFlag(x86_flag_cf));
1136                         write32(operands[0], result);
1137                         break;
1138                     }
1139                     case 8: {
1140                         Word(64) result = doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true,
1141                                                              policy.readFlag(x86_flag_cf));
1142                         write64(operands[0], result);
1143                         break;
1144                     }
1145
1146                     default:
1147                         ROSE_ASSERT(!"Bad size");
1148                         break;
1149                 }
1150                 break;
1151             }
1152
1153             case x86_cmp: {
1154                 ROSE_ASSERT(operands.size() == 2);
1155                 switch (numBytesInAsmType(operands[0]->get_type())) {
1156                     case 1: {
1157                         doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true, policy.false_());
1158                         break;
1159                     }
1160                     case 2: {
1161                         doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true, policy.false_());
1162                         break;
1163                     }
1164                     case 4: {
1165                         doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true, policy.false_());
1166                         break;
1167                     }
1168                     case 8: {
1169                         doAddOperation<64>(read64(operands[0]), policy.invert(read64(operands[1])), true, policy.false_());
1170                         break;
1171                     }
1172
1173                     default:
1174                         ROSE_ASSERT(!"Bad size");
1175                         break;
1176                 }
1177                 break;
1178             }
1179
1180             case x86_neg: {
1181                 ROSE_ASSERT(operands.size() == 1);
1182                 switch (numBytesInAsmType(operands[0]->get_type())) {
1183                     case 1: {
1184                         Word(8) result = doAddOperation<8>(number<8>(0), policy.invert(read8(operands[0])), true,
1185                                                            policy.false_());
1186                         write8(operands[0], result);
1187                         break;
1188                     }
1189                     case 2: {
1190                         Word(16) result = doAddOperation<16>(number<16>(0), policy.invert(read16(operands[0])), true,
1191                                                              policy.false_());
1192                         write16(operands[0], result);
1193                         break;
1194                     }
1195                     case 4: {
1196                         Word(32) result = doAddOperation<32>(number<32>(0), policy.invert(read32(operands[0])), true,
1197                                                              policy.false_());
1198                         write32(operands[0], result);
1199                         break;
1200                     }
1201                     case 8: {
1202                         Word(64) result = doAddOperation<64>(number<64>(0), policy.invert(read64(operands[0])), true,
1203                                                              policy.false_());
1204                         write64(operands[0], result);
1205                         break;
1206                     }
1207
1208                     default:
1209                         ROSE_ASSERT(!"Bad size");
1210                         break;
1211                 }
1212                 break;
1213             }
1214
1215             case x86_inc: {
1216                 ROSE_ASSERT(operands.size() == 1);
1217                 switch (numBytesInAsmType(operands[0]->get_type())) {
1218                     case 1: {
1219                         Word(8) result = doIncOperation<8>(read8(operands[0]), false, false);
1220                         write8(operands[0], result);
1221                         break;
1222                     }
1223                     case 2: {
1224                         Word(16) result = doIncOperation<16>(read16(operands[0]), false, false);
1225                         write16(operands[0], result);
1226                         break;
1227                     }
1228                     case 4: {
1229                         Word(32) result = doIncOperation<32>(read32(operands[0]), false, false);
1230                         write32(operands[0], result);
1231                         break;
1232                     }
1233                     case 8: {
1234                         Word(64) result = doIncOperation<64>(read64(operands[0]), false, false);
1235                         write64(operands[0], result);
1236                         break;
1237                     }
1238
1239                     default:
1240                         ROSE_ASSERT(!"Bad size");
1241                         break;
1242                 }
1243                 break;
1244             }
1245
1246             case x86_dec: {
1247                 ROSE_ASSERT(operands.size() == 1);
1248                 switch (numBytesInAsmType(operands[0]->get_type())) {
1249                     case 1: {
1250                         Word(8) result = doIncOperation<8>(read8(operands[0]), true, false);
1251                         write8(operands[0], result);
1252                         break;
1253                     }
1254                     case 2: {
1255                         Word(16) result = doIncOperation<16>(read16(operands[0]), true, false);
1256                         write16(operands[0], result);
1257                         break;
1258                     }
1259                     case 4: {
1260                         Word(32) result = doIncOperation<32>(read32(operands[0]), true, false);
1261                         write32(operands[0], result);
1262                         break;
1263                     }
1264                     case 8: {
1265                         Word(64) result = doIncOperation<64>(read64(operands[0]), true, false);
1266                         write64(operands[0], result);
1267                         break;
1268                     }
1269
1270                     default:
1271                         ROSE_ASSERT(!"Bad size");
1272                         break;
1273                 }
1274                 break;
1275             }
1276 /*
1277             case x86_cmpxchg: {
1278                 ROSE_ASSERT(operands.size() == 2);
1279                 switch (numBytesInAsmType(operands[0]->get_type())) {
1280                     case 1: {
1281                         Word(8) op0 = read8(operands[0]);
1282                         Word(8) oldAx = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1283                         doAddOperation<8>(oldAx, policy.invert(op0), true, policy.false_());
1284                         write8(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read8(operands[1]), op0));
1285                         updateGPRLowByte(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1286                         break;
1287                     }
1288                     case 2: {
1289                         Word(16) op0 = read16(operands[0]);
1290                         Word(16) oldAx = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1291                         doAddOperation<16>(oldAx, policy.invert(op0), true, policy.false_());
1292                         write16(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read16(operands[1]), op0));
1293                         updateGPRLowWord(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1294                         break;
1295                     }
1296                     case 4: {
1297                         Word(32) op0 = read32(operands[0]);
1298                         Word(32) oldAx = policy.readGPR(x86_gpr_ax);
1299                         doAddOperation<32>(oldAx, policy.invert(op0), true, policy.false_());
1300                         write32(operands[0], policy.ite(policy.readFlag(x86_flag_zf), read32(operands[1]), op0));
1301                         policy.writeGPR(x86_gpr_ax, policy.ite(policy.readFlag(x86_flag_zf), oldAx, op0));
1302                         break;
1303                     }
1304                     default:
1305                         ROSE_ASSERT(!"Bad size");
1306                         break;
1307                 }
1308                 break;
1309             }
1310 */
1311             case x86_shl: {
1312                 //TODO : ask bill, not sure about the shiftCount bound
1313                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1314                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1315                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1316                 switch (numBytesInAsmType(operands[0]->get_type())) {
1317                     case 1: {
1318                         Word(8) op = read8(operands[0]);
1319                         Word(8) output = policy.shiftLeft(op, shiftCount);
1320                         Word(1) newCf = policy.ite(shiftCountZero,
1321                                                    policy.readFlag(x86_flag_cf),
1322                                                    extract<7, 8>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(7)))));
1323                         policy.writeFlag(x86_flag_cf, newCf);
1324                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1325                                                                  policy.readFlag(x86_flag_of),
1326                                                                  policy.xor_(extract<7, 8>(output), newCf)));
1327                         write8(operands[0], output);
1328                         setFlagsForResult<8>(output, policy.invert(shiftCountZero));
1329                         break;
1330                     }
1331                     case 2: {
1332                         Word(16) op = read16(operands[0]);
1333                         Word(16) output = policy.shiftLeft(op, shiftCount);
1334                         Word(1) newCf = policy.ite(shiftCountZero,
1335                                                    policy.readFlag(x86_flag_cf),
1336                                                    extract<15, 16>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(15)))));
1337                         policy.writeFlag(x86_flag_cf, newCf);
1338                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1339                                                                  policy.readFlag(x86_flag_of),
1340                                                                  policy.xor_(extract<15, 16>(output), newCf)));
1341                         write16(operands[0], output);
1342                         setFlagsForResult<16>(output, policy.invert(shiftCountZero));
1343                         break;
1344                     }
1345                     case 4: {
1346                         Word(32) op = read32(operands[0]);
1347                         Word(32) output = policy.shiftLeft(op, shiftCount);
1348                         Word(1) newCf = policy.ite(shiftCountZero,
1349                                                    policy.readFlag(x86_flag_cf),
1350                                                    extract<31, 32>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(31)))));
1351                         policy.writeFlag(x86_flag_cf, newCf);
1352                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1353                                                                  policy.readFlag(x86_flag_of),
1354                                                                  policy.xor_(extract<31, 32>(output), newCf)));
1355                         write32(operands[0], output);
1356                         setFlagsForResult<32>(output, policy.invert(shiftCountZero));
1357                         break;
1358                     }
1359                     case 8: {
1360                         Word(64) op = read64(operands[0]);
1361                         Word(64) output = policy.shiftLeft(op, shiftCount);
1362                         Word(1) newCf = policy.ite(shiftCountZero,
1363                                                    policy.readFlag(x86_flag_cf),
1364                                                    extract<63, 64>(policy.shiftLeft(op, policy.add(shiftCount, number<5>(63)))));
1365                         policy.writeFlag(x86_flag_cf, newCf);
1366                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1367                                                                  policy.readFlag(x86_flag_of),
1368                                                                  policy.xor_(extract<63, 64>(output), newCf)));
1369                         write64(operands[0], output);
1370                         setFlagsForResult<64>(output, policy.invert(shiftCountZero));
1371                         break;
1372                     }
1373
1374                     default:
1375                         ROSE_ASSERT(!"Bad size");
1376                 }
1377                 break;
1378             }
1379
1380             case x86_shr: {
1381                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1382                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1383                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1384                 switch (numBytesInAsmType(operands[0]->get_type())) {
1385                     case 1: {
1386                         Word(8) op = read8(operands[0]);
1387                         Word(8) output = policy.shiftRight(op, shiftCount);
1388                         Word(1) newCf = policy.ite(shiftCountZero,
1389                                                    policy.readFlag(x86_flag_cf),
1390                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(7)))));
1391                         policy.writeFlag(x86_flag_cf, newCf);
1392                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero, policy.readFlag(x86_flag_of), extract<7, 8>(op)));
1393                         write8(operands[0], output);
1394                         setFlagsForResult<8>(output, policy.invert(shiftCountZero));
1395                         break;
1396                     }
1397                     case 2: {
1398                         Word(16) op = read16(operands[0]);
1399                         Word(16) output = policy.shiftRight(op, shiftCount);
1400                         Word(1) newCf = policy.ite(shiftCountZero,
1401                                                    policy.readFlag(x86_flag_cf),
1402                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(15)))));
1403                         policy.writeFlag(x86_flag_cf, newCf);
1404                         policy.writeFlag(x86_flag_of,
1405                                          policy.ite(shiftCountZero, policy.readFlag(x86_flag_of), extract<15, 16>(op)));
1406                         write16(operands[0], output);
1407                         setFlagsForResult<16>(output, policy.invert(shiftCountZero));
1408                         break;
1409                     }
1410                     case 4: {
1411                         Word(32) op = read32(operands[0]);
1412                         Word(32) output = policy.shiftRight(op, shiftCount);
1413                         Word(1) newCf = policy.ite(shiftCountZero,
1414                                                    policy.readFlag(x86_flag_cf),
1415                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(31)))));
1416                         policy.writeFlag(x86_flag_cf, newCf);
1417                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1418                                                                  policy.readFlag(x86_flag_of),
1419                                                                  extract<31, 32>(op)));
1420                         write32(operands[0], output);
1421                         setFlagsForResult<32>(output, policy.invert(shiftCountZero));
1422                         break;
1423                     }
1424                     case 8: {
1425                         Word(64) op = read64(operands[0]);
1426                         Word(64) output = policy.shiftRight(op, shiftCount);
1427                         Word(1) newCf = policy.ite(shiftCountZero,
1428                                                    policy.readFlag(x86_flag_cf),
1429                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(63)))));
1430                         policy.writeFlag(x86_flag_cf, newCf);
1431                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1432                                                                  policy.readFlag(x86_flag_of),
1433                                                                  extract<63, 64>(op)));
1434                         write64(operands[0], output);
1435                         setFlagsForResult<64>(output, policy.invert(shiftCountZero));
1436                         break;
1437                     }
1438
1439                     default:
1440                         ROSE_ASSERT(!"Bad size");
1441                 }
1442                 break;
1443             }
1444
1445             case x86_sar: {
1446                 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1447                 Word(1) shiftCountZero = policy.equalToZero(shiftCount);
1448                 Word(1) shiftCountNotZero = policy.invert(shiftCountZero);
1449                 policy.writeFlag(x86_flag_af, policy.ite(shiftCountZero, policy.readFlag(x86_flag_af), policy.undefined_()));
1450                 switch (numBytesInAsmType(operands[0]->get_type())) {
1451                     case 1: {
1452                         Word(8) op = read8(operands[0]);
1453                         Word(8) output = policy.shiftRightArithmetic(op, shiftCount);
1454                         Word(1) newCf = policy.ite(shiftCountZero,
1455                                                    policy.readFlag(x86_flag_cf),
1456                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(7)))));
1457                         policy.writeFlag(x86_flag_cf, newCf);
1458                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1459                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1460                                                                  policy.readFlag(x86_flag_of),
1461                                                                  policy.false_()));
1462                         write8(operands[0], output);
1463                         setFlagsForResult<8>(output, shiftCountNotZero);
1464                         break;
1465                     }
1466                     case 2: {
1467                         Word(16) op = read16(operands[0]);
1468                         Word(16) output = policy.shiftRightArithmetic(op, shiftCount);
1469                         Word(1) newCf = policy.ite(shiftCountZero,
1470                                                    policy.readFlag(x86_flag_cf),
1471                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(15)))));
1472                         policy.writeFlag(x86_flag_cf, newCf);
1473                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1474                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1475                                                                  policy.readFlag(x86_flag_of),
1476                                                                  policy.false_()));
1477                         write16(operands[0], output);
1478                         setFlagsForResult<16>(output, shiftCountNotZero);
1479                         break;
1480                     }
1481                     case 4: {
1482                         Word(32) op = read32(operands[0]);
1483                         Word(32) output = policy.shiftRightArithmetic(op, shiftCount);
1484                         Word(1) newCf = policy.ite(shiftCountZero,
1485                                                    policy.readFlag(x86_flag_cf),
1486                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(31)))));
1487                         policy.writeFlag(x86_flag_cf, newCf);
1488                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1489                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1490                                                                  policy.readFlag(x86_flag_of),
1491                                                                  policy.false_()));
1492                         write32(operands[0], output);
1493                         setFlagsForResult<32>(output, shiftCountNotZero);
1494                         break;
1495                     }
1496                     case 8: {
1497                         Word(64) op = read64(operands[0]);
1498                         Word(64) output = policy.shiftRightArithmetic(op, shiftCount);
1499                         Word(1) newCf = policy.ite(shiftCountZero,
1500                                                    policy.readFlag(x86_flag_cf),
1501                                                    extract<0, 1>(policy.shiftRight(op, policy.add(shiftCount, number<5>(63)))));
1502                         policy.writeFlag(x86_flag_cf, newCf);
1503                         // No change with sc = 0, clear when sc = 1, undefined otherwise 
1504                         policy.writeFlag(x86_flag_of, policy.ite(shiftCountZero,
1505                                                                  policy.readFlag(x86_flag_of),
1506                                                                  policy.false_()));
1507                         write64(operands[0], output);
1508                         setFlagsForResult<64>(output, shiftCountNotZero);
1509                         break;
1510                     }
1511
1512                     default:
1513                         ROSE_ASSERT(!"Bad size");
1514                 }
1515                 break;
1516             }
1517 /*
1518             case x86_rol: {
1519                 switch (numBytesInAsmType(operands[0]->get_type())) {
1520                     case 1: {
1521                         Word(8) op = read8(operands[0]);
1522                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1523                         Word(8) output = policy.rotateLeft(op, shiftCount);
1524                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1525                                                                  policy.readFlag(x86_flag_cf),
1526                                                                  extract<0, 1>(output)));
1527                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1528                                                                  policy.readFlag(x86_flag_of),
1529                                                                  policy.xor_(extract<0, 1>(output), extract<7, 8>(output))));
1530                         write8(operands[0], output);
1531                         break;
1532                     }
1533                     case 2: {
1534                         Word(16) op = read16(operands[0]);
1535                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1536                         Word(16) output = policy.rotateLeft(op, shiftCount);
1537                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1538                                                                  policy.readFlag(x86_flag_cf),
1539                                                                  extract<0, 1>(output)));
1540                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1541                                                                  policy.readFlag(x86_flag_of),
1542                                                                  policy.xor_(extract<0, 1>(output), extract<15, 16>(output))));
1543                         write16(operands[0], output);
1544                         break;
1545                     }
1546                     case 4: {
1547                         Word(32) op = read32(operands[0]);
1548                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1549                         Word(32) output = policy.rotateLeft(op, shiftCount);
1550                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1551                                                                  policy.readFlag(x86_flag_cf),
1552                                                                  extract<0, 1>(output)));
1553                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1554                                                                  policy.readFlag(x86_flag_of),
1555                                                                  policy.xor_(extract<0, 1>(output), extract<31, 32>(output))));
1556                         write32(operands[0], output);
1557                         break;
1558                     }
1559                     default:
1560                         ROSE_ASSERT(!"Bad size");
1561                 }
1562                 break;
1563             }
1564 */
1565             case x86_ror: {
1566                 switch (numBytesInAsmType(operands[0]->get_type())) {
1567                     case 1: {
1568                         Word(8) op = read8(operands[0]);
1569                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1570                         Word(8) output = policy.rotateRight(op, shiftCount);
1571                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1572                                                                  policy.readFlag(x86_flag_cf),
1573                                                                  extract<7, 8>(output)));
1574                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1575                                                                  policy.readFlag(x86_flag_of),
1576                                                                  policy.xor_(extract<6, 7>(output), extract<7, 8>(output))));
1577                         write8(operands[0], output);
1578                         break;
1579                     }
1580                     case 2: {
1581                         Word(16) op = read16(operands[0]);
1582                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1583                         Word(16) output = policy.rotateRight(op, shiftCount);
1584                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1585                                                                  policy.readFlag(x86_flag_cf),
1586                                                                  extract<15, 16>(output)));
1587                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1588                                                                  policy.readFlag(x86_flag_of),
1589                                                                  policy.xor_(extract<14, 15>(output), extract<15, 16>(output))));
1590                         write16(operands[0], output);
1591                         break;
1592                     }
1593                     case 4: {
1594                         Word(32) op = read32(operands[0]);
1595                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1596                         Word(32) output = policy.rotateRight(op, shiftCount);
1597                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1598                                                                  policy.readFlag(x86_flag_cf),
1599                                                                  extract<31, 32>(output)));
1600                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1601                                                                  policy.readFlag(x86_flag_of),
1602                                                                  policy.xor_(extract<30, 31>(output), extract<31, 32>(output))));
1603                         write32(operands[0], output);
1604                         break;
1605                     }
1606                     case 8: {
1607                         Word(64) op = read64(operands[0]);
1608                         Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
1609                         Word(64) output = policy.rotateRight(op, shiftCount);
1610                         policy.writeFlag(x86_flag_cf, policy.ite(policy.equalToZero(shiftCount),
1611                                                                  policy.readFlag(x86_flag_cf),
1612                                                                  extract<63, 64>(output)));
1613                         policy.writeFlag(x86_flag_of, policy.ite(policy.equalToZero(shiftCount),
1614                                                                  policy.readFlag(x86_flag_of),
1615                                                                  policy.xor_(extract<62, 63>(output), extract<63, 64>(output))));
1616                         write64(operands[0], output);
1617                         break;
1618                     }
1619
1620                     default:
1621                         ROSE_ASSERT(!"Bad size");
1622                 }
1623                 break;
1624             }
1625 /*
1626             case x86_shld: {
1627                 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1628                 switch (numBytesInAsmType(operands[0]->get_type())) {
1629                     case 2: {
1630                         Word(16) op1 = read16(operands[0]);
1631                         Word(16) op2 = read16(operands[1]);
1632                         Word(16) output1 = policy.shiftLeft(op1, shiftCount);
1633                         Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
1634                                                       number<16>(0),
1635                                                       policy.shiftRight(op2, policy.negate(shiftCount)));
1636                         Word(16) output = policy.or_(output1, output2);
1637                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1638                                                    policy.readFlag(x86_flag_cf),
1639                                                    extract<15, 16>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(15)))));
1640                         policy.writeFlag(x86_flag_cf, newCf);
1641                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1642                                                    policy.readFlag(x86_flag_of), 
1643                                                    policy.xor_(extract<15, 16>(output), newCf));
1644                         policy.writeFlag(x86_flag_of, newOf);
1645                         write16(operands[0], output);
1646                         setFlagsForResult<16>(output);
1647                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1648                                                                  policy.readFlag(x86_flag_af),
1649                                                                  policy.undefined_()));
1650                         break;
1651                     }
1652                     case 4: {
1653                         Word(32) op1 = read32(operands[0]);
1654                         Word(32) op2 = read32(operands[1]);
1655                         Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1656                         Word(32) output1 = policy.shiftLeft(op1, shiftCount);
1657                         Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
1658                                                       number<32>(0),
1659                                                       policy.shiftRight(op2, policy.negate(shiftCount)));
1660                         Word(32) output = policy.or_(output1, output2);
1661                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1662                                                    policy.readFlag(x86_flag_cf),
1663                                                    extract<31, 32>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(31)))));
1664                         policy.writeFlag(x86_flag_cf, newCf);
1665                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1666                                                    policy.readFlag(x86_flag_of), 
1667                                                    policy.xor_(extract<31, 32>(output), newCf));
1668                         policy.writeFlag(x86_flag_of, newOf);
1669                         write32(operands[0], output);
1670                         setFlagsForResult<32>(output);
1671                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1672                                                                  policy.readFlag(x86_flag_af),
1673                                                                  policy.undefined_()));
1674                         break;
1675                     }
1676                     default:
1677                         ROSE_ASSERT(!"Bad size");
1678                 }
1679                 break;
1680             }
1681
1682             case x86_shrd: {
1683                 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
1684                 switch (numBytesInAsmType(operands[0]->get_type())) {
1685                     case 2: {
1686                         Word(16) op1 = read16(operands[0]);
1687                         Word(16) op2 = read16(operands[1]);
1688                         Word(16) output1 = policy.shiftRight(op1, shiftCount);
1689                         Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
1690                                                       number<16>(0),
1691                                                       policy.shiftLeft(op2, policy.negate(shiftCount)));
1692                         Word(16) output = policy.or_(output1, output2);
1693                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1694                                                    policy.readFlag(x86_flag_cf),
1695                                                    extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(15)))));
1696                         policy.writeFlag(x86_flag_cf, newCf);
1697                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1698                                                    policy.readFlag(x86_flag_of), 
1699                                                    policy.xor_(extract<15, 16>(output),
1700                                                                extract<15, 16>(op1)));
1701                         policy.writeFlag(x86_flag_of, newOf);
1702                         write16(operands[0], output);
1703                         setFlagsForResult<16>(output);
1704                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1705                                                                  policy.readFlag(x86_flag_af),
1706                                                                  policy.undefined_()));
1707                         break;
1708                     }
1709                     case 4: {
1710                         Word(32) op1 = read32(operands[0]);
1711                         Word(32) op2 = read32(operands[1]);
1712                         Word(32) output1 = policy.shiftRight(op1, shiftCount);
1713                         Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
1714                                                       number<32>(0),
1715                                                       policy.shiftLeft(op2, policy.negate(shiftCount)));
1716                         Word(32) output = policy.or_(output1, output2);
1717                         Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
1718                                                    policy.readFlag(x86_flag_cf),
1719                                                    extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(31)))));
1720                         policy.writeFlag(x86_flag_cf, newCf);
1721                         Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
1722                                                    policy.readFlag(x86_flag_of), 
1723                                                    policy.xor_(extract<31, 32>(output),
1724                                                                extract<31, 32>(op1)));
1725                         policy.writeFlag(x86_flag_of, newOf);
1726                         write32(operands[0], output);
1727                         setFlagsForResult<32>(output);
1728                         policy.writeFlag(x86_flag_af, policy.ite(policy.equalToZero(shiftCount),
1729                                                                  policy.readFlag(x86_flag_af),
1730                                                                  policy.undefined_()));
1731                         break;
1732                     }
1733                     default:
1734                         ROSE_ASSERT(!"Bad size");
1735                 }
1736                 break;
1737             }
1738
1739             case x86_bsf: {
1740                 policy.writeFlag(x86_flag_of, policy.undefined_());
1741                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1742                 policy.writeFlag(x86_flag_af, policy.undefined_());
1743                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1744                 policy.writeFlag(x86_flag_cf, policy.undefined_());
1745                 switch (numBytesInAsmType(operands[0]->get_type())) {
1746                     case 2: {
1747                         Word(16) op = read16(operands[1]);
1748                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1749                         Word(16) result = policy.ite(policy.readFlag(x86_flag_zf),
1750                                                      read16(operands[0]),
1751                                                      policy.leastSignificantSetBit(op));
1752                         write16(operands[0], result);
1753                         break;
1754                     }
1755                     case 4: {
1756                         Word(32) op = read32(operands[1]);
1757                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1758                         Word(32) result = policy.ite(policy.readFlag(x86_flag_zf),
1759                                                      read32(operands[0]),
1760                                                      policy.leastSignificantSetBit(op));
1761                         write32(operands[0], result);
1762                         break;
1763                     }
1764                     default:
1765                         ROSE_ASSERT(!"Bad size");
1766                 }
1767                 break;
1768             }
1769
1770             case x86_bsr: {
1771                 policy.writeFlag(x86_flag_of, policy.undefined_());
1772                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1773                 policy.writeFlag(x86_flag_af, policy.undefined_());
1774                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1775                 policy.writeFlag(x86_flag_cf, policy.undefined_());
1776                 switch (numBytesInAsmType(operands[0]->get_type())) {
1777                     case 2: {
1778                         Word(16) op = read16(operands[1]);
1779                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1780                         Word(16) result = policy.ite(policy.readFlag(x86_flag_zf),
1781                                                      read16(operands[0]),
1782                                                      policy.mostSignificantSetBit(op));
1783                         write16(operands[0], result);
1784                         break;
1785                     }
1786                     case 4: {
1787                         Word(32) op = read32(operands[1]);
1788                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1789                         Word(32) result = policy.ite(policy.readFlag(x86_flag_zf),
1790                                                      read32(operands[0]),
1791                                                      policy.mostSignificantSetBit(op));
1792                         write32(operands[0], result);
1793                         break;
1794                     }
1795                     default:
1796                         ROSE_ASSERT(!"Bad size");
1797                 }
1798                 break;
1799             }
1800
1801             case x86_bts: {
1802                 ROSE_ASSERT(operands.size() == 2);
1803                 // All flags except CF are undefined 
1804                 policy.writeFlag(x86_flag_of, policy.undefined_());
1805                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1806                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1807                 policy.writeFlag(x86_flag_af, policy.undefined_());
1808                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1809                 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
1810                     // Special case allowing multi-word offsets into memory 
1811                     Word(32) addr = readEffectiveAddress(operands[0]);
1812                     int numBytes = numBytesInAsmType(operands[1]->get_type());
1813                     Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
1814                     Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
1815                     Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1816                                                 adjustedAddr, policy.true_());
1817                     Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
1818                     Word(8) result = policy.or_(val, policy.rotateLeft(number<8>(1), extract<0, 3>(bitnum)));
1819                     policy.writeFlag(x86_flag_cf, bitval);
1820                     policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1821                                        adjustedAddr, result, policy.true_());
1822                 } else {
1823                     // Simple case 
1824                     switch (numBytesInAsmType(operands[0]->get_type())) {
1825                         case 2: {
1826                             Word(16) op0 = read16(operands[0]);
1827                             Word(4) bitnum = extract<0, 4>(read16(operands[1]));
1828                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1829                             Word(16) result = policy.or_(op0, policy.rotateLeft(number<16>(1), bitnum));
1830                             policy.writeFlag(x86_flag_cf, bitval);
1831                             write16(operands[0], result);
1832                             break;
1833                         }
1834                         case 4: {
1835                             Word(32) op0 = read32(operands[0]);
1836                             Word(5) bitnum = extract<0, 5>(read32(operands[1]));
1837                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1838                             Word(32) result = policy.or_(op0, policy.rotateLeft(number<32>(1), bitnum));
1839                             policy.writeFlag(x86_flag_cf, bitval);
1840                             write32(operands[0], result);
1841                             break;
1842                         }
1843                         default:
1844                             ROSE_ASSERT(!"Bad size");
1845                     }
1846                 }
1847                 break;
1848             }
1849 */
1850             case x86_imul: {
1851                 switch (numBytesInAsmType(operands[0]->get_type())) {
1852                     case 1: {
1853                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1854                         Word(8) op1 = read8(operands[0]);
1855                         Word(16) mulResult = policy.signedMultiply(op0, op1);
1856                         updateGPRLowWord(x86_gpr_ax, mulResult);
1857                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 16>(mulResult))),
1858                                                                  policy.equalToZero(extract<7, 16>(mulResult))));
1859                         policy.writeFlag(x86_flag_cf, carry);
1860                         policy.writeFlag(x86_flag_of, carry);
1861                         break;
1862                     }
1863                     case 2: {
1864                         Word(16) op0 = operands.size() == 1 ?
1865                                        extract<0, 16>(policy.readGPR(x86_gpr_ax)) :
1866                                        read16(operands[operands.size() - 2]);
1867                         Word(16) op1 = read16(operands[operands.size() - 1]);
1868                         Word(32) mulResult = policy.signedMultiply(op0, op1);
1869                         if (operands.size() == 1) {
1870                             updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1871                             updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1872                         } else {
1873                             write16(operands[0], extract<0, 16>(mulResult));
1874                         }
1875                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 32>(mulResult))),
1876                                                                  policy.equalToZero(extract<7, 32>(mulResult))));
1877                         policy.writeFlag(x86_flag_cf, carry);
1878                         policy.writeFlag(x86_flag_of, carry);
1879                         break;
1880                     }
1881                     case 4: {
1882                         Word(32) op0 = (operands.size() == 1) ? extract<0,32>(policy.readGPR(x86_gpr_ax)) : read32(operands[operands.size() - 2]);
1883                         Word(32) op1 = read32(operands[operands.size() - 1]);
1884                         Word(64) mulResult = policy.signedMultiply(op0, op1);
1885                         if (operands.size() == 1) {
1886                             updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1887                             updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1888                         } else {
1889                             write32(operands[0], extract<0, 32>(mulResult));
1890                         }
1891                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 64>(mulResult))),
1892                                                                  policy.equalToZero(extract<7, 64>(mulResult))));
1893                         policy.writeFlag(x86_flag_cf, carry);
1894                         policy.writeFlag(x86_flag_of, carry);
1895                         break;
1896                     }
1897                     case 8: {
1898                         Word(64) op0 = operands.size() == 1 ? policy.readGPR(x86_gpr_ax) : read64(operands[operands.size() - 2]);
1899                         Word(64) op1 = read64(operands[operands.size() - 1]);
1900                         Word(128) mulResult = policy.signedMultiply(op0, op1);
1901                         if (operands.size() == 1) {
1902                             policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1903                             policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1904                         } else {
1905                             write64(operands[0], extract<0, 64>(mulResult));
1906                         }
1907                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 128>(mulResult))),
1908                                                                  policy.equalToZero(extract<7, 128>(mulResult))));
1909                         policy.writeFlag(x86_flag_cf, carry);
1910                         policy.writeFlag(x86_flag_of, carry);
1911                         break;
1912                     }
1913
1914                     default:
1915                         ROSE_ASSERT(!"Bad size");
1916                 }
1917                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1918                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1919                 policy.writeFlag(x86_flag_af, policy.undefined_());
1920                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1921                 break;
1922             }
1923
1924             case x86_mul: {
1925                 switch (numBytesInAsmType(operands[0]->get_type())) {
1926                     case 1: {
1927                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1928                         Word(8) op1 = read8(operands[0]);
1929                         Word(16) mulResult = policy.unsignedMultiply(op0, op1);
1930                         updateGPRLowWord(x86_gpr_ax, mulResult);
1931                         Word(1) carry = policy.invert(policy.equalToZero(extract<8, 16>(mulResult)));
1932                         policy.writeFlag(x86_flag_cf, carry);
1933                         policy.writeFlag(x86_flag_of, carry);
1934                         break;
1935                     }
1936                     case 2: {
1937                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1938                         Word(16) op1 = read16(operands[0]);
1939                         Word(32) mulResult = policy.unsignedMultiply(op0, op1);
1940                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1941                         updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1942                         Word(1) carry = policy.invert(policy.equalToZero(extract<16, 32>(mulResult)));
1943                         policy.writeFlag(x86_flag_cf, carry);
1944                         policy.writeFlag(x86_flag_of, carry);
1945                         break;
1946                     }
1947                     case 4: {
1948                         Word(32) op0 = extract<0,32>(policy.readGPR(x86_gpr_ax));
1949                         Word(32) op1 = read32(operands[0]);
1950                         Word(64) mulResult = policy.unsignedMultiply(op0, op1);
1951                         updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1952                         updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1953                         Word(1) carry = policy.invert(policy.equalToZero(extract<32, 64>(mulResult)));
1954                         policy.writeFlag(x86_flag_cf, carry);
1955                         policy.writeFlag(x86_flag_of, carry);
1956                         break;
1957                     }
1958                     case 8: {
1959                         Word(64) op0 = policy.readGPR(x86_gpr_ax);
1960                         Word(64) op1 = read64(operands[0]);
1961                         Word(128) mulResult = policy.unsignedMultiply(op0, op1);
1962                         policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1963                         policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1964                         Word(1) carry = policy.invert(policy.equalToZero(extract<64, 128>(mulResult)));
1965                         policy.writeFlag(x86_flag_cf, carry);
1966                         policy.writeFlag(x86_flag_of, carry);
1967                         break;
1968                     }
1969
1970                     default:
1971                         ROSE_ASSERT(!"Bad size");
1972                 }
1973                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1974                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1975                 policy.writeFlag(x86_flag_af, policy.undefined_());
1976                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1977                 break;
1978             }
1979 /*
1980             case x86_idiv: {
1981                 switch (numBytesInAsmType(operands[0]->get_type())) {
1982                     case 1: {
1983                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1984                         Word(8) op1 = read8(operands[0]);
1985                         // if op1 == 0, we should trap 
1986                         Word(16) divResult = policy.signedDivide(op0, op1);
1987                         Word(8) modResult = policy.signedModulo(op0, op1);
1988                         // if result overflows, we should trap 
1989                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
1990                         break;
1991                     }
1992                     case 2: {
1993                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
1994                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
1995                         Word(16) op1 = read16(operands[0]);
1996                         // if op1 == 0, we should trap 
1997                         Word(32) divResult = policy.signedDivide(op0, op1);
1998                         Word(16) modResult = policy.signedModulo(op0, op1);
1999                         // if result overflows, we should trap 
2000                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2001                         updateGPRLowWord(x86_gpr_dx, modResult);
2002                         break;
2003                     }
2004                     case 4: {
2005                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2006                         Word(32) op1 = read32(operands[0]);
2007                         // if op1 == 0, we should trap
2008                         Word(64) divResult = policy.signedDivide(op0, op1);
2009                         Word(32) modResult = policy.signedModulo(op0, op1);
2010                         // if result overflows, we should trap
2011                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2012                         policy.writeGPR(x86_gpr_dx, modResult);
2013                         break;
2014                     }
2015                     default:
2016                         ROSE_ASSERT(!"Bad size");
2017                 }
2018                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2019                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2020                 policy.writeFlag(x86_flag_af, policy.undefined_());
2021                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2022                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2023                 policy.writeFlag(x86_flag_of, policy.undefined_());
2024                 break;
2025             }
2026
2027             case x86_div: {
2028                 switch (numBytesInAsmType(operands[0]->get_type())) {
2029                     case 1: {
2030                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
2031                         Word(8) op1 = read8(operands[0]);
2032                         // if op1 == 0, we should trap 
2033                         Word(16) divResult = policy.unsignedDivide(op0, op1);
2034                         Word(8) modResult = policy.unsignedModulo(op0, op1);
2035                         // if extract<8, 16> of divResult is non-zero (overflow), we should trap 
2036                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
2037                         break;
2038                     }
2039                     case 2: {
2040                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
2041                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
2042                         Word(16) op1 = read16(operands[0]);
2043                         // if op1 == 0, we should trap 
2044                         Word(32) divResult = policy.unsignedDivide(op0, op1);
2045                         Word(16) modResult = policy.unsignedModulo(op0, op1);
2046                         // if extract<16, 32> of divResult is non-zero (overflow), we should trap 
2047                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2048                         updateGPRLowWord(x86_gpr_dx, modResult);
2049                         break;
2050                     }
2051                     case 4: {
2052                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2053                         Word(32) op1 = read32(operands[0]);
2054                         // if op1 == 0, we should trap 
2055                         Word(64) divResult = policy.unsignedDivide(op0, op1);
2056                         Word(32) modResult = policy.unsignedModulo(op0, op1);
2057                         // if extract<32, 64> of divResult is non-zero (overflow), we should trap 
2058                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2059                         policy.writeGPR(x86_gpr_dx, modResult);
2060                         break;
2061                     }
2062                     default:
2063                         ROSE_ASSERT(!"Bad size");
2064                 }
2065                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2066                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2067                 policy.writeFlag(x86_flag_af, policy.undefined_());
2068                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2069                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2070                 policy.writeFlag(x86_flag_of, policy.undefined_());
2071                 break;
2072             }
2073
2074             case x86_aaa: {
2075                 ROSE_ASSERT(operands.size() == 0);
2076                 Word(1) incAh = policy.or_(policy.readFlag(x86_flag_af),
2077                                            greaterOrEqualToTen<4>(extract<0, 4>(policy.readGPR(x86_gpr_ax))));
2078                 updateGPRLowWord(x86_gpr_ax,
2079                                  policy.concat(policy.add(policy.ite(incAh, number<4>(6), number<4>(0)),
2080                                                           extract<0, 4>(policy.readGPR(x86_gpr_ax))),
2081                                                policy.concat(number<4>(0),
2082                                                              policy.add(policy.ite(incAh, number<8>(1), number<8>(0)),
2083                                                                         extract<8, 16>(policy.readGPR(x86_gpr_ax))))));
2084                 policy.writeFlag(x86_flag_of, policy.undefined_());
2085                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2086                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2087                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2088                 policy.writeFlag(x86_flag_af, incAh);
2089                 policy.writeFlag(x86_flag_cf, incAh);
2090                 break;
2091             }
2092
2093             case x86_aas: {
2094                 ROSE_ASSERT(operands.size() == 0);
2095                 Word(1) decAh = 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(decAh, 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(decAh, 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, decAh);
2108                 policy.writeFlag(x86_flag_cf, decAh);
2109                 break;
2110             }
2111
2112             case x86_aam: {
2113                 ROSE_ASSERT(operands.size() == 1);
2114                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2115                 Word(8) divisor = read8(operands[0]);
2116                 Word(8) newAh = policy.unsignedDivide(al, divisor);
2117                 Word(8) newAl = policy.unsignedModulo(al, divisor);
2118                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, newAh));
2119                 policy.writeFlag(x86_flag_of, policy.undefined_());
2120                 policy.writeFlag(x86_flag_af, policy.undefined_());
2121                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2122                 setFlagsForResult<8>(newAl);
2123                 break;
2124             }
2125
2126             case x86_aad: {
2127                 ROSE_ASSERT(operands.size() == 1);
2128                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2129                 Word(8) ah = extract<8, 16>(policy.readGPR(x86_gpr_ax));
2130                 Word(8) divisor = read8(operands[0]);
2131                 Word(8) newAl = policy.add(al, extract<0, 8>(policy.unsignedMultiply(ah, divisor)));
2132                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, number<8>(0)));
2133                 policy.writeFlag(x86_flag_of, policy.undefined_());
2134                 policy.writeFlag(x86_flag_af, policy.undefined_());
2135                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2136                 setFlagsForResult<8>(newAl);
2137                 break;
2138             }
2139
2140             case x86_bswap: {
2141                 ROSE_ASSERT(operands.size() == 1);
2142                 Word(32) oldVal = read32(operands[0]);
2143                 Word(32) newVal = policy.concat(extract<24, 32>(oldVal),
2144                                                 policy.concat(extract<16, 24>(oldVal),
2145                                                               policy.concat(extract<8, 16>(oldVal),
2146                                                                             extract<0, 8>(oldVal))));
2147                 write32(operands[0], newVal);
2148                 break;
2149             }
2150 */
2151             case x86_push: {
2152                 ROSE_ASSERT(operands.size() == 1);
2153                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2154                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2155
2156                 // Override hack for push <segreg>
2157                 // TODO: ask bill
2158                 if (operands[0]->variantT() == V_SgAsmx86RegisterReferenceExpression) {
2159                    SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(operands[0]);
2160                    if (rre->get_register_class() == x86_regclass_segment) {
2161                       Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2162                       Word(64) newSp = policy.add(oldSp, number<64>(-2));
2163                       policy.writeMemory(x86_segreg_ss, newSp, read16(operands[0]), policy.true_());
2164                       policy.writeGPR(x86_gpr_sp, newSp);
2165                       break;
2166                    }
2167                 }
2168                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2169                 Word(64) newSp = policy.add(oldSp, number<64>(-8));
2170                 policy.writeMemory(x86_segreg_ss, newSp, read64(operands[0]), policy.true_());
2171                 policy.writeGPR(x86_gpr_sp, newSp);                      
2172
2173                 break;
2174             }
2175 /*
2176             case x86_pushad: {
2177                 ROSE_ASSERT(operands.size() == 0);
2178                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2179                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2180                 Word(32) newSp = policy.add(oldSp, number<32>(-32));
2181                 policy.writeMemory(x86_segreg_ss, newSp, policy.readGPR(x86_gpr_di), policy.true_());
2182                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(4)), policy.readGPR(x86_gpr_si), policy.true_());
2183                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(8)), policy.readGPR(x86_gpr_bp), policy.true_());
2184                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(12)), oldSp, policy.true_());
2185                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(16)), policy.readGPR(x86_gpr_bx), policy.true_());
2186                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(20)), policy.readGPR(x86_gpr_dx), policy.true_());
2187                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(24)), policy.readGPR(x86_gpr_cx), policy.true_());
2188                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(28)), policy.readGPR(x86_gpr_ax), policy.true_());
2189                 policy.writeGPR(x86_gpr_sp, newSp);
2190                 break;
2191             }
2192
2193             case x86_pushfd: {
2194                 ROSE_ASSERT(operands.size() == 0);
2195                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2196                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2197                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2198                 policy.writeMemory(x86_segreg_ss, newSp, readEflags(), policy.true_());
2199                 policy.writeGPR(x86_gpr_sp, newSp);
2200                 break;
2201             }
2202 */
2203
2204             case x86_pop: {
2205                 ROSE_ASSERT(operands.size() == 1);
2206                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2207                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2208                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2209                 Word(64) newSp = policy.add(oldSp, number<64>(8));
2210                 write64(operands[0], readMemory<64>(x86_segreg_ss, oldSp, policy.true_()));
2211                 policy.writeGPR(x86_gpr_sp, newSp);
2212                 break;
2213             }
2214 /*
2215             case x86_popad: {
2216                 ROSE_ASSERT(operands.size() == 0);
2217                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2218                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2219                 Word(32) newSp = policy.add(oldSp, number<32>(32));
2220                 policy.writeGPR(x86_gpr_di, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2221                 policy.writeGPR(x86_gpr_si, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(4)), policy.true_()));
2222                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(8)), policy.true_()));
2223                 policy.writeGPR(x86_gpr_bx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(16)), policy.true_()));
2224                 policy.writeGPR(x86_gpr_dx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(20)), policy.true_()));
2225                 policy.writeGPR(x86_gpr_cx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(24)), policy.true_()));
2226                 policy.writeGPR(x86_gpr_ax, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(28)), policy.true_()));
2227                 readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(12)), policy.true_());
2228                 policy.writeGPR(x86_gpr_sp, newSp);
2229                 break;
2230             }
2231
2232             case x86_leave: {
2233                 ROSE_ASSERT(operands.size() == 0);
2234                 policy.writeGPR(x86_gpr_sp, policy.readGPR(x86_gpr_bp));
2235                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2236                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2237                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2238                 Word(32) newSp = policy.add(oldSp, number<32>(4));
2239                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2240                 policy.writeGPR(x86_gpr_sp, newSp);
2241                 break;
2242             }
2243
2244             case x86_call: {
2245                 ROSE_ASSERT(operands.size() == 1);
2246                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2247                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2248                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2249                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2250                 policy.writeMemory(x86_segreg_ss, newSp, policy.readIP(), policy.true_());
2251                 policy.writeIP(policy.filterCallTarget(read32(operands[0])));
2252                 policy.writeGPR(x86_gpr_sp, newSp);
2253                 break;
2254             }
2255
2256             case x86_ret: {
2257                 ROSE_ASSERT(operands.size() <= 1);
2258                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2259                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2260                                 Word(32) extraBytes = (operands.size() == 1 ? read32(operands[0]) : number<32>(0));
2261                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2262                 Word(32) newSp = policy.add(oldSp, policy.add(number<32>(4), extraBytes));
2263                 policy.writeIP(policy.filterReturnTarget(readMemory<32>(x86_segreg_ss, oldSp, policy.true_())));
2264                 policy.writeGPR(x86_gpr_sp, newSp);
2265                 break;
2266             }
2267
2268             case x86_loop: {
2269                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2270                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2271                 ROSE_ASSERT(operands.size() == 1);
2272                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2273                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2274                 policy.writeGPR(x86_gpr_cx, newCx);
2275                 Word(1) doLoop = policy.invert(policy.equalToZero(newCx));
2276                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2277                 break;
2278             }
2279             case x86_loopz: {
2280                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2281                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2282                 ROSE_ASSERT(operands.size() == 1);
2283                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2284                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2285                 policy.writeGPR(x86_gpr_cx, newCx);
2286                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)), policy.readFlag(x86_flag_zf));
2287                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2288                 break;
2289             }
2290             case x86_loopnz: {
2291                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2292                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2293                 ROSE_ASSERT(operands.size() == 1);
2294                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2295                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2296                 policy.writeGPR(x86_gpr_cx, newCx);
2297                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)),
2298                                              policy.invert(policy.readFlag(x86_flag_zf)));
2299                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2300                 break;
2301             }
2302 */
2303             case x86_jmp: {
2304                 ROSE_ASSERT(operands.size() == 1);
2305                 policy.writeIP(policy.filterIndirectJumpTarget(read64(operands[0])));
2306                 break;
2307             }
2308
2309
2310             /* Flag expressions that must be true for a conditional jump to occur. */
2311 #           define FLAGCOMBO_ne    policy.invert(policy.readFlag(x86_flag_zf))
2312 #           define FLAGCOMBO_e     policy.readFlag(x86_flag_zf)
2313 #           define FLAGCOMBO_no    policy.invert(policy.readFlag(x86_flag_of))
2314 #           define FLAGCOMBO_o     policy.readFlag(x86_flag_of)
2315 #           define FLAGCOMBO_ns    policy.invert(policy.readFlag(x86_flag_sf))
2316 #           define FLAGCOMBO_s     policy.readFlag(x86_flag_sf)
2317 #           define FLAGCOMBO_po    policy.invert(policy.readFlag(x86_flag_pf))
2318 #           define FLAGCOMBO_pe    policy.readFlag(x86_flag_pf)
2319 #           define FLAGCOMBO_ae    policy.invert(policy.readFlag(x86_flag_cf))
2320 #           define FLAGCOMBO_b     policy.readFlag(x86_flag_cf)
2321 #           define FLAGCOMBO_be    policy.or_(FLAGCOMBO_b, FLAGCOMBO_e)
2322 #           define FLAGCOMBO_a     policy.and_(FLAGCOMBO_ae, FLAGCOMBO_ne)
2323 #           define FLAGCOMBO_l     policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of))
2324 #           define FLAGCOMBO_ge    policy.invert(policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of)))
2325 #           define FLAGCOMBO_le    policy.or_(FLAGCOMBO_e, FLAGCOMBO_l)
2326 #           define FLAGCOMBO_g     policy.and_(FLAGCOMBO_ge, FLAGCOMBO_ne)
2327 #           define FLAGCOMBO_cxz   policy.equalToZero(extract<0, 16>(policy.readGPR(x86_gpr_cx)))
2328 #           define FLAGCOMBO_ecxz  policy.equalToZero(policy.readGPR(x86_gpr_cx))
2329
2330 #           define JUMP(tag) {                                                                                                 \
2331                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2332                 policy.writeIP(policy.ite(FLAGCOMBO_##tag,                                                                     \
2333                                           read64(operands[0]),                                                                 \
2334                                           policy.readIP()));                                                                   \
2335             }
2336             case x86_jne:   JUMP(ne);   break;
2337             case x86_je:    JUMP(e);    break;
2338             case x86_jno:   JUMP(no);   break;
2339             case x86_jo:    JUMP(o);    break;
2340             case x86_jpo:   JUMP(po);   break;
2341             case x86_jpe:   JUMP(pe);   break;
2342             case x86_jns:   JUMP(ns);   break;
2343             case x86_js:    JUMP(s);    break;
2344             case x86_jae:   JUMP(ae);   break;
2345             case x86_jb:    JUMP(b);    break;
2346             case x86_jbe:   JUMP(be);   break;
2347             case x86_ja:    JUMP(a);    break;
2348             case x86_jle:   JUMP(le);   break;
2349             case x86_jg:    JUMP(g);    break;
2350             case x86_jge:   JUMP(ge);   break;
2351             case x86_jl:    JUMP(l);    break;
2352             case x86_jcxz:  JUMP(cxz);  break;
2353             case x86_jecxz: JUMP(ecxz); break;
2354 #           undef JUMP
2355
2356 #           define SET(tag) {                                                                                                  \
2357                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2358                 write8(operands[0], policy.concat(FLAGCOMBO_##tag, number<7>(0)));                                             \
2359             }
2360             case x86_setne: SET(ne); break;
2361             case x86_sete:  SET(e);  break;
2362             case x86_setno: SET(no); break;
2363             case x86_seto:  SET(o);  break;
2364             case x86_setpo: SET(po); break;
2365             case x86_setpe: SET(pe); break;
2366             case x86_setns: SET(ns); break;
2367             case x86_sets:  SET(s);  break;
2368             case x86_setae: SET(ae); break;
2369             case x86_setb:  SET(b);  break;
2370             case x86_setbe: SET(be); break;
2371             case x86_seta:  SET(a);  break;
2372             case x86_setle: SET(le); break;
2373             case x86_setg:  SET(g);  break;
2374             case x86_setge: SET(ge); break;
2375             case x86_setl:  SET(l);  break;
2376 #           undef SET
2377                 
2378 #           define CMOV(tag) {                                                                                                 \
2379                 ROSE_ASSERT(operands.size() == 2);                                                                             \
2380                 switch (numBytesInAsmType(operands[0]->get_type())) {                                                          \
2381                     case 2: write16(operands[0], policy.ite(FLAGCOMBO_##tag, read16(operands[1]), read16(operands[0]))); break; \
2382                     case 4: write32(operands[0], policy.ite(FLAGCOMBO_##tag, read32(operands[1]), read32(operands[0]))); break; \
2383                     case 8: write64(operands[0], policy.ite(FLAGCOMBO_##tag, read64(operands[1]), read64(operands[0]))); break; \
2384                     default: ROSE_ASSERT(!"Bad size"); break;                                                                   \
2385                 }                                                                                                              \
2386             }
2387 /*            case x86_cmovne:    CMOV(ne);       break;
2388             case x86_cmove:     CMOV(e);        break;
2389             case x86_cmovno:    CMOV(no);       break;
2390             case x86_cmovo:     CMOV(o);        break;
2391             case x86_cmovpo:    CMOV(po);       break;
2392             case x86_cmovpe:    CMOV(pe);       break;
2393             case x86_cmovns:    CMOV(ns);       break;
2394             case x86_cmovs:     CMOV(s);        break;
2395             case x86_cmovae:    CMOV(ae);       break;
2396             case x86_cmovb:     CMOV(b);        break;
2397             case x86_cmovbe:    CMOV(be);       break;
2398             case x86_cmova:     CMOV(a);        break;
2399             case x86_cmovle:    CMOV(le);       break;
2400             case x86_cmovg:     CMOV(g);        break;
2401             case x86_cmovge:    CMOV(ge);       break;
2402             case x86_cmovl:     CMOV(l);        break;
2403 */          
2404 #           undef CMOV
2405
2406             /* The flag expressions are no longer needed */
2407 #           undef FLAGCOMBO_ne
2408 #           undef FLAGCOMBO_e
2409 #           undef FLAGCOMBO_ns
2410 #           undef FLAGCOMBO_s
2411 #           undef FLAGCOMBO_ae
2412 #           undef FLAGCOMBO_b
2413 #           undef FLAGCOMBO_be
2414 #           undef FLAGCOMBO_a
2415 #           undef FLAGCOMBO_l
2416 #           undef FLAGCOMBO_ge
2417 #           undef FLAGCOMBO_le
2418 #           undef FLAGCOMBO_g
2419 #           undef FLAGCOMBO_cxz
2420 #           undef FLAGCOMBO_ecxz
2421
2422             case x86_cld: {
2423                 ROSE_ASSERT(operands.size() == 0);
2424                 policy.writeFlag(x86_flag_df, policy.false_());
2425                 break;
2426             }
2427
2428             case x86_std: {
2429                 ROSE_ASSERT(operands.size() == 0);
2430                 policy.writeFlag(x86_flag_df, policy.true_());
2431                 break;
2432             }
2433
2434             case x86_clc: {
2435                 ROSE_ASSERT(operands.size() == 0);
2436                 policy.writeFlag(x86_flag_cf, policy.false_());
2437                 break;
2438             }
2439
2440             case x86_stc: {
2441                 ROSE_ASSERT(operands.size() == 0);
2442                 policy.writeFlag(x86_flag_cf, policy.true_());
2443                 break;
2444             }
2445
2446             case x86_cmc: {
2447                 ROSE_ASSERT(operands.size() == 0);
2448                 policy.writeFlag(x86_flag_cf, policy.invert(policy.readFlag(x86_flag_cf)));
2449                 break;
2450             }
2451
2452             case x86_nop:
2453                 break;
2454
2455 #           define STRINGOP_LOAD_SI(len, cond)                                                                                 \
2456                 readMemory<(8 * (len))>((insn->get_segmentOverride() == x86_segreg_none ?                                      \
2457                                          x86_segreg_ds :                                                                       \
2458                                          insn->get_segmentOverride()),                                                         \
2459                                         policy.readGPR(x86_gpr_si),                                                            \
2460                                         (cond))
2461             
2462 #           define STRINGOP_LOAD_DI(len, cond)                                                                                 \
2463                 readMemory<(8 * (len))>(x86_segreg_es, policy.readGPR(x86_gpr_di), (cond))
2464
2465             /* If true, repeat this instruction, otherwise go to the next one */
2466 #           define STRINGOP_LOOP_E                                                                                             \
2467                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.readFlag(x86_flag_zf)),                               \
2468                                           number<64>((uint64_t)(insn->get_address())),                                         \
2469                                           policy.readIP()))
2470
2471             /* If true, repeat this instruction, otherwise go to the next one */
2472 #           define STRINGOP_LOOP_NE                                                                                            \
2473                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.invert(policy.readFlag(x86_flag_zf))),                \
2474                                           number<64>((uint64_t)(insn->get_address())),                                         \
2475                                           policy.readIP()))
2476
2477 #           define REP_SCAS(suffix, len, repsuffix, loopmacro) {                                                               \
2478                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2479                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2480                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2481                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2482                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2483                                           true,                                                                                \
2484                                           policy.false_(),                                                                     \
2485                                           ecxNotZero);                                                                         \
2486                 policy.writeGPR(x86_gpr_di,                                                                                    \
2487                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2488                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2489                 loopmacro;                                                                                                     \
2490             }
2491             case x86_repne_scasb: REP_SCAS(b, 1, ne, STRINGOP_LOOP_NE); break;
2492             case x86_repne_scasw: REP_SCAS(w, 2, ne, STRINGOP_LOOP_NE); break;
2493             case x86_repne_scasd: REP_SCAS(d, 4, ne, STRINGOP_LOOP_NE); break;
2494             case x86_repe_scasb:  REP_SCAS(b, 1, e,  STRINGOP_LOOP_E);  break;
2495             case x86_repe_scasw:  REP_SCAS(w, 2, e,  STRINGOP_LOOP_E);  break;
2496             case x86_repe_scasd:  REP_SCAS(d, 4, e,  STRINGOP_LOOP_E);  break;
2497 #           undef REP_SCAS
2498
2499 #           define SCAS(suffix, len) {                                                                                         \
2500                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2501                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2502                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2503                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2504                                           true,                                                                                \
2505                                           policy.false_(),                                                                     \
2506                                           policy.true_());                                                                     \
2507                 policy.writeGPR(x86_gpr_di,                                                                                    \
2508                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2509                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2510             }
2511             case x86_scasb: SCAS(b, 1); break;
2512             case x86_scasw: SCAS(w, 2); break;
2513             case x86_scasd: SCAS(d, 4); break;
2514 #           undef SCAS
2515
2516 #           define REP_CMPS(suffix, len, repsuffix, loopmacro) {                                                               \
2517                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2518                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2519                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2520                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, ecxNotZero),                                                   \
2521                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2522                                           true,                                                                                \
2523                                           policy.false_(),                                                                     \
2524                                           ecxNotZero);                                                                         \
2525                 policy.writeGPR(x86_gpr_si,                                                                                    \
2526                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2527                                            policy.ite(ecxNotZero,                                                              \
2528                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2529                                                                  number<64>(-(len)),                                           \
2530                                                                  number<64>(len)),                                             \
2531                                                       number<64>(0))));                                                        \
2532                 policy.writeGPR(x86_gpr_di,                                                                                    \
2533                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2534                                            policy.ite(ecxNotZero,                                                              \
2535                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2536                                                                  number<64>(-(len)),                                           \
2537                                                                  number<64>(len)),                                             \
2538                                                       number<64>(0))));                                                        \
2539                 loopmacro;                                                                                                     \
2540             }
2541             case x86_repne_cmpsb: REP_CMPS(b, 1, ne, STRINGOP_LOOP_NE); break;
2542             case x86_repne_cmpsw: REP_CMPS(w, 2, ne, STRINGOP_LOOP_NE); break;
2543             case x86_repne_cmpsd: REP_CMPS(d, 4, ne, STRINGOP_LOOP_NE); break;
2544             case x86_repe_cmpsb:  REP_CMPS(b, 1, e,  STRINGOP_LOOP_E);  break;
2545             case x86_repe_cmpsw:  REP_CMPS(w, 2, e,  STRINGOP_LOOP_E);  break;
2546             case x86_repe_cmpsd:  REP_CMPS(d, 4, e,  STRINGOP_LOOP_E);  break;
2547 #           undef REP_CMPS
2548
2549 #           define CMPS(suffix, len) {                                                                                         \
2550                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2551                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2552                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, policy.true_()),                                               \
2553                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2554                                           true,                                                                                \
2555                                           policy.false_(),                                                                     \
2556                                           policy.true_());                                                                     \
2557                 policy.writeGPR(x86_gpr_si,                                                                                    \
2558                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2559                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2560                 policy.writeGPR(x86_gpr_di,                                                                                    \
2561                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2562                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2563             }
2564             case x86_cmpsb: CMPS(b, 1); break;
2565             case x86_cmpsw: CMPS(w, 2); break;
2566             case x86_cmpsd: CMPS(d, 4); break;
2567 #           undef CMPS
2568
2569 #           define MOVS(suffix, len) {                                                                                         \
2570                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2571                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2572                 policy.writeMemory(x86_segreg_es,                                                                              \
2573                                    policy.readGPR(x86_gpr_di),                                                                 \
2574                                    STRINGOP_LOAD_SI(len, policy.true_()),                                                      \
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_movsb: MOVS(b, 1); break;
2584             case x86_movsw: MOVS(w, 2); break;
2585             case x86_movsd: MOVS(d, 4); break;
2586 #           undef MOVS
2587
2588 #           define REP_MOVS(suffix, len) {                                                                                     \
2589                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2590                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2591                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2592                 policy.writeMemory(x86_segreg_es, policy.readGPR(x86_gpr_di), STRINGOP_LOAD_SI(len, ecxNotZero), ecxNotZero);  \
2593                 policy.writeGPR(x86_gpr_si,                                                                                    \
2594                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2595                                            policy.ite(ecxNotZero,                                                              \
2596                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2597                                                                  number<64>(-(len)),                                           \
2598                                                                  number<64>(len)),                                             \
2599                                                       number<64>(0))));                                                        \
2600                 policy.writeGPR(x86_gpr_di,                                                                                    \
2601                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2602                                            policy.ite(ecxNotZero,                                                              \
2603                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2604                                                                  number<64>(-(len)),                                           \
2605                                                                  number<64>(len)),                                             \
2606                                                       number<64>(0))));                                                        \
2607                 policy.writeIP(policy.ite(ecxNotZero, /* If true, repeat this instruction, otherwise go to the next one */     \
2608                                           number<64>((uint32_t)(insn->get_address())),                                         \
2609                                           policy.readIP()));                                                                   \
2610             }
2611             case x86_rep_movsb: REP_MOVS(b, 1); break;
2612             case x86_rep_movsw: REP_MOVS(w, 2); break;
2613             case x86_rep_movsd: REP_MOVS(d, 4); break;
2614 #           undef REP_MOVS
2615
2616             case x86_stosb: {
2617                 stos_semantics<1>(insn);
2618                 break;
2619             }
2620
2621             case x86_rep_stosb: {
2622                 rep_stos_semantics<1>(insn);
2623                 break;
2624             }
2625
2626             case x86_stosw: {
2627                 stos_semantics<2>(insn);
2628                 break;
2629             }
2630
2631             case x86_rep_stosw: {
2632                 rep_stos_semantics<2>(insn);
2633                 break;
2634             }
2635
2636             case x86_stosd: {
2637                 stos_semantics<4>(insn);
2638                 break;
2639             }
2640
2641             case x86_rep_stosd: {
2642                 rep_stos_semantics<4>(insn);
2643                 break;
2644             }
2645
2646 #           define LODS(suffix, len, regupdate) {                                                                              \
2647                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2648                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2649                 regupdate(x86_gpr_ax, STRINGOP_LOAD_SI(len, policy.true_()));                                                  \
2650                 policy.writeGPR(x86_gpr_si,                                                                                    \
2651                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2652                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2653             }
2654             case x86_lodsb: LODS(b, 1, updateGPRLowByte); break;
2655             case x86_lodsw: LODS(w, 2, updateGPRLowWord); break;
2656             case x86_lodsd: LODS(d, 4, updateGPRLowDWord);  break;
2657 #           undef LODS
2658
2659 #undef STRINGOP_LOAD_SI
2660 #undef STRINGOP_LOAD_DI
2661 #undef STRINGOP_UPDATE_CX
2662 #undef STRINGOP_LOOP_E
2663 #undef STRINGOP_LOOP_NE
2664
2665             case x86_hlt: {
2666                 ROSE_ASSERT(operands.size() == 0);
2667                 policy.hlt();
2668                 policy.writeIP(number<64>((uint64_t)(insn->get_address())));
2669                 break;
2670             }
2671 /*
2672             case x86_rdtsc: {
2673                 ROSE_ASSERT(operands.size() == 0);
2674                 Word(64) tsc = policy.rdtsc();
2675                 policy.writeGPR(x86_gpr_ax, extract<0, 32>(tsc));
2676                 policy.writeGPR(x86_gpr_dx, extract<32, 64>(tsc));
2677                 break;
2678             }
2679
2680             case x86_int: {
2681                 ROSE_ASSERT(operands.size() == 1);
2682                 SgAsmByteValueExpression* bv = isSgAsmByteValueExpression(operands[0]);
2683                 ROSE_ASSERT(bv);
2684                 policy.interrupt(bv->get_value());
2685                 break;
2686             }
2687 */
2688                 /* This is a dummy version that should be replaced later FIXME */
2689 /*            case x86_fnstcw: {
2690                 ROSE_ASSERT(operands.size() == 1);
2691                 write16(operands[0], number<16>(0x37f));
2692                 break;
2693             }
2694
2695             case x86_fldcw: {
2696                 ROSE_ASSERT(operands.size() == 1);
2697                 read16(operands[0]); // To catch access control violations 
2698                 break;
2699             }
2700 */
2701             default: {
2702
2703 //                std::cerr <<"Bad instruction [0x" <<std::hex <<insn->get_address() <<": "// <<unparseInstruction(insn) <<"]"
2704 //                          <<" (skipping semantic analysis)\n";
2705                 break;
2706             }
2707         }
2708     }
2709
2710     void processInstruction(SgAsmx86Instruction* insn) {
2711         ROSE_ASSERT(insn);
2712         policy.startInstruction(insn);
2713         translate(insn);
2714         policy.finishInstruction(insn);
2715     }
2716
2717     /*
2718     void processBlock(const SgAsmStatementPtrList& stmts, size_t begin, size_t end) {
2719         if (begin == end) return;
2720         policy.startBlock(stmts[begin]->get_address());
2721         for (size_t i = begin; i < end; ++i) {
2722             processInstruction(isSgAsmx86Instruction(stmts[i]));
2723         }
2724         policy.finishBlock(stmts[begin]->get_address());
2725     }
2726     */
2727
2728     static bool isRepeatedStringOp(SgAsmx86Instruction* insn) {
2729         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2730         if (!insn) return false;
2731         switch (insn->get_kind()) {
2732             case x86_repe_cmpsb: return true;
2733             case x86_repe_cmpsd: return true;
2734             case x86_repe_cmpsq: return true;
2735             case x86_repe_cmpsw: return true;
2736             case x86_repe_scasb: return true;
2737             case x86_repe_scasd: return true;
2738             case x86_repe_scasq: return true;
2739             case x86_repe_scasw: return true;
2740             case x86_rep_insb: return true;
2741             case x86_rep_insd: return true;
2742             case x86_rep_insw: return true;
2743             case x86_rep_lodsb: return true;
2744             case x86_rep_lodsd: return true;
2745             case x86_rep_lodsq: return true;
2746             case x86_rep_lodsw: return true;
2747             case x86_rep_movsb: return true;
2748             case x86_rep_movsd: return true;
2749             case x86_rep_movsq: return true;
2750             case x86_rep_movsw: return true;
2751             case x86_repne_cmpsb: return true;
2752             case x86_repne_cmpsd: return true;
2753             case x86_repne_cmpsq: return true;
2754             case x86_repne_cmpsw: return true;
2755             case x86_repne_scasb: return true;
2756             case x86_repne_scasd: return true;
2757             case x86_repne_scasq: return true;
2758             case x86_repne_scasw: return true;
2759             case x86_rep_outsb: return true;
2760             case x86_rep_outsd: return true;
2761             case x86_rep_outsw: return true;
2762             case x86_rep_stosb: return true;
2763             case x86_rep_stosd: return true;
2764             case x86_rep_stosq: return true;
2765             case x86_rep_stosw: return true;
2766             default: return false;
2767         }
2768     }
2769
2770     static bool isHltOrInt(SgAsmx86Instruction* insn) {
2771         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2772         if (!insn) return false;
2773         switch (insn->get_kind()) {
2774             case x86_hlt: return true;
2775             case x86_int: return true;
2776             default: return false;
2777         }
2778     }
2779
2780 #if 0
2781     void processBlock(SgAsmBlock* b) {
2782         const SgAsmStatementPtrList& stmts = b->get_statementList();
2783         if (stmts.empty()) return;
2784         if (!isSgAsmInstruction(stmts[0])) return; /* A block containing functions or something */
2785         size_t i = 0;
2786         while (i < stmts.size()) {
2787             size_t oldI = i;
2788             /* Advance until either i points to a repeated string op or it is just after a hlt or int */
2789             while (i < stmts.size() && !isRepeatedStringOp(stmts[i]) && (i == oldI || !isHltOrInt(stmts[i - 1]))) ++i;
2790             processBlock(stmts, oldI, i);
2791             if (i >= stmts.size()) break;
2792             if (isRepeatedStringOp(stmts[i])) {
2793                 processBlock(stmts, i, i + 1);
2794                 ++i;
2795             }
2796             ROSE_ASSERT(i != oldI);
2797         }
2798     }
2799 #endif
2800
2801 };
2802
2803 #undef Word
2804
2805 #endif // ROSE_X86_64INSTRUCTIONSEMANTICS_H