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