BSF and BSR instructions can produce bounds for jump tables
[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                     case 8: {
1765                         Word(64) op = read64(operands[1]);
1766                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1767                         Word(64) result = policy.ite(policy.readFlag(x86_flag_zf),
1768                                                      read64(operands[0]),
1769                                                      policy.leastSignificantSetBit(op));
1770                         write64(operands[0], result);
1771                         break;
1772                     }
1773                     default:
1774                         ROSE_ASSERT(!"Bad size");
1775                 }
1776                 break;
1777             }
1778
1779             case x86_bsr: {
1780                 policy.writeFlag(x86_flag_of, policy.undefined_());
1781                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1782                 policy.writeFlag(x86_flag_af, policy.undefined_());
1783                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1784                 policy.writeFlag(x86_flag_cf, policy.undefined_());
1785                 switch (numBytesInAsmType(operands[0]->get_type())) {
1786                     case 2: {
1787                         Word(16) op = read16(operands[1]);
1788                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1789                         Word(16) result = policy.ite(policy.readFlag(x86_flag_zf),
1790                                                      read16(operands[0]),
1791                                                      policy.mostSignificantSetBit(op));
1792                         write16(operands[0], result);
1793                         break;
1794                     }
1795                     case 4: {
1796                         Word(32) op = read32(operands[1]);
1797                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1798                         Word(32) result = policy.ite(policy.readFlag(x86_flag_zf),
1799                                                      read32(operands[0]),
1800                                                      policy.mostSignificantSetBit(op));
1801                         write32(operands[0], result);
1802                         break;
1803                     }
1804                     case 8: {
1805                         Word(64) op = read64(operands[1]);
1806                         policy.writeFlag(x86_flag_zf, policy.equalToZero(op));
1807                         Word(64) result = policy.ite(policy.readFlag(x86_flag_zf),
1808                                                      read64(operands[0]),
1809                                                      policy.mostSignificantSetBit(op));
1810                         write64(operands[0], result);
1811                         break;
1812                     }
1813                     default:
1814                         ROSE_ASSERT(!"Bad size");
1815                 }
1816                 break;
1817             }
1818             /*
1819             case x86_bts: {
1820                 ROSE_ASSERT(operands.size() == 2);
1821                 // All flags except CF are undefined 
1822                 policy.writeFlag(x86_flag_of, policy.undefined_());
1823                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1824                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1825                 policy.writeFlag(x86_flag_af, policy.undefined_());
1826                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1827                 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
1828                     // Special case allowing multi-word offsets into memory 
1829                     Word(32) addr = readEffectiveAddress(operands[0]);
1830                     int numBytes = numBytesInAsmType(operands[1]->get_type());
1831                     Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
1832                     Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
1833                     Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1834                                                 adjustedAddr, policy.true_());
1835                     Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
1836                     Word(8) result = policy.or_(val, policy.rotateLeft(number<8>(1), extract<0, 3>(bitnum)));
1837                     policy.writeFlag(x86_flag_cf, bitval);
1838                     policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
1839                                        adjustedAddr, result, policy.true_());
1840                 } else {
1841                     // Simple case 
1842                     switch (numBytesInAsmType(operands[0]->get_type())) {
1843                         case 2: {
1844                             Word(16) op0 = read16(operands[0]);
1845                             Word(4) bitnum = extract<0, 4>(read16(operands[1]));
1846                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1847                             Word(16) result = policy.or_(op0, policy.rotateLeft(number<16>(1), bitnum));
1848                             policy.writeFlag(x86_flag_cf, bitval);
1849                             write16(operands[0], result);
1850                             break;
1851                         }
1852                         case 4: {
1853                             Word(32) op0 = read32(operands[0]);
1854                             Word(5) bitnum = extract<0, 5>(read32(operands[1]));
1855                             Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
1856                             Word(32) result = policy.or_(op0, policy.rotateLeft(number<32>(1), bitnum));
1857                             policy.writeFlag(x86_flag_cf, bitval);
1858                             write32(operands[0], result);
1859                             break;
1860                         }
1861                         default:
1862                             ROSE_ASSERT(!"Bad size");
1863                     }
1864                 }
1865                 break;
1866             }
1867 */
1868             case x86_imul: {
1869                 switch (numBytesInAsmType(operands[0]->get_type())) {
1870                     case 1: {
1871                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1872                         Word(8) op1 = read8(operands[0]);
1873                         Word(16) mulResult = policy.signedMultiply(op0, op1);
1874                         updateGPRLowWord(x86_gpr_ax, mulResult);
1875                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 16>(mulResult))),
1876                                                                  policy.equalToZero(extract<7, 16>(mulResult))));
1877                         policy.writeFlag(x86_flag_cf, carry);
1878                         policy.writeFlag(x86_flag_of, carry);
1879                         break;
1880                     }
1881                     case 2: {
1882                         Word(16) op0 = operands.size() == 1 ?
1883                                        extract<0, 16>(policy.readGPR(x86_gpr_ax)) :
1884                                        read16(operands[operands.size() - 2]);
1885                         Word(16) op1 = read16(operands[operands.size() - 1]);
1886                         Word(32) mulResult = policy.signedMultiply(op0, op1);
1887                         if (operands.size() == 1) {
1888                             updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1889                             updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1890                         } else {
1891                             write16(operands[0], extract<0, 16>(mulResult));
1892                         }
1893                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 32>(mulResult))),
1894                                                                  policy.equalToZero(extract<7, 32>(mulResult))));
1895                         policy.writeFlag(x86_flag_cf, carry);
1896                         policy.writeFlag(x86_flag_of, carry);
1897                         break;
1898                     }
1899                     case 4: {
1900                         Word(32) op0 = (operands.size() == 1) ? extract<0,32>(policy.readGPR(x86_gpr_ax)) : read32(operands[operands.size() - 2]);
1901                         Word(32) op1 = read32(operands[operands.size() - 1]);
1902                         Word(64) mulResult = policy.signedMultiply(op0, op1);
1903                         if (operands.size() == 1) {
1904                             updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1905                             updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1906                         } else {
1907                             write32(operands[0], extract<0, 32>(mulResult));
1908                         }
1909                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 64>(mulResult))),
1910                                                                  policy.equalToZero(extract<7, 64>(mulResult))));
1911                         policy.writeFlag(x86_flag_cf, carry);
1912                         policy.writeFlag(x86_flag_of, carry);
1913                         break;
1914                     }
1915                     case 8: {
1916                         Word(64) op0 = operands.size() == 1 ? policy.readGPR(x86_gpr_ax) : read64(operands[operands.size() - 2]);
1917                         Word(64) op1 = read64(operands[operands.size() - 1]);
1918                         Word(128) mulResult = policy.signedMultiply(op0, op1);
1919                         if (operands.size() == 1) {
1920                             policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1921                             policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1922                         } else {
1923                             write64(operands[0], extract<0, 64>(mulResult));
1924                         }
1925                         Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 128>(mulResult))),
1926                                                                  policy.equalToZero(extract<7, 128>(mulResult))));
1927                         policy.writeFlag(x86_flag_cf, carry);
1928                         policy.writeFlag(x86_flag_of, carry);
1929                         break;
1930                     }
1931
1932                     default:
1933                         ROSE_ASSERT(!"Bad size");
1934                 }
1935                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1936                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1937                 policy.writeFlag(x86_flag_af, policy.undefined_());
1938                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1939                 break;
1940             }
1941
1942             case x86_mul: {
1943                 switch (numBytesInAsmType(operands[0]->get_type())) {
1944                     case 1: {
1945                         Word(8) op0 = extract<0, 8>(policy.readGPR(x86_gpr_ax));
1946                         Word(8) op1 = read8(operands[0]);
1947                         Word(16) mulResult = policy.unsignedMultiply(op0, op1);
1948                         updateGPRLowWord(x86_gpr_ax, mulResult);
1949                         Word(1) carry = policy.invert(policy.equalToZero(extract<8, 16>(mulResult)));
1950                         policy.writeFlag(x86_flag_cf, carry);
1951                         policy.writeFlag(x86_flag_of, carry);
1952                         break;
1953                     }
1954                     case 2: {
1955                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
1956                         Word(16) op1 = read16(operands[0]);
1957                         Word(32) mulResult = policy.unsignedMultiply(op0, op1);
1958                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(mulResult));
1959                         updateGPRLowWord(x86_gpr_dx, extract<16, 32>(mulResult));
1960                         Word(1) carry = policy.invert(policy.equalToZero(extract<16, 32>(mulResult)));
1961                         policy.writeFlag(x86_flag_cf, carry);
1962                         policy.writeFlag(x86_flag_of, carry);
1963                         break;
1964                     }
1965                     case 4: {
1966                         Word(32) op0 = extract<0,32>(policy.readGPR(x86_gpr_ax));
1967                         Word(32) op1 = read32(operands[0]);
1968                         Word(64) mulResult = policy.unsignedMultiply(op0, op1);
1969                         updateGPRLowDWord(x86_gpr_ax, extract<0, 32>(mulResult));
1970                         updateGPRLowDWord(x86_gpr_dx, extract<32, 64>(mulResult));
1971                         Word(1) carry = policy.invert(policy.equalToZero(extract<32, 64>(mulResult)));
1972                         policy.writeFlag(x86_flag_cf, carry);
1973                         policy.writeFlag(x86_flag_of, carry);
1974                         break;
1975                     }
1976                     case 8: {
1977                         Word(64) op0 = policy.readGPR(x86_gpr_ax);
1978                         Word(64) op1 = read64(operands[0]);
1979                         Word(128) mulResult = policy.unsignedMultiply(op0, op1);
1980                         policy.writeGPR(x86_gpr_ax, extract<0, 64>(mulResult));
1981                         policy.writeGPR(x86_gpr_dx, extract<64, 128>(mulResult));
1982                         Word(1) carry = policy.invert(policy.equalToZero(extract<64, 128>(mulResult)));
1983                         policy.writeFlag(x86_flag_cf, carry);
1984                         policy.writeFlag(x86_flag_of, carry);
1985                         break;
1986                     }
1987
1988                     default:
1989                         ROSE_ASSERT(!"Bad size");
1990                 }
1991                 policy.writeFlag(x86_flag_sf, policy.undefined_());
1992                 policy.writeFlag(x86_flag_zf, policy.undefined_());
1993                 policy.writeFlag(x86_flag_af, policy.undefined_());
1994                 policy.writeFlag(x86_flag_pf, policy.undefined_());
1995                 break;
1996             }
1997 /*
1998             case x86_idiv: {
1999                 switch (numBytesInAsmType(operands[0]->get_type())) {
2000                     case 1: {
2001                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
2002                         Word(8) op1 = read8(operands[0]);
2003                         // if op1 == 0, we should trap 
2004                         Word(16) divResult = policy.signedDivide(op0, op1);
2005                         Word(8) modResult = policy.signedModulo(op0, op1);
2006                         // if result overflows, we should trap 
2007                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
2008                         break;
2009                     }
2010                     case 2: {
2011                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
2012                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
2013                         Word(16) op1 = read16(operands[0]);
2014                         // if op1 == 0, we should trap 
2015                         Word(32) divResult = policy.signedDivide(op0, op1);
2016                         Word(16) modResult = policy.signedModulo(op0, op1);
2017                         // if result overflows, we should trap 
2018                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2019                         updateGPRLowWord(x86_gpr_dx, modResult);
2020                         break;
2021                     }
2022                     case 4: {
2023                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2024                         Word(32) op1 = read32(operands[0]);
2025                         // if op1 == 0, we should trap
2026                         Word(64) divResult = policy.signedDivide(op0, op1);
2027                         Word(32) modResult = policy.signedModulo(op0, op1);
2028                         // if result overflows, we should trap
2029                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2030                         policy.writeGPR(x86_gpr_dx, modResult);
2031                         break;
2032                     }
2033                     default:
2034                         ROSE_ASSERT(!"Bad size");
2035                 }
2036                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2037                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2038                 policy.writeFlag(x86_flag_af, policy.undefined_());
2039                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2040                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2041                 policy.writeFlag(x86_flag_of, policy.undefined_());
2042                 break;
2043             }
2044
2045             case x86_div: {
2046                 switch (numBytesInAsmType(operands[0]->get_type())) {
2047                     case 1: {
2048                         Word(16) op0 = extract<0, 16>(policy.readGPR(x86_gpr_ax));
2049                         Word(8) op1 = read8(operands[0]);
2050                         // if op1 == 0, we should trap 
2051                         Word(16) divResult = policy.unsignedDivide(op0, op1);
2052                         Word(8) modResult = policy.unsignedModulo(op0, op1);
2053                         // if extract<8, 16> of divResult is non-zero (overflow), we should trap 
2054                         updateGPRLowWord(x86_gpr_ax, policy.concat(extract<0, 8>(divResult), modResult));
2055                         break;
2056                     }
2057                     case 2: {
2058                         Word(32) op0 = policy.concat(extract<0, 16>(policy.readGPR(x86_gpr_ax)),
2059                                                      extract<0, 16>(policy.readGPR(x86_gpr_dx)));
2060                         Word(16) op1 = read16(operands[0]);
2061                         // if op1 == 0, we should trap 
2062                         Word(32) divResult = policy.unsignedDivide(op0, op1);
2063                         Word(16) modResult = policy.unsignedModulo(op0, op1);
2064                         // if extract<16, 32> of divResult is non-zero (overflow), we should trap 
2065                         updateGPRLowWord(x86_gpr_ax, extract<0, 16>(divResult));
2066                         updateGPRLowWord(x86_gpr_dx, modResult);
2067                         break;
2068                     }
2069                     case 4: {
2070                         Word(64) op0 = policy.concat(policy.readGPR(x86_gpr_ax), policy.readGPR(x86_gpr_dx));
2071                         Word(32) op1 = read32(operands[0]);
2072                         // if op1 == 0, we should trap 
2073                         Word(64) divResult = policy.unsignedDivide(op0, op1);
2074                         Word(32) modResult = policy.unsignedModulo(op0, op1);
2075                         // if extract<32, 64> of divResult is non-zero (overflow), we should trap 
2076                         policy.writeGPR(x86_gpr_ax, extract<0, 32>(divResult));
2077                         policy.writeGPR(x86_gpr_dx, modResult);
2078                         break;
2079                     }
2080                     default:
2081                         ROSE_ASSERT(!"Bad size");
2082                 }
2083                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2084                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2085                 policy.writeFlag(x86_flag_af, policy.undefined_());
2086                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2087                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2088                 policy.writeFlag(x86_flag_of, policy.undefined_());
2089                 break;
2090             }
2091
2092             case x86_aaa: {
2093                 ROSE_ASSERT(operands.size() == 0);
2094                 Word(1) incAh = policy.or_(policy.readFlag(x86_flag_af),
2095                                            greaterOrEqualToTen<4>(extract<0, 4>(policy.readGPR(x86_gpr_ax))));
2096                 updateGPRLowWord(x86_gpr_ax,
2097                                  policy.concat(policy.add(policy.ite(incAh, number<4>(6), number<4>(0)),
2098                                                           extract<0, 4>(policy.readGPR(x86_gpr_ax))),
2099                                                policy.concat(number<4>(0),
2100                                                              policy.add(policy.ite(incAh, number<8>(1), number<8>(0)),
2101                                                                         extract<8, 16>(policy.readGPR(x86_gpr_ax))))));
2102                 policy.writeFlag(x86_flag_of, policy.undefined_());
2103                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2104                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2105                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2106                 policy.writeFlag(x86_flag_af, incAh);
2107                 policy.writeFlag(x86_flag_cf, incAh);
2108                 break;
2109             }
2110
2111             case x86_aas: {
2112                 ROSE_ASSERT(operands.size() == 0);
2113                 Word(1) decAh = policy.or_(policy.readFlag(x86_flag_af),
2114                                            greaterOrEqualToTen<4>(extract<0, 4>(policy.readGPR(x86_gpr_ax))));
2115                 updateGPRLowWord(x86_gpr_ax,
2116                                  policy.concat(policy.add(policy.ite(decAh, number<4>(-6), number<4>(0)),
2117                                                           extract<0, 4>(policy.readGPR(x86_gpr_ax))),
2118                                                policy.concat(number<4>(0),
2119                                                              policy.add(policy.ite(decAh, number<8>(-1), number<8>(0)),
2120                                                                         extract<8, 16>(policy.readGPR(x86_gpr_ax))))));
2121                 policy.writeFlag(x86_flag_of, policy.undefined_());
2122                 policy.writeFlag(x86_flag_sf, policy.undefined_());
2123                 policy.writeFlag(x86_flag_zf, policy.undefined_());
2124                 policy.writeFlag(x86_flag_pf, policy.undefined_());
2125                 policy.writeFlag(x86_flag_af, decAh);
2126                 policy.writeFlag(x86_flag_cf, decAh);
2127                 break;
2128             }
2129
2130             case x86_aam: {
2131                 ROSE_ASSERT(operands.size() == 1);
2132                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2133                 Word(8) divisor = read8(operands[0]);
2134                 Word(8) newAh = policy.unsignedDivide(al, divisor);
2135                 Word(8) newAl = policy.unsignedModulo(al, divisor);
2136                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, newAh));
2137                 policy.writeFlag(x86_flag_of, policy.undefined_());
2138                 policy.writeFlag(x86_flag_af, policy.undefined_());
2139                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2140                 setFlagsForResult<8>(newAl);
2141                 break;
2142             }
2143
2144             case x86_aad: {
2145                 ROSE_ASSERT(operands.size() == 1);
2146                 Word(8) al = extract<0, 8>(policy.readGPR(x86_gpr_ax));
2147                 Word(8) ah = extract<8, 16>(policy.readGPR(x86_gpr_ax));
2148                 Word(8) divisor = read8(operands[0]);
2149                 Word(8) newAl = policy.add(al, extract<0, 8>(policy.unsignedMultiply(ah, divisor)));
2150                 updateGPRLowWord(x86_gpr_ax, policy.concat(newAl, number<8>(0)));
2151                 policy.writeFlag(x86_flag_of, policy.undefined_());
2152                 policy.writeFlag(x86_flag_af, policy.undefined_());
2153                 policy.writeFlag(x86_flag_cf, policy.undefined_());
2154                 setFlagsForResult<8>(newAl);
2155                 break;
2156             }
2157
2158             case x86_bswap: {
2159                 ROSE_ASSERT(operands.size() == 1);
2160                 Word(32) oldVal = read32(operands[0]);
2161                 Word(32) newVal = policy.concat(extract<24, 32>(oldVal),
2162                                                 policy.concat(extract<16, 24>(oldVal),
2163                                                               policy.concat(extract<8, 16>(oldVal),
2164                                                                             extract<0, 8>(oldVal))));
2165                 write32(operands[0], newVal);
2166                 break;
2167             }
2168 */
2169             case x86_push: {
2170                 ROSE_ASSERT(operands.size() == 1);
2171                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2172                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2173
2174                 // Override hack for push <segreg>
2175                 // TODO: ask bill
2176                 if (operands[0]->variantT() == V_SgAsmx86RegisterReferenceExpression) {
2177                    SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(operands[0]);
2178                    if (rre->get_register_class() == x86_regclass_segment) {
2179                       Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2180                       Word(64) newSp = policy.add(oldSp, number<64>(-2));
2181                       policy.writeMemory(x86_segreg_ss, newSp, read16(operands[0]), policy.true_());
2182                       policy.writeGPR(x86_gpr_sp, newSp);
2183                       break;
2184                    }
2185                 }
2186                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2187                 Word(64) newSp = policy.add(oldSp, number<64>(-8));
2188                 policy.writeMemory(x86_segreg_ss, newSp, read64(operands[0]), policy.true_());
2189                 policy.writeGPR(x86_gpr_sp, newSp);                      
2190
2191                 break;
2192             }
2193 /*
2194             case x86_pushad: {
2195                 ROSE_ASSERT(operands.size() == 0);
2196                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2197                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2198                 Word(32) newSp = policy.add(oldSp, number<32>(-32));
2199                 policy.writeMemory(x86_segreg_ss, newSp, policy.readGPR(x86_gpr_di), policy.true_());
2200                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(4)), policy.readGPR(x86_gpr_si), policy.true_());
2201                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(8)), policy.readGPR(x86_gpr_bp), policy.true_());
2202                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(12)), oldSp, policy.true_());
2203                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(16)), policy.readGPR(x86_gpr_bx), policy.true_());
2204                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(20)), policy.readGPR(x86_gpr_dx), policy.true_());
2205                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(24)), policy.readGPR(x86_gpr_cx), policy.true_());
2206                 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(28)), policy.readGPR(x86_gpr_ax), policy.true_());
2207                 policy.writeGPR(x86_gpr_sp, newSp);
2208                 break;
2209             }
2210
2211             case x86_pushfd: {
2212                 ROSE_ASSERT(operands.size() == 0);
2213                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2214                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2215                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2216                 policy.writeMemory(x86_segreg_ss, newSp, readEflags(), policy.true_());
2217                 policy.writeGPR(x86_gpr_sp, newSp);
2218                 break;
2219             }
2220 */
2221
2222             case x86_pop: {
2223                 ROSE_ASSERT(operands.size() == 1);
2224                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);
2225                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64);
2226                 Word(64) oldSp = policy.readGPR(x86_gpr_sp);
2227                 Word(64) newSp = policy.add(oldSp, number<64>(8));
2228                 write64(operands[0], readMemory<64>(x86_segreg_ss, oldSp, policy.true_()));
2229                 policy.writeGPR(x86_gpr_sp, newSp);
2230                 break;
2231             }
2232 /*
2233             case x86_popad: {
2234                 ROSE_ASSERT(operands.size() == 0);
2235                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2236                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2237                 Word(32) newSp = policy.add(oldSp, number<32>(32));
2238                 policy.writeGPR(x86_gpr_di, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2239                 policy.writeGPR(x86_gpr_si, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(4)), policy.true_()));
2240                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(8)), policy.true_()));
2241                 policy.writeGPR(x86_gpr_bx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(16)), policy.true_()));
2242                 policy.writeGPR(x86_gpr_dx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(20)), policy.true_()));
2243                 policy.writeGPR(x86_gpr_cx, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(24)), policy.true_()));
2244                 policy.writeGPR(x86_gpr_ax, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(28)), policy.true_()));
2245                 readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(12)), policy.true_());
2246                 policy.writeGPR(x86_gpr_sp, newSp);
2247                 break;
2248             }
2249
2250             case x86_leave: {
2251                 ROSE_ASSERT(operands.size() == 0);
2252                 policy.writeGPR(x86_gpr_sp, policy.readGPR(x86_gpr_bp));
2253                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2254                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2255                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2256                 Word(32) newSp = policy.add(oldSp, number<32>(4));
2257                 policy.writeGPR(x86_gpr_bp, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
2258                 policy.writeGPR(x86_gpr_sp, newSp);
2259                 break;
2260             }
2261
2262             case x86_call: {
2263                 ROSE_ASSERT(operands.size() == 1);
2264                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2265                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2266                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2267                 Word(32) newSp = policy.add(oldSp, number<32>(-4));
2268                 policy.writeMemory(x86_segreg_ss, newSp, policy.readIP(), policy.true_());
2269                 policy.writeIP(policy.filterCallTarget(read32(operands[0])));
2270                 policy.writeGPR(x86_gpr_sp, newSp);
2271                 break;
2272             }
2273
2274             case x86_ret: {
2275                 ROSE_ASSERT(operands.size() <= 1);
2276                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2277                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2278                                 Word(32) extraBytes = (operands.size() == 1 ? read32(operands[0]) : number<32>(0));
2279                 Word(32) oldSp = policy.readGPR(x86_gpr_sp);
2280                 Word(32) newSp = policy.add(oldSp, policy.add(number<32>(4), extraBytes));
2281                 policy.writeIP(policy.filterReturnTarget(readMemory<32>(x86_segreg_ss, oldSp, policy.true_())));
2282                 policy.writeGPR(x86_gpr_sp, newSp);
2283                 break;
2284             }
2285
2286             case x86_loop: {
2287                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2288                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2289                 ROSE_ASSERT(operands.size() == 1);
2290                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2291                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2292                 policy.writeGPR(x86_gpr_cx, newCx);
2293                 Word(1) doLoop = policy.invert(policy.equalToZero(newCx));
2294                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2295                 break;
2296             }
2297             case x86_loopz: {
2298                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2299                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2300                 ROSE_ASSERT(operands.size() == 1);
2301                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2302                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2303                 policy.writeGPR(x86_gpr_cx, newCx);
2304                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)), policy.readFlag(x86_flag_zf));
2305                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2306                 break;
2307             }
2308             case x86_loopnz: {
2309                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32);
2310                 ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32);
2311                 ROSE_ASSERT(operands.size() == 1);
2312                 Word(32) oldCx = policy.readGPR(x86_gpr_cx);
2313                 Word(32) newCx = policy.add(number<32>(-1), oldCx);
2314                 policy.writeGPR(x86_gpr_cx, newCx);
2315                 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)),
2316                                              policy.invert(policy.readFlag(x86_flag_zf)));
2317                 policy.writeIP(policy.ite(doLoop, read32(operands[0]), policy.readIP()));
2318                 break;
2319             }
2320 */
2321             case x86_jmp: {
2322                 ROSE_ASSERT(operands.size() == 1);
2323                 policy.writeIP(policy.filterIndirectJumpTarget(read64(operands[0])));
2324                 break;
2325             }
2326
2327
2328             /* Flag expressions that must be true for a conditional jump to occur. */
2329 #           define FLAGCOMBO_ne    policy.invert(policy.readFlag(x86_flag_zf))
2330 #           define FLAGCOMBO_e     policy.readFlag(x86_flag_zf)
2331 #           define FLAGCOMBO_no    policy.invert(policy.readFlag(x86_flag_of))
2332 #           define FLAGCOMBO_o     policy.readFlag(x86_flag_of)
2333 #           define FLAGCOMBO_ns    policy.invert(policy.readFlag(x86_flag_sf))
2334 #           define FLAGCOMBO_s     policy.readFlag(x86_flag_sf)
2335 #           define FLAGCOMBO_po    policy.invert(policy.readFlag(x86_flag_pf))
2336 #           define FLAGCOMBO_pe    policy.readFlag(x86_flag_pf)
2337 #           define FLAGCOMBO_ae    policy.invert(policy.readFlag(x86_flag_cf))
2338 #           define FLAGCOMBO_b     policy.readFlag(x86_flag_cf)
2339 #           define FLAGCOMBO_be    policy.or_(FLAGCOMBO_b, FLAGCOMBO_e)
2340 #           define FLAGCOMBO_a     policy.and_(FLAGCOMBO_ae, FLAGCOMBO_ne)
2341 #           define FLAGCOMBO_l     policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of))
2342 #           define FLAGCOMBO_ge    policy.invert(policy.xor_(policy.readFlag(x86_flag_sf), policy.readFlag(x86_flag_of)))
2343 #           define FLAGCOMBO_le    policy.or_(FLAGCOMBO_e, FLAGCOMBO_l)
2344 #           define FLAGCOMBO_g     policy.and_(FLAGCOMBO_ge, FLAGCOMBO_ne)
2345 #           define FLAGCOMBO_cxz   policy.equalToZero(extract<0, 16>(policy.readGPR(x86_gpr_cx)))
2346 #           define FLAGCOMBO_ecxz  policy.equalToZero(policy.readGPR(x86_gpr_cx))
2347
2348 #           define JUMP(tag) {                                                                                                 \
2349                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2350                 policy.writeIP(policy.ite(FLAGCOMBO_##tag,                                                                     \
2351                                           read64(operands[0]),                                                                 \
2352                                           policy.readIP()));                                                                   \
2353             }
2354             case x86_jne:   JUMP(ne);   break;
2355             case x86_je:    JUMP(e);    break;
2356             case x86_jno:   JUMP(no);   break;
2357             case x86_jo:    JUMP(o);    break;
2358             case x86_jpo:   JUMP(po);   break;
2359             case x86_jpe:   JUMP(pe);   break;
2360             case x86_jns:   JUMP(ns);   break;
2361             case x86_js:    JUMP(s);    break;
2362             case x86_jae:   JUMP(ae);   break;
2363             case x86_jb:    JUMP(b);    break;
2364             case x86_jbe:   JUMP(be);   break;
2365             case x86_ja:    JUMP(a);    break;
2366             case x86_jle:   JUMP(le);   break;
2367             case x86_jg:    JUMP(g);    break;
2368             case x86_jge:   JUMP(ge);   break;
2369             case x86_jl:    JUMP(l);    break;
2370             case x86_jcxz:  JUMP(cxz);  break;
2371             case x86_jecxz: JUMP(ecxz); break;
2372 #           undef JUMP
2373
2374 #           define SET(tag) {                                                                                                  \
2375                 ROSE_ASSERT(operands.size() == 1);                                                                             \
2376                 write8(operands[0], policy.concat(FLAGCOMBO_##tag, number<7>(0)));                                             \
2377             }
2378             case x86_setne: SET(ne); break;
2379             case x86_sete:  SET(e);  break;
2380             case x86_setno: SET(no); break;
2381             case x86_seto:  SET(o);  break;
2382             case x86_setpo: SET(po); break;
2383             case x86_setpe: SET(pe); break;
2384             case x86_setns: SET(ns); break;
2385             case x86_sets:  SET(s);  break;
2386             case x86_setae: SET(ae); break;
2387             case x86_setb:  SET(b);  break;
2388             case x86_setbe: SET(be); break;
2389             case x86_seta:  SET(a);  break;
2390             case x86_setle: SET(le); break;
2391             case x86_setg:  SET(g);  break;
2392             case x86_setge: SET(ge); break;
2393             case x86_setl:  SET(l);  break;
2394 #           undef SET
2395                 
2396 #           define CMOV(tag) {                                                                                                 \
2397                 ROSE_ASSERT(operands.size() == 2);                                                                             \
2398                 switch (numBytesInAsmType(operands[0]->get_type())) {                                                          \
2399                     case 2: write16(operands[0], policy.ite(FLAGCOMBO_##tag, read16(operands[1]), read16(operands[0]))); break; \
2400                     case 4: write32(operands[0], policy.ite(FLAGCOMBO_##tag, read32(operands[1]), read32(operands[0]))); break; \
2401                     case 8: write64(operands[0], policy.ite(FLAGCOMBO_##tag, read64(operands[1]), read64(operands[0]))); break; \
2402                     default: ROSE_ASSERT(!"Bad size"); break;                                                                   \
2403                 }                                                                                                              \
2404             }
2405 /*            case x86_cmovne:    CMOV(ne);       break;
2406             case x86_cmove:     CMOV(e);        break;
2407             case x86_cmovno:    CMOV(no);       break;
2408             case x86_cmovo:     CMOV(o);        break;
2409             case x86_cmovpo:    CMOV(po);       break;
2410             case x86_cmovpe:    CMOV(pe);       break;
2411             case x86_cmovns:    CMOV(ns);       break;
2412             case x86_cmovs:     CMOV(s);        break;
2413             case x86_cmovae:    CMOV(ae);       break;
2414             case x86_cmovb:     CMOV(b);        break;
2415             case x86_cmovbe:    CMOV(be);       break;
2416             case x86_cmova:     CMOV(a);        break;
2417             case x86_cmovle:    CMOV(le);       break;
2418             case x86_cmovg:     CMOV(g);        break;
2419             case x86_cmovge:    CMOV(ge);       break;
2420             case x86_cmovl:     CMOV(l);        break;
2421 */          
2422 #           undef CMOV
2423
2424             /* The flag expressions are no longer needed */
2425 #           undef FLAGCOMBO_ne
2426 #           undef FLAGCOMBO_e
2427 #           undef FLAGCOMBO_ns
2428 #           undef FLAGCOMBO_s
2429 #           undef FLAGCOMBO_ae
2430 #           undef FLAGCOMBO_b
2431 #           undef FLAGCOMBO_be
2432 #           undef FLAGCOMBO_a
2433 #           undef FLAGCOMBO_l
2434 #           undef FLAGCOMBO_ge
2435 #           undef FLAGCOMBO_le
2436 #           undef FLAGCOMBO_g
2437 #           undef FLAGCOMBO_cxz
2438 #           undef FLAGCOMBO_ecxz
2439
2440             case x86_cld: {
2441                 ROSE_ASSERT(operands.size() == 0);
2442                 policy.writeFlag(x86_flag_df, policy.false_());
2443                 break;
2444             }
2445
2446             case x86_std: {
2447                 ROSE_ASSERT(operands.size() == 0);
2448                 policy.writeFlag(x86_flag_df, policy.true_());
2449                 break;
2450             }
2451
2452             case x86_clc: {
2453                 ROSE_ASSERT(operands.size() == 0);
2454                 policy.writeFlag(x86_flag_cf, policy.false_());
2455                 break;
2456             }
2457
2458             case x86_stc: {
2459                 ROSE_ASSERT(operands.size() == 0);
2460                 policy.writeFlag(x86_flag_cf, policy.true_());
2461                 break;
2462             }
2463
2464             case x86_cmc: {
2465                 ROSE_ASSERT(operands.size() == 0);
2466                 policy.writeFlag(x86_flag_cf, policy.invert(policy.readFlag(x86_flag_cf)));
2467                 break;
2468             }
2469
2470             case x86_nop:
2471                 break;
2472
2473 #           define STRINGOP_LOAD_SI(len, cond)                                                                                 \
2474                 readMemory<(8 * (len))>((insn->get_segmentOverride() == x86_segreg_none ?                                      \
2475                                          x86_segreg_ds :                                                                       \
2476                                          insn->get_segmentOverride()),                                                         \
2477                                         policy.readGPR(x86_gpr_si),                                                            \
2478                                         (cond))
2479             
2480 #           define STRINGOP_LOAD_DI(len, cond)                                                                                 \
2481                 readMemory<(8 * (len))>(x86_segreg_es, policy.readGPR(x86_gpr_di), (cond))
2482
2483             /* If true, repeat this instruction, otherwise go to the next one */
2484 #           define STRINGOP_LOOP_E                                                                                             \
2485                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.readFlag(x86_flag_zf)),                               \
2486                                           number<64>((uint64_t)(insn->get_address())),                                         \
2487                                           policy.readIP()))
2488
2489             /* If true, repeat this instruction, otherwise go to the next one */
2490 #           define STRINGOP_LOOP_NE                                                                                            \
2491                 policy.writeIP(policy.ite(policy.and_(ecxNotZero, policy.invert(policy.readFlag(x86_flag_zf))),                \
2492                                           number<64>((uint64_t)(insn->get_address())),                                         \
2493                                           policy.readIP()))
2494
2495 #           define REP_SCAS(suffix, len, repsuffix, loopmacro) {                                                               \
2496                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2497                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2498                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2499                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2500                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2501                                           true,                                                                                \
2502                                           policy.false_(),                                                                     \
2503                                           ecxNotZero);                                                                         \
2504                 policy.writeGPR(x86_gpr_di,                                                                                    \
2505                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2506                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2507                 loopmacro;                                                                                                     \
2508             }
2509             case x86_repne_scasb: REP_SCAS(b, 1, ne, STRINGOP_LOOP_NE); break;
2510             case x86_repne_scasw: REP_SCAS(w, 2, ne, STRINGOP_LOOP_NE); break;
2511             case x86_repne_scasd: REP_SCAS(d, 4, ne, STRINGOP_LOOP_NE); break;
2512             case x86_repe_scasb:  REP_SCAS(b, 1, e,  STRINGOP_LOOP_E);  break;
2513             case x86_repe_scasw:  REP_SCAS(w, 2, e,  STRINGOP_LOOP_E);  break;
2514             case x86_repe_scasd:  REP_SCAS(d, 4, e,  STRINGOP_LOOP_E);  break;
2515 #           undef REP_SCAS
2516
2517 #           define SCAS(suffix, len) {                                                                                         \
2518                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2519                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2520                 doAddOperation<(len * 8)>(extract<0, (len * 8)>(policy.readGPR(x86_gpr_ax)),                                   \
2521                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2522                                           true,                                                                                \
2523                                           policy.false_(),                                                                     \
2524                                           policy.true_());                                                                     \
2525                 policy.writeGPR(x86_gpr_di,                                                                                    \
2526                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2527                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2528             }
2529             case x86_scasb: SCAS(b, 1); break;
2530             case x86_scasw: SCAS(w, 2); break;
2531             case x86_scasd: SCAS(d, 4); break;
2532 #           undef SCAS
2533
2534 #           define REP_CMPS(suffix, len, repsuffix, loopmacro) {                                                               \
2535                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2536                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2537                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2538                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, ecxNotZero),                                                   \
2539                                           policy.invert(STRINGOP_LOAD_DI(len, ecxNotZero)),                                    \
2540                                           true,                                                                                \
2541                                           policy.false_(),                                                                     \
2542                                           ecxNotZero);                                                                         \
2543                 policy.writeGPR(x86_gpr_si,                                                                                    \
2544                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2545                                            policy.ite(ecxNotZero,                                                              \
2546                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2547                                                                  number<64>(-(len)),                                           \
2548                                                                  number<64>(len)),                                             \
2549                                                       number<64>(0))));                                                        \
2550                 policy.writeGPR(x86_gpr_di,                                                                                    \
2551                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2552                                            policy.ite(ecxNotZero,                                                              \
2553                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2554                                                                  number<64>(-(len)),                                           \
2555                                                                  number<64>(len)),                                             \
2556                                                       number<64>(0))));                                                        \
2557                 loopmacro;                                                                                                     \
2558             }
2559             case x86_repne_cmpsb: REP_CMPS(b, 1, ne, STRINGOP_LOOP_NE); break;
2560             case x86_repne_cmpsw: REP_CMPS(w, 2, ne, STRINGOP_LOOP_NE); break;
2561             case x86_repne_cmpsd: REP_CMPS(d, 4, ne, STRINGOP_LOOP_NE); break;
2562             case x86_repe_cmpsb:  REP_CMPS(b, 1, e,  STRINGOP_LOOP_E);  break;
2563             case x86_repe_cmpsw:  REP_CMPS(w, 2, e,  STRINGOP_LOOP_E);  break;
2564             case x86_repe_cmpsd:  REP_CMPS(d, 4, e,  STRINGOP_LOOP_E);  break;
2565 #           undef REP_CMPS
2566
2567 #           define CMPS(suffix, len) {                                                                                         \
2568                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2569                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2570                 doAddOperation<(len * 8)>(STRINGOP_LOAD_SI(len, policy.true_()),                                               \
2571                                           policy.invert(STRINGOP_LOAD_DI(len, policy.true_())),                                \
2572                                           true,                                                                                \
2573                                           policy.false_(),                                                                     \
2574                                           policy.true_());                                                                     \
2575                 policy.writeGPR(x86_gpr_si,                                                                                    \
2576                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2577                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2578                 policy.writeGPR(x86_gpr_di,                                                                                    \
2579                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2580                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2581             }
2582             case x86_cmpsb: CMPS(b, 1); break;
2583             case x86_cmpsw: CMPS(w, 2); break;
2584             case x86_cmpsd: CMPS(d, 4); break;
2585 #           undef CMPS
2586
2587 #           define MOVS(suffix, len) {                                                                                         \
2588                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2589                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2590                 policy.writeMemory(x86_segreg_es,                                                                              \
2591                                    policy.readGPR(x86_gpr_di),                                                                 \
2592                                    STRINGOP_LOAD_SI(len, policy.true_()),                                                      \
2593                                    policy.true_());                                                                            \
2594                 policy.writeGPR(x86_gpr_si,                                                                                    \
2595                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2596                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2597                 policy.writeGPR(x86_gpr_di,                                                                                    \
2598                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2599                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2600             }
2601             case x86_movsb: MOVS(b, 1); break;
2602             case x86_movsw: MOVS(w, 2); break;
2603             case x86_movsd: MOVS(d, 4); break;
2604 #           undef MOVS
2605
2606 #           define REP_MOVS(suffix, len) {                                                                                     \
2607                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2608                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2609                 Word(1) ecxNotZero = stringop_setup_loop();                                                                    \
2610                 policy.writeMemory(x86_segreg_es, policy.readGPR(x86_gpr_di), STRINGOP_LOAD_SI(len, ecxNotZero), ecxNotZero);  \
2611                 policy.writeGPR(x86_gpr_si,                                                                                    \
2612                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2613                                            policy.ite(ecxNotZero,                                                              \
2614                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2615                                                                  number<64>(-(len)),                                           \
2616                                                                  number<64>(len)),                                             \
2617                                                       number<64>(0))));                                                        \
2618                 policy.writeGPR(x86_gpr_di,                                                                                    \
2619                                 policy.add(policy.readGPR(x86_gpr_di),                                                         \
2620                                            policy.ite(ecxNotZero,                                                              \
2621                                                       policy.ite(policy.readFlag(x86_flag_df),                                 \
2622                                                                  number<64>(-(len)),                                           \
2623                                                                  number<64>(len)),                                             \
2624                                                       number<64>(0))));                                                        \
2625                 policy.writeIP(policy.ite(ecxNotZero, /* If true, repeat this instruction, otherwise go to the next one */     \
2626                                           number<64>((uint32_t)(insn->get_address())),                                         \
2627                                           policy.readIP()));                                                                   \
2628             }
2629             case x86_rep_movsb: REP_MOVS(b, 1); break;
2630             case x86_rep_movsw: REP_MOVS(w, 2); break;
2631             case x86_rep_movsd: REP_MOVS(d, 4); break;
2632 #           undef REP_MOVS
2633
2634             case x86_stosb: {
2635                 stos_semantics<1>(insn);
2636                 break;
2637             }
2638
2639             case x86_rep_stosb: {
2640                 rep_stos_semantics<1>(insn);
2641                 break;
2642             }
2643
2644             case x86_stosw: {
2645                 stos_semantics<2>(insn);
2646                 break;
2647             }
2648
2649             case x86_rep_stosw: {
2650                 rep_stos_semantics<2>(insn);
2651                 break;
2652             }
2653
2654             case x86_stosd: {
2655                 stos_semantics<4>(insn);
2656                 break;
2657             }
2658
2659             case x86_rep_stosd: {
2660                 rep_stos_semantics<4>(insn);
2661                 break;
2662             }
2663
2664 #           define LODS(suffix, len, regupdate) {                                                                              \
2665                 ROSE_ASSERT(operands.size() == 0);                                                                             \
2666                 ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64);                                                       \
2667                 regupdate(x86_gpr_ax, STRINGOP_LOAD_SI(len, policy.true_()));                                                  \
2668                 policy.writeGPR(x86_gpr_si,                                                                                    \
2669                                 policy.add(policy.readGPR(x86_gpr_si),                                                         \
2670                                            policy.ite(policy.readFlag(x86_flag_df), number<64>(-(len)), number<64>(len))));    \
2671             }
2672             case x86_lodsb: LODS(b, 1, updateGPRLowByte); break;
2673             case x86_lodsw: LODS(w, 2, updateGPRLowWord); break;
2674             case x86_lodsd: LODS(d, 4, updateGPRLowDWord);  break;
2675 #           undef LODS
2676
2677 #undef STRINGOP_LOAD_SI
2678 #undef STRINGOP_LOAD_DI
2679 #undef STRINGOP_UPDATE_CX
2680 #undef STRINGOP_LOOP_E
2681 #undef STRINGOP_LOOP_NE
2682
2683             case x86_hlt: {
2684                 ROSE_ASSERT(operands.size() == 0);
2685                 policy.hlt();
2686                 policy.writeIP(number<64>((uint64_t)(insn->get_address())));
2687                 break;
2688             }
2689 /*
2690             case x86_rdtsc: {
2691                 ROSE_ASSERT(operands.size() == 0);
2692                 Word(64) tsc = policy.rdtsc();
2693                 policy.writeGPR(x86_gpr_ax, extract<0, 32>(tsc));
2694                 policy.writeGPR(x86_gpr_dx, extract<32, 64>(tsc));
2695                 break;
2696             }
2697
2698             case x86_int: {
2699                 ROSE_ASSERT(operands.size() == 1);
2700                 SgAsmByteValueExpression* bv = isSgAsmByteValueExpression(operands[0]);
2701                 ROSE_ASSERT(bv);
2702                 policy.interrupt(bv->get_value());
2703                 break;
2704             }
2705 */
2706                 /* This is a dummy version that should be replaced later FIXME */
2707 /*            case x86_fnstcw: {
2708                 ROSE_ASSERT(operands.size() == 1);
2709                 write16(operands[0], number<16>(0x37f));
2710                 break;
2711             }
2712
2713             case x86_fldcw: {
2714                 ROSE_ASSERT(operands.size() == 1);
2715                 read16(operands[0]); // To catch access control violations 
2716                 break;
2717             }
2718 */
2719             default: {
2720
2721 //                std::cerr <<"Bad instruction [0x" <<std::hex <<insn->get_address() <<": "// <<unparseInstruction(insn) <<"]"
2722 //                          <<" (skipping semantic analysis)\n";
2723                 break;
2724             }
2725         }
2726     }
2727
2728     void processInstruction(SgAsmx86Instruction* insn) {
2729         ROSE_ASSERT(insn);
2730         policy.startInstruction(insn);
2731         translate(insn);
2732         policy.finishInstruction(insn);
2733     }
2734
2735     /*
2736     void processBlock(const SgAsmStatementPtrList& stmts, size_t begin, size_t end) {
2737         if (begin == end) return;
2738         policy.startBlock(stmts[begin]->get_address());
2739         for (size_t i = begin; i < end; ++i) {
2740             processInstruction(isSgAsmx86Instruction(stmts[i]));
2741         }
2742         policy.finishBlock(stmts[begin]->get_address());
2743     }
2744     */
2745
2746     static bool isRepeatedStringOp(SgAsmx86Instruction* insn) {
2747         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2748         if (!insn) return false;
2749         switch (insn->get_kind()) {
2750             case x86_repe_cmpsb: return true;
2751             case x86_repe_cmpsd: return true;
2752             case x86_repe_cmpsq: return true;
2753             case x86_repe_cmpsw: return true;
2754             case x86_repe_scasb: return true;
2755             case x86_repe_scasd: return true;
2756             case x86_repe_scasq: return true;
2757             case x86_repe_scasw: return true;
2758             case x86_rep_insb: return true;
2759             case x86_rep_insd: return true;
2760             case x86_rep_insw: return true;
2761             case x86_rep_lodsb: return true;
2762             case x86_rep_lodsd: return true;
2763             case x86_rep_lodsq: return true;
2764             case x86_rep_lodsw: return true;
2765             case x86_rep_movsb: return true;
2766             case x86_rep_movsd: return true;
2767             case x86_rep_movsq: return true;
2768             case x86_rep_movsw: return true;
2769             case x86_repne_cmpsb: return true;
2770             case x86_repne_cmpsd: return true;
2771             case x86_repne_cmpsq: return true;
2772             case x86_repne_cmpsw: return true;
2773             case x86_repne_scasb: return true;
2774             case x86_repne_scasd: return true;
2775             case x86_repne_scasq: return true;
2776             case x86_repne_scasw: return true;
2777             case x86_rep_outsb: return true;
2778             case x86_rep_outsd: return true;
2779             case x86_rep_outsw: return true;
2780             case x86_rep_stosb: return true;
2781             case x86_rep_stosd: return true;
2782             case x86_rep_stosq: return true;
2783             case x86_rep_stosw: return true;
2784             default: return false;
2785         }
2786     }
2787
2788     static bool isHltOrInt(SgAsmx86Instruction* insn) {
2789         //SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
2790         if (!insn) return false;
2791         switch (insn->get_kind()) {
2792             case x86_hlt: return true;
2793             case x86_int: return true;
2794             default: return false;
2795         }
2796     }
2797
2798 #if 0
2799     void processBlock(SgAsmBlock* b) {
2800         const SgAsmStatementPtrList& stmts = b->get_statementList();
2801         if (stmts.empty()) return;
2802         if (!isSgAsmInstruction(stmts[0])) return; /* A block containing functions or something */
2803         size_t i = 0;
2804         while (i < stmts.size()) {
2805             size_t oldI = i;
2806             /* Advance until either i points to a repeated string op or it is just after a hlt or int */
2807             while (i < stmts.size() && !isRepeatedStringOp(stmts[i]) && (i == oldI || !isHltOrInt(stmts[i - 1]))) ++i;
2808             processBlock(stmts, oldI, i);
2809             if (i >= stmts.size()) break;
2810             if (isRepeatedStringOp(stmts[i])) {
2811                 processBlock(stmts, i, i + 1);
2812                 ++i;
2813             }
2814             ROSE_ASSERT(i != oldI);
2815         }
2816     }
2817 #endif
2818
2819 };
2820
2821 #undef Word
2822
2823 #endif // ROSE_X86_64INSTRUCTIONSEMANTICS_H