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