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