00001 #ifndef ROSE_X86INSTRUCTIONSEMANTICS_H
00002 #define ROSE_X86INSTRUCTIONSEMANTICS_H
00003
00004
00005
00006
00007
00008 #include "semanticsModule.h"
00009 #include <cassert>
00010 #include <cstdio>
00011 #include <iostream>
00012 #include "integerOps.h"
00013 #include "AsmUnparser_compat.h"
00014
00015
00016 static inline X86SegmentRegister getSegregFromMemoryReference(SgAsmMemoryReferenceExpression* mr) {
00017 X86SegmentRegister segreg = x86_segreg_none;
00018 SgAsmx86RegisterReferenceExpression* seg = isSgAsmx86RegisterReferenceExpression(mr->get_segment());
00019 if (seg) {
00020 ROSE_ASSERT(seg->get_descriptor().get_major() == x86_regclass_segment);
00021 segreg = (X86SegmentRegister)(seg->get_descriptor().get_minor());
00022 } else {
00023 ROSE_ASSERT(!"Bad segment expr");
00024 }
00025 if (segreg == x86_segreg_none) segreg = x86_segreg_ds;
00026 return segreg;
00027 }
00028
00029 namespace BinaryAnalysis {
00030 namespace InstructionSemantics {
00031
00036 template <typename Policy, template <size_t> class WordType>
00037 struct X86InstructionSemantics {
00038 # ifdef Word
00039 # error "Having a macro called \"Word\" conflicts with x86InstructionSemantics.h"
00040 # else
00041 # define Word(Len) WordType<(Len)>
00042 # endif
00043
00044 struct Exception {
00045 Exception(const std::string &mesg, SgAsmInstruction *insn): mesg(mesg), insn(insn) {}
00046 friend std::ostream& operator<<(std::ostream &o, const Exception &e) {
00047 o <<"instruction semantics: " <<e.mesg;
00048 if (e.insn) o <<" [" <<unparseInstructionWithAddress(e.insn) <<"]";
00049 return o;
00050 }
00051 std::string mesg;
00052 SgAsmInstruction *insn;
00053 };
00054
00055 Policy& policy;
00056 SgAsmInstruction *current_instruction;
00057 Word(32) orig_eip;
00058
00059
00060 RegisterDescriptor REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_EDI, REG_EIP, REG_ESI, REG_ESP, REG_EBP;
00061 RegisterDescriptor REG_AX, REG_CX, REG_DX, REG_AL, REG_AH;
00062 RegisterDescriptor REG_EFLAGS, REG_AF, REG_CF, REG_DF, REG_OF, REG_PF, REG_SF, REG_ZF;
00063
00064 X86InstructionSemantics(Policy& policy)
00065 : policy(policy), current_instruction(NULL), orig_eip(policy.readRegister<32>(policy.findRegister("eip"))) {
00066 REG_EAX = policy.findRegister("eax", 32);
00067 REG_EBX = policy.findRegister("ebx", 32);
00068 REG_ECX = policy.findRegister("ecx", 32);
00069 REG_EDX = policy.findRegister("edx", 32);
00070 REG_EDI = policy.findRegister("edi", 32);
00071 REG_EIP = policy.findRegister("eip", 32);
00072 REG_ESI = policy.findRegister("esi", 32);
00073 REG_ESP = policy.findRegister("esp", 32);
00074 REG_EBP = policy.findRegister("ebp", 32);
00075
00076 REG_AX = policy.findRegister("ax", 16);
00077 REG_CX = policy.findRegister("cx", 16);
00078 REG_DX = policy.findRegister("dx", 16);
00079
00080 REG_AL = policy.findRegister("al", 8);
00081 REG_AH = policy.findRegister("ah", 8);
00082
00083 REG_EFLAGS=policy.findRegister("eflags", 32);
00084 REG_AF = policy.findRegister("af", 1);
00085 REG_CF = policy.findRegister("cf", 1);
00086 REG_DF = policy.findRegister("df", 1);
00087 REG_OF = policy.findRegister("of", 1);
00088 REG_PF = policy.findRegister("pf", 1);
00089 REG_SF = policy.findRegister("sf", 1);
00090 REG_ZF = policy.findRegister("zf", 1);
00091 }
00092 virtual ~X86InstructionSemantics() {}
00093
00096 WordType<1> rep_enter() {
00097 return policy.invert(policy.equalToZero(readRegister<32>(REG_ECX)));
00098 }
00099
00104 void rep_repeat(SgAsmx86Instruction *insn, WordType<1> repeat, WordType<1> cond) {
00105 WordType<32> new_cx = policy.add(readRegister<32>(REG_ECX),
00106 policy.ite(cond,
00107 number<32>(-1),
00108 number<32>(0)));
00109 writeRegister(REG_ECX, new_cx);
00110 repeat = policy.and_(repeat, policy.invert(policy.equalToZero(new_cx)));
00111 writeRegister(REG_EIP,
00112 policy.ite(policy.and_(cond, repeat),
00113 orig_eip,
00114 readRegister<32>(REG_EIP)));
00115 }
00116
00118 template<size_t N>
00119 WordType<8*N> stringop_load_si(SgAsmx86Instruction *insn, WordType<1> cond) {
00120 return readMemory<8*N>((insn->get_segmentOverride() == x86_segreg_none ? x86_segreg_ds : insn->get_segmentOverride()),
00121 readRegister<32>(REG_ESI),
00122 cond);
00123 }
00124
00126 template<size_t N>
00127 WordType<8*N> stringop_load_di(WordType<1> cond) {
00128 return readMemory<8*N>(x86_segreg_es, readRegister<32>(REG_EDI), cond);
00129 }
00130
00133 template<size_t N>
00134 void stos_semantics(SgAsmx86Instruction *insn, WordType<1> cond) {
00135 const SgAsmExpressionPtrList& operands = insn->get_operandList()->get_operands();
00136 if (operands.size()!=0)
00137 throw Exception("instruction must have no operands", insn);
00138 if (insn->get_addressSize()!=x86_insnsize_32)
00139 throw Exception("address size must be 32 bits", insn);
00140
00141
00142 policy.writeMemory(x86_segreg_es,
00143 readRegister<32>(REG_EDI),
00144 extract<0, 8*N>(readRegister<32>(REG_EAX)),
00145 cond);
00146
00147
00148 writeRegister(REG_EDI,
00149 policy.ite(cond,
00150 policy.add(readRegister<32>(REG_EDI),
00151 policy.ite(readRegister<1>(REG_DF), number<32>(-N), number<32>(N))),
00152 readRegister<32>(REG_EDI)));
00153 }
00154
00157 template<size_t N>
00158 void rep_stos_semantics(SgAsmx86Instruction *insn) {
00159 WordType<1> in_loop = rep_enter();
00160 stos_semantics<N>(insn, in_loop);
00161 rep_repeat(insn, policy.true_(), in_loop);
00162 }
00163
00166 template<size_t N>
00167 void movs_semantics(SgAsmx86Instruction *insn, WordType<1> cond) {
00168 const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands();
00169 if (operands.size()!=0)
00170 throw Exception("instruction must have no operands", insn);
00171 if (insn->get_addressSize() != x86_insnsize_32)
00172 throw Exception("size not implemented", insn);
00173
00174 policy.writeMemory(x86_segreg_es,
00175 readRegister<32>(REG_EDI),
00176 stringop_load_si<N>(insn, cond),
00177 cond);
00178 writeRegister(REG_ESI,
00179 policy.add(readRegister<32>(REG_ESI),
00180 policy.ite(cond,
00181 policy.ite(readRegister<1>(REG_DF),
00182 number<32>(-(N)),
00183 number<32>(N)),
00184 number<32>(0))));
00185 writeRegister(REG_EDI,
00186 policy.add(readRegister<32>(REG_EDI),
00187 policy.ite(cond,
00188 policy.ite(readRegister<1>(REG_DF),
00189 number<32>(-(N)),
00190 number<32>(N)),
00191 number<32>(0))));
00192 }
00193
00196 template<size_t N>
00197 void rep_movs_semantics(SgAsmx86Instruction *insn) {
00198 WordType<1> in_loop = rep_enter();
00199 movs_semantics<N>(insn, in_loop);
00200 rep_repeat(insn, policy.true_(), in_loop);
00201 }
00202
00205 template<size_t N>
00206 void cmps_semantics(SgAsmx86Instruction *insn, WordType<1> cond) {
00207 const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands();
00208 if (operands.size()!=0)
00209 throw Exception("instruction must have no operands", insn);
00210 if (insn->get_addressSize() != x86_insnsize_32)
00211 throw Exception("size not implemented", insn);
00212 doAddOperation<8*N>(stringop_load_si<N>(insn, cond),
00213 policy.invert(stringop_load_di<N>(cond)),
00214 true,
00215 policy.false_(),
00216 cond);
00217 writeRegister(REG_ESI,
00218 policy.ite(cond,
00219 policy.add(readRegister<32>(REG_ESI),
00220 policy.ite(readRegister<1>(REG_DF), number<32>(-N), number<32>(N))),
00221 readRegister<32>(REG_ESI)));
00222 writeRegister(REG_EDI,
00223 policy.ite(cond,
00224 policy.add(readRegister<32>(REG_EDI),
00225 policy.ite(readRegister<1>(REG_DF), number<32>(-N), number<32>(N))),
00226 readRegister<32>(REG_EDI)));
00227 }
00228
00230 template<size_t N>
00231 void repe_cmps_semantics(SgAsmx86Instruction *insn) {
00232 WordType<1> in_loop = rep_enter();
00233 cmps_semantics<N>(insn, in_loop);
00234 WordType<1> repeat = readRegister<1>(REG_ZF);
00235 rep_repeat(insn, repeat, in_loop);
00236 }
00237
00239 template<size_t N>
00240 void repne_cmps_semantics(SgAsmx86Instruction *insn) {
00241 WordType<1> in_loop = rep_enter();
00242 cmps_semantics<N>(insn, in_loop);
00243 WordType<1> repeat = policy.invert(readRegister<1>(REG_ZF));
00244 rep_repeat(insn, repeat, in_loop);
00245 }
00246
00249 template<size_t N>
00250 void scas_semantics(SgAsmx86Instruction *insn, WordType<1> cond) {
00251 const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands();
00252 if (operands.size()!=0)
00253 throw Exception("instruction must have no operands", insn);
00254 if (insn->get_addressSize() != x86_insnsize_32)
00255 throw Exception("size not implemented", insn);
00256 doAddOperation<8*N>(extract<0, 8*N>(readRegister<32>(REG_EAX)),
00257 policy.invert(stringop_load_di<N>(cond)),
00258 true,
00259 policy.false_(),
00260 cond);
00261 writeRegister(REG_EDI,
00262 policy.ite(cond,
00263 policy.add(readRegister<32>(REG_EDI),
00264 policy.ite(readRegister<1>(REG_DF), number<32>(-N), number<32>(N))),
00265 readRegister<32>(REG_EDI)));
00266 }
00267
00269 template<size_t N>
00270 void repe_scas_semantics(SgAsmx86Instruction *insn) {
00271 WordType<1> in_loop = rep_enter();
00272 scas_semantics<N>(insn, in_loop);
00273 WordType<1> repeat = readRegister<1>(REG_ZF);
00274 rep_repeat(insn, repeat, in_loop);
00275 }
00276
00278 template<size_t N>
00279 void repne_scas_semantics(SgAsmx86Instruction *insn) {
00280 WordType<1> in_loop = rep_enter();
00281 scas_semantics<N>(insn, in_loop);
00282 WordType<1> repeat = policy.invert(readRegister<1>(REG_ZF));
00283 rep_repeat(insn, repeat, in_loop);
00284 }
00285
00287 void lods_semantics_regupdate(WordType<8> v) {
00288 writeRegister(REG_AL, v);
00289 }
00290
00292 void lods_semantics_regupdate(WordType<16> v) {
00293 writeRegister(REG_AX, v);
00294 }
00295
00297 void lods_semantics_regupdate(WordType<32> v) {
00298 writeRegister(REG_EAX, v);
00299 }
00300
00302 template<size_t N>
00303 void lods_semantics(SgAsmx86Instruction *insn) {
00304 const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands();
00305 if (operands.size()!=0)
00306 throw Exception("instruction must have no operands", insn);
00307 if (insn->get_addressSize() != x86_insnsize_32)
00308 throw Exception("size not implemented", insn);
00309 lods_semantics_regupdate(stringop_load_si<N>(insn, policy.true_()));
00310 writeRegister(REG_ESI,
00311 policy.add(readRegister<32>(REG_ESI),
00312 policy.ite(readRegister<1>(REG_DF), number<32>(-N), number<32>(N))));
00313 }
00314
00319 template<size_t operandBits, size_t shiftSignificantBits>
00320 WordType<operandBits> shift_semantics(X86InstructionKind kind, const WordType<operandBits> &operand,
00321 const WordType<8> &total_shift) {
00322 assert(x86_shr==kind || x86_sar==kind || x86_shl==kind);
00323
00324
00325
00326 WordType<shiftSignificantBits> maskedShiftCount = extract<0, shiftSignificantBits>(total_shift);
00327 WordType<1> isZeroShiftCount = policy.equalToZero(maskedShiftCount);
00328
00329
00330 WordType<operandBits> retval;
00331 switch (kind) {
00332 case x86_shr:
00333 retval = policy.shiftRight(operand, maskedShiftCount);
00334 break;
00335 case x86_sar:
00336 retval = policy.shiftRightArithmetic(operand, maskedShiftCount);
00337 break;
00338 case x86_shl:
00339 retval = policy.shiftLeft(operand, maskedShiftCount);
00340 break;
00341 default:
00342 abort();
00343 }
00344
00345
00346
00347 writeRegister(REG_AF, policy.ite(isZeroShiftCount, readRegister<1>(REG_AF), policy.undefined_()));
00348
00349
00350
00351 uintmax_t m = ((uintmax_t)1 << shiftSignificantBits) - 1;
00352 WordType<shiftSignificantBits> mask = number<shiftSignificantBits>(m);
00353 WordType<shiftSignificantBits> bitPosition;
00354 if (x86_shr==kind || x86_sar==kind) {
00355 bitPosition = policy.add(maskedShiftCount, mask);
00356 } else {
00357 bitPosition = policy.add(number<shiftSignificantBits>(operandBits & m),
00358 policy.add(policy.invert(maskedShiftCount),
00359 number<shiftSignificantBits>(1)));
00360 }
00361 WordType<1> shifted_off = extract<0, 1>(policy.shiftRight(operand, bitPosition));
00362
00363
00364
00365 assert(shiftSignificantBits<8);
00366 WordType<1> isLargeShift = policy.invert(policy.equalToZero(extract<shiftSignificantBits, 8>(total_shift)));
00367
00368
00369 WordType<1> isOneBitShift = policy.equalToZero(policy.add(maskedShiftCount, mask));
00370
00371
00372
00373
00374
00375 WordType<1> newCF = policy.ite(isZeroShiftCount,
00376 readRegister<1>(REG_CF),
00377 policy.ite(isLargeShift,
00378 (x86_sar==kind ?
00379 extract<operandBits-1, operandBits>(operand) :
00380 policy.undefined_()),
00381 shifted_off));
00382 writeRegister(REG_CF, newCF);
00383
00384
00385
00386
00387
00388
00389 WordType<1> newOF;
00390 switch (kind) {
00391 case x86_shr:
00392 newOF = policy.ite(isOneBitShift,
00393 extract<operandBits-1, operandBits>(operand),
00394 readRegister<1>(REG_OF));
00395 break;
00396 case x86_sar:
00397 newOF = policy.ite(isOneBitShift,
00398 policy.false_(),
00399 readRegister<1>(REG_OF));
00400 break;
00401 case x86_shl:
00402 newOF = policy.ite(isOneBitShift,
00403 policy.xor_(newCF, extract<operandBits-1, operandBits>(retval)),
00404 readRegister<1>(REG_OF));
00405 break;
00406 default:
00407 abort();
00408 }
00409 writeRegister(REG_OF, newOF);
00410
00411
00412 setFlagsForResult<operandBits>(retval, policy.invert(isZeroShiftCount));
00413 return retval;
00414 }
00415
00416 template <size_t Len>
00417 Word(Len) invertMaybe(const Word(Len)& w, bool inv) {
00418 if (inv) {
00419 return policy.invert(w);
00420 } else {
00421 return w;
00422 }
00423 }
00424
00425 template <size_t Len>
00426 Word(Len) number(uintmax_t v) {
00427 return policy.template number<Len>(v);
00428 }
00429
00430 template <size_t From, size_t To, size_t Len>
00431 Word(To - From) extract(Word(Len) w) {
00432 return policy.template extract<From, To>(w);
00433 }
00434
00435 template <size_t From, size_t To>
00436 Word(To) signExtend(Word(From) w) {
00437 return policy.template signExtend<From, To>(w);
00438 }
00439
00441 template<size_t Len>
00442 Word(Len) readRegister(const RegisterDescriptor ®) {
00443 return policy.template readRegister<Len>(reg);
00444 }
00445
00447 template<size_t Len>
00448 void writeRegister(const RegisterDescriptor ®, const Word(Len) &value) {
00449 policy.template writeRegister<Len>(reg, value);
00450 }
00451
00452 template <size_t Len>
00453 Word(1) greaterOrEqualToTen(Word(Len) w) {
00454 Word(Len) carries = number<Len>(0);
00455 policy.addWithCarries(w, number<Len>(6), policy.false_(), carries);
00456 return extract<Len - 1, Len>(carries);
00457 }
00458
00459 template <size_t Len>
00460 Word(Len) readMemory(X86SegmentRegister segreg, const Word(32)& addr, Word(1) cond) {
00461 return policy.template readMemory<Len>(segreg, addr, cond);
00462 }
00463
00464 Word(32) readEffectiveAddress(SgAsmExpression* expr) {
00465 assert (isSgAsmMemoryReferenceExpression(expr));
00466 return read32(isSgAsmMemoryReferenceExpression(expr)->get_address());
00467 }
00468
00469
00470 Word(8) read8(SgAsmExpression* e) {
00471 switch (e->variantT()) {
00472 case V_SgAsmx86RegisterReferenceExpression: {
00473 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00474 return policy.readRegister<8>(rre->get_descriptor());
00475 }
00476 case V_SgAsmBinaryAdd: {
00477 return policy.add(read8(isSgAsmBinaryAdd(e)->get_lhs()), read8(isSgAsmBinaryAdd(e)->get_rhs()));
00478 }
00479 case V_SgAsmBinaryMultiply: {
00480 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
00481 if (!rhs)
00482 throw Exception("byte value expression expected", current_instruction);
00483 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
00484 return extract<0, 8>(policy.unsignedMultiply(read8(lhs), read8(rhs)));
00485 }
00486 case V_SgAsmMemoryReferenceExpression: {
00487 return readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00488 readEffectiveAddress(e), policy.true_());
00489 }
00490 case V_SgAsmByteValueExpression:
00491 case V_SgAsmWordValueExpression:
00492 case V_SgAsmDoubleWordValueExpression:
00493 case V_SgAsmQuadWordValueExpression: {
00494 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
00495 return number<8>(val & 0xFFU);
00496 }
00497 default: {
00498 fprintf(stderr, "Bad variant %s in read8\n", e->class_name().c_str());
00499 abort();
00500 }
00501 }
00502 }
00503
00504
00505 Word(16) read16(SgAsmExpression* e) {
00506 switch (e->variantT()) {
00507 case V_SgAsmx86RegisterReferenceExpression: {
00508 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00509 return policy.readRegister<16>(rre->get_descriptor());
00510 }
00511 case V_SgAsmBinaryAdd: {
00512 return policy.add(read16(isSgAsmBinaryAdd(e)->get_lhs()), read16(isSgAsmBinaryAdd(e)->get_rhs()));
00513 }
00514 case V_SgAsmBinaryMultiply: {
00515 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
00516 if (!rhs)
00517 throw Exception("byte value expression expected", current_instruction);
00518 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
00519 return extract<0, 16>(policy.unsignedMultiply(read16(lhs), read8(rhs)));
00520 }
00521 case V_SgAsmMemoryReferenceExpression: {
00522 return readMemory<16>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00523 readEffectiveAddress(e), policy.true_());
00524 }
00525 case V_SgAsmByteValueExpression:
00526 case V_SgAsmWordValueExpression:
00527 case V_SgAsmDoubleWordValueExpression:
00528 case V_SgAsmQuadWordValueExpression: {
00529 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
00530 return number<16>(val & 0xFFFFU);
00531 }
00532 default: {
00533 fprintf(stderr, "Bad variant %s in read16\n", e->class_name().c_str());
00534 abort();
00535 }
00536 }
00537 }
00538
00539
00540 Word(32) read32(SgAsmExpression* e) {
00541 switch (e->variantT()) {
00542 case V_SgAsmx86RegisterReferenceExpression: {
00543 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00544 return policy.readRegister<32>(rre->get_descriptor());
00545 }
00546 case V_SgAsmBinaryAdd: {
00547 return policy.add(read32(isSgAsmBinaryAdd(e)->get_lhs()), read32(isSgAsmBinaryAdd(e)->get_rhs()));
00548 }
00549 case V_SgAsmBinaryMultiply: {
00550 SgAsmByteValueExpression* rhs = isSgAsmByteValueExpression(isSgAsmBinaryMultiply(e)->get_rhs());
00551 if (!rhs)
00552 throw Exception("byte value expression expected", current_instruction);
00553 SgAsmExpression* lhs = isSgAsmBinaryMultiply(e)->get_lhs();
00554 return extract<0, 32>(policy.unsignedMultiply(read32(lhs), read8(rhs)));
00555 }
00556 case V_SgAsmMemoryReferenceExpression: {
00557 return readMemory<32>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00558 readEffectiveAddress(e), policy.true_());
00559 }
00560 case V_SgAsmByteValueExpression:
00561 case V_SgAsmWordValueExpression:
00562 case V_SgAsmDoubleWordValueExpression:
00563 case V_SgAsmQuadWordValueExpression: {
00564 uint64_t val = SageInterface::getAsmSignedConstant(isSgAsmValueExpression(e));
00565 return number<32>(val & 0xFFFFFFFFU);
00566 }
00567 default: {
00568 fprintf(stderr, "Bad variant %s in read32\n", e->class_name().c_str());
00569 abort();
00570 }
00571 }
00572 }
00573
00574
00575 void write8(SgAsmExpression* e, const Word(8)& value) {
00576 switch (e->variantT()) {
00577 case V_SgAsmx86RegisterReferenceExpression: {
00578 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00579 policy.writeRegister(rre->get_descriptor(), value);
00580 break;
00581 }
00582 case V_SgAsmMemoryReferenceExpression: {
00583 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00584 readEffectiveAddress(e), value, policy.true_());
00585 break;
00586 }
00587 default: {
00588 fprintf(stderr, "Bad variant %s in write8\n", e->class_name().c_str());
00589 abort();
00590 }
00591 }
00592 }
00593
00594
00595 void write16(SgAsmExpression* e, const Word(16)& value) {
00596 switch (e->variantT()) {
00597 case V_SgAsmx86RegisterReferenceExpression: {
00598 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00599 policy.writeRegister(rre->get_descriptor(), value);
00600 break;
00601 }
00602 case V_SgAsmMemoryReferenceExpression: {
00603 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00604 readEffectiveAddress(e), value, policy.true_());
00605 break;
00606 }
00607 default: {
00608 fprintf(stderr, "Bad variant %s in write16\n", e->class_name().c_str());
00609 abort();
00610 }
00611 }
00612 }
00613
00614
00615 void write32(SgAsmExpression* e, const Word(32)& value) {
00616 switch (e->variantT()) {
00617 case V_SgAsmx86RegisterReferenceExpression: {
00618 SgAsmx86RegisterReferenceExpression* rre = isSgAsmx86RegisterReferenceExpression(e);
00619 policy.writeRegister(rre->get_descriptor(), value);
00620 break;
00621 }
00622 case V_SgAsmMemoryReferenceExpression: {
00623 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(e)),
00624 readEffectiveAddress(e), value, policy.true_());
00625 break;
00626 }
00627 default: {
00628 fprintf(stderr, "Bad variant %s in write32\n", e->class_name().c_str());
00629 abort();
00630 }
00631 }
00632 }
00633
00634
00635 Word(1) parity(Word(8) w) {
00636 Word(1) p01 = policy.xor_(extract<0, 1>(w), extract<1, 2>(w));
00637 Word(1) p23 = policy.xor_(extract<2, 3>(w), extract<3, 4>(w));
00638 Word(1) p45 = policy.xor_(extract<4, 5>(w), extract<5, 6>(w));
00639 Word(1) p67 = policy.xor_(extract<6, 7>(w), extract<7, 8>(w));
00640 Word(1) p0123 = policy.xor_(p01, p23);
00641 Word(1) p4567 = policy.xor_(p45, p67);
00642 return policy.invert(policy.xor_(p0123, p4567));
00643 }
00644
00645
00646 template <size_t Len>
00647 void setFlagsForResult(const Word(Len)& result) {
00648 writeRegister(REG_PF, parity(extract<0, 8>(result)));
00649 writeRegister(REG_SF, extract<Len - 1, Len>(result));
00650 writeRegister(REG_ZF, policy.equalToZero(result));
00651 }
00652
00653
00654 template <size_t Len>
00655 void setFlagsForResult(const Word(Len)& result, Word(1) cond) {
00656 writeRegister(REG_PF, policy.ite(cond, parity(extract<0, 8>(result)), readRegister<1>(REG_PF)));
00657 writeRegister(REG_SF, policy.ite(cond, extract<Len - 1, Len>(result), readRegister<1>(REG_SF)));
00658 writeRegister(REG_ZF, policy.ite(cond, policy.equalToZero(result), readRegister<1>(REG_ZF)));
00659 }
00660
00661
00662 template <size_t Len>
00663 Word(Len) doAddOperation(const Word(Len)& a, const Word(Len)& b, bool invertCarries, Word(1) carryIn) {
00664 Word(Len) carries = number<Len>(0);
00665 Word(Len) result = policy.addWithCarries(a, b, invertMaybe(carryIn, invertCarries), carries);
00666 setFlagsForResult<Len>(result);
00667 writeRegister(REG_AF, invertMaybe(extract<3, 4>(carries), invertCarries));
00668 writeRegister(REG_CF, invertMaybe(extract<Len - 1, Len>(carries), invertCarries));
00669 writeRegister(REG_OF, policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)));
00670 return result;
00671 }
00672
00673
00674
00675 template <size_t Len>
00676 Word(Len) doAddOperation(const Word(Len)& a, const Word(Len)& b, bool invertCarries, Word(1) carryIn, Word(1) cond) {
00677 Word(Len) carries = number<Len>(0);
00678 Word(Len) result = policy.addWithCarries(a, b, invertMaybe(carryIn, invertCarries), carries);
00679 setFlagsForResult<Len>(result, cond);
00680 writeRegister(REG_AF,
00681 policy.ite(cond,
00682 invertMaybe(extract<3, 4>(carries), invertCarries),
00683 readRegister<1>(REG_AF)));
00684 writeRegister(REG_CF,
00685 policy.ite(cond,
00686 invertMaybe(extract<Len - 1, Len>(carries), invertCarries),
00687 readRegister<1>(REG_CF)));
00688 writeRegister(REG_OF,
00689 policy.ite(cond,
00690 policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)),
00691 readRegister<1>(REG_OF)));
00692 return result;
00693 }
00694
00695
00696 template <size_t Len>
00697 Word(Len) doIncOperation(const Word(Len)& a, bool dec, bool setCarry) {
00698 Word(Len) carries = number<Len>(0);
00699 Word(Len) result = policy.addWithCarries(a, number<Len>(dec ? -1 : 1), policy.false_(), carries);
00700 setFlagsForResult<Len>(result);
00701 writeRegister(REG_AF, invertMaybe(extract<3, 4>(carries), dec));
00702 writeRegister(REG_OF, policy.xor_(extract<Len - 1, Len>(carries), extract<Len - 2, Len - 1>(carries)));
00703 if (setCarry)
00704 writeRegister(REG_CF, invertMaybe(extract<Len - 1, Len>(carries), dec));
00705 return result;
00706 }
00707
00708
00709
00710 #if _MSC_VER
00711
00712
00713 virtual void translate(SgAsmx86Instruction* insn) {
00714 }
00715 #else
00716 virtual void translate(SgAsmx86Instruction* insn) try {
00717 orig_eip = readRegister<32>(REG_EIP);
00718 writeRegister(REG_EIP, policy.add(orig_eip, policy.number<32>(insn->get_size())));
00719 X86InstructionKind kind = insn->get_kind();
00720 const SgAsmExpressionPtrList& operands = insn->get_operandList()->get_operands();
00721 switch (kind) {
00722
00723 case x86_mov: {
00724 if (operands.size()!=2)
00725 throw Exception("instruction must have two operands", insn);
00726 switch (numBytesInAsmType(operands[0]->get_type())) {
00727 case 1: write8(operands[0], read8(operands[1])); break;
00728 case 2: write16(operands[0], read16(operands[1])); break;
00729 case 4: write32(operands[0], read32(operands[1])); break;
00730 default: throw Exception("size not implemented", insn); break;
00731 }
00732 break;
00733 }
00734
00735 case x86_xchg: {
00736 if (operands.size()!=2)
00737 throw Exception("instruction must have two operands", insn);
00738 switch (numBytesInAsmType(operands[0]->get_type())) {
00739 case 1: {
00740 Word(8) temp = read8(operands[1]);
00741 write8(operands[1], read8(operands[0]));
00742 write8(operands[0], temp);
00743 break;
00744 }
00745 case 2: {
00746 Word(16) temp = read16(operands[1]);
00747 write16(operands[1], read16(operands[0]));
00748 write16(operands[0], temp);
00749 break;
00750 }
00751 case 4: {
00752 Word(32) temp = read32(operands[1]);
00753 write32(operands[1], read32(operands[0]));
00754 write32(operands[0], temp);
00755 break;
00756 }
00757 default:
00758 throw Exception("size not implemented", insn);
00759 break;
00760 }
00761 break;
00762 }
00763
00764 case x86_movzx: {
00765 if (operands.size()!=2)
00766 throw Exception("instruction must have two operands", insn);
00767 switch (numBytesInAsmType(operands[0]->get_type())) {
00768 case 2: {
00769 write16(operands[0], policy.concat(read8(operands[1]), number<8>(0)));
00770 break;
00771 }
00772 case 4: {
00773 switch (numBytesInAsmType(operands[1]->get_type())) {
00774 case 1: write32(operands[0], policy.concat(read8(operands[1]), number<24>(0))); break;
00775 case 2: write32(operands[0], policy.concat(read16(operands[1]), number<16>(0))); break;
00776 default: throw Exception("size not implemented", insn);
00777
00778 }
00779 break;
00780 }
00781 default:
00782 throw Exception("size not implemented", insn);
00783 break;
00784 }
00785 break;
00786 }
00787
00788 case x86_movsx: {
00789 if (operands.size()!=2)
00790 throw Exception("instruction must have two operands", insn);
00791 switch (numBytesInAsmType(operands[0]->get_type())) {
00792 case 2: {
00793 Word(8) op1 = read8(operands[1]);
00794 Word(16) result = signExtend<8, 16>(op1);
00795 write16(operands[0], result);
00796 break;
00797 }
00798 case 4: {
00799 switch (numBytesInAsmType(operands[1]->get_type())) {
00800 case 1: {
00801 Word(8) op1 = read8(operands[1]);
00802 Word(32) result = signExtend<8, 32>(op1);
00803 write32(operands[0], result);
00804 break;
00805 }
00806 case 2: {
00807 Word(16) op1 = read16(operands[1]);
00808 Word(32) result = signExtend<16, 32>(op1);
00809 write32(operands[0], result);
00810 break;
00811 }
00812 default:
00813 throw Exception("size not implemented", insn);
00814 }
00815 break;
00816 }
00817 default:
00818 throw Exception("size not implemented", insn);
00819 break;
00820 }
00821 break;
00822 }
00823
00824 case x86_cbw: {
00825 if (operands.size()!=0)
00826 throw Exception("instruction must have no operands", insn);
00827 writeRegister(REG_AX, signExtend<8, 16>(readRegister<8>(REG_AL)));
00828 break;
00829 }
00830
00831 case x86_cwde: {
00832 if (operands.size()!=0)
00833 throw Exception("instruction must have no operands", insn);
00834 writeRegister(REG_EAX, signExtend<16, 32>(readRegister<16>(REG_AX)));
00835 break;
00836 }
00837
00838 case x86_cwd: {
00839 if (operands.size()!=0)
00840 throw Exception("instruction must have no operands", insn);
00841 writeRegister(REG_DX, extract<16, 32>(signExtend<16, 32>(readRegister<16>(REG_AX))));
00842 break;
00843 }
00844
00845 case x86_cdq: {
00846 if (operands.size()!=0)
00847 throw Exception("instruction must have no operands", insn);
00848 writeRegister(REG_EDX, extract<32, 64>(signExtend<32, 64>(readRegister<32>(REG_AX))));
00849 break;
00850 }
00851
00852 case x86_lea: {
00853 if (operands.size()!=2)
00854 throw Exception("instruction must have two operands", insn);
00855 write32(operands[0], readEffectiveAddress(operands[1]));
00856 break;
00857 }
00858
00859 case x86_and: {
00860 if (operands.size()!=2)
00861 throw Exception("instruction must have two operands", insn);
00862 switch (numBytesInAsmType(operands[0]->get_type())) {
00863 case 1: {
00864 Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
00865 setFlagsForResult<8>(result);
00866 write8(operands[0], result);
00867 break;
00868 }
00869 case 2: {
00870 Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
00871 setFlagsForResult<16>(result);
00872 write16(operands[0], result);
00873 break;
00874 }
00875 case 4: {
00876 Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
00877 setFlagsForResult<32>(result);
00878 write32(operands[0], result);
00879 break;
00880 }
00881 default:
00882 throw Exception("size not implemented", insn);
00883 break;
00884 }
00885 writeRegister(REG_OF, policy.false_());
00886 writeRegister(REG_AF, policy.undefined_());
00887 writeRegister(REG_CF, policy.false_());
00888 break;
00889 }
00890
00891 case x86_or: {
00892 if (operands.size()!=2)
00893 throw Exception("instruction must have two operands", insn);
00894 switch (numBytesInAsmType(operands[0]->get_type())) {
00895 case 1: {
00896 Word(8) result = policy.or_(read8(operands[0]), read8(operands[1]));
00897 setFlagsForResult<8>(result);
00898 write8(operands[0], result);
00899 break;
00900 }
00901 case 2: {
00902 Word(16) result = policy.or_(read16(operands[0]), read16(operands[1]));
00903 setFlagsForResult<16>(result);
00904 write16(operands[0], result);
00905 break;
00906 }
00907 case 4: {
00908 Word(32) result = policy.or_(read32(operands[0]), read32(operands[1]));
00909 setFlagsForResult<32>(result);
00910 write32(operands[0], result);
00911 break;
00912 }
00913 default:
00914 throw Exception("size not implemented", insn);
00915 break;
00916 }
00917 writeRegister(REG_OF, policy.false_());
00918 writeRegister(REG_AF, policy.undefined_());
00919 writeRegister(REG_CF, policy.false_());
00920 break;
00921 }
00922
00923 case x86_test: {
00924 if (operands.size()!=2)
00925 throw Exception("instruction must have two operands", insn);
00926 switch (numBytesInAsmType(operands[0]->get_type())) {
00927 case 1: {
00928 Word(8) result = policy.and_(read8(operands[0]), read8(operands[1]));
00929 setFlagsForResult<8>(result);
00930 break;
00931 }
00932 case 2: {
00933 Word(16) result = policy.and_(read16(operands[0]), read16(operands[1]));
00934 setFlagsForResult<16>(result);
00935 break;
00936 }
00937 case 4: {
00938 Word(32) result = policy.and_(read32(operands[0]), read32(operands[1]));
00939 setFlagsForResult<32>(result);
00940 break;
00941 }
00942 default:
00943 throw Exception("size not implemented", insn);
00944 break;
00945 }
00946 writeRegister(REG_OF, policy.false_());
00947 writeRegister(REG_AF, policy.undefined_());
00948 writeRegister(REG_CF, policy.false_());
00949 break;
00950 }
00951
00952 case x86_xor: {
00953 if (operands.size()!=2)
00954 throw Exception("instruction must have two operands", insn);
00955 switch (numBytesInAsmType(operands[0]->get_type())) {
00956 case 1: {
00957 Word(8) result = policy.xor_(read8(operands[0]), read8(operands[1]));
00958 setFlagsForResult<8>(result);
00959 write8(operands[0], result);
00960 break;
00961 }
00962 case 2: {
00963 Word(16) result = policy.xor_(read16(operands[0]), read16(operands[1]));
00964 setFlagsForResult<16>(result);
00965 write16(operands[0], result);
00966 break;
00967 }
00968 case 4: {
00969 Word(32) result = policy.xor_(read32(operands[0]), read32(operands[1]));
00970 setFlagsForResult<32>(result);
00971 write32(operands[0], result);
00972 break;
00973 }
00974 default:
00975 throw Exception("size not implemented", insn);
00976 break;
00977 }
00978 writeRegister(REG_OF, policy.false_());
00979 writeRegister(REG_AF, policy.undefined_());
00980 writeRegister(REG_CF, policy.false_());
00981 break;
00982 }
00983
00984 case x86_not: {
00985 if (operands.size()!=1)
00986 throw Exception("instruction must have one operand", insn);
00987 switch (numBytesInAsmType(operands[0]->get_type())) {
00988 case 1: {
00989 Word(8) result = policy.invert(read8(operands[0]));
00990 write8(operands[0], result);
00991 break;
00992 }
00993 case 2: {
00994 Word(16) result = policy.invert(read16(operands[0]));
00995 write16(operands[0], result);
00996 break;
00997 }
00998 case 4: {
00999 Word(32) result = policy.invert(read32(operands[0]));
01000 write32(operands[0], result);
01001 break;
01002 }
01003 default:
01004 throw Exception("size not implemented", insn);
01005 break;
01006 }
01007 break;
01008 }
01009
01010 case x86_xadd: {
01011 if (operands.size()!=2)
01012 throw Exception("instruction must have two operands", insn);
01013 switch (numBytesInAsmType(operands[0]->get_type())) {
01014 case 1: {
01015 Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false, policy.false_());
01016 write8(operands[1], read8(operands[0]));
01017 write8(operands[0], result);
01018 break;
01019 }
01020 case 2: {
01021 Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false, policy.false_());
01022 write16(operands[1], read16(operands[0]));
01023 write16(operands[0], result);
01024 break;
01025 }
01026 case 4: {
01027 Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false, policy.false_());
01028 write32(operands[1], read32(operands[0]));
01029 write32(operands[0], result);
01030 break;
01031 }
01032 default:
01033 throw Exception("size not implemented", insn);
01034 break;
01035 }
01036 break;
01037 }
01038
01039 case x86_add: {
01040 if (operands.size()!=2)
01041 throw Exception("instruction must have two operands", insn);
01042 switch (numBytesInAsmType(operands[0]->get_type())) {
01043 case 1: {
01044 Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false, policy.false_());
01045 write8(operands[0], result);
01046 break;
01047 }
01048 case 2: {
01049 Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false, policy.false_());
01050 write16(operands[0], result);
01051 break;
01052 }
01053 case 4: {
01054 Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false, policy.false_());
01055 write32(operands[0], result);
01056 break;
01057 }
01058 default:
01059 throw Exception("size not implemented", insn);
01060 break;
01061 }
01062 break;
01063 }
01064
01065 case x86_adc: {
01066 if (operands.size()!=2)
01067 throw Exception("instruction must have two operands", insn);
01068 switch (numBytesInAsmType(operands[0]->get_type())) {
01069 case 1: {
01070 Word(8) result = doAddOperation<8>(read8(operands[0]), read8(operands[1]), false,
01071 readRegister<1>(REG_CF));
01072 write8(operands[0], result);
01073 break;
01074 }
01075 case 2: {
01076 Word(16) result = doAddOperation<16>(read16(operands[0]), read16(operands[1]), false,
01077 readRegister<1>(REG_CF));
01078 write16(operands[0], result);
01079 break;
01080 }
01081 case 4: {
01082 Word(32) result = doAddOperation<32>(read32(operands[0]), read32(operands[1]), false,
01083 readRegister<1>(REG_CF));
01084 write32(operands[0], result);
01085 break;
01086 }
01087 default:
01088 throw Exception("size not implemented", insn);
01089 break;
01090 }
01091 break;
01092 }
01093
01094 case x86_sub: {
01095 if (operands.size()!=2)
01096 throw Exception("instruction must have two operands", insn);
01097 switch (numBytesInAsmType(operands[0]->get_type())) {
01098 case 1: {
01099 Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
01100 policy.false_());
01101 write8(operands[0], result);
01102 break;
01103 }
01104 case 2: {
01105 Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
01106 policy.false_());
01107 write16(operands[0], result);
01108 break;
01109 }
01110 case 4: {
01111 Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
01112 policy.false_());
01113 write32(operands[0], result);
01114 break;
01115 }
01116 default:
01117 throw Exception("size not implemented", insn);
01118 break;
01119 }
01120 break;
01121 }
01122
01123 case x86_sbb: {
01124 if (operands.size()!=2)
01125 throw Exception("instruction must have two operands", insn);
01126 switch (numBytesInAsmType(operands[0]->get_type())) {
01127 case 1: {
01128 Word(8) result = doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true,
01129 readRegister<1>(REG_CF));
01130 write8(operands[0], result);
01131 break;
01132 }
01133 case 2: {
01134 Word(16) result = doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true,
01135 readRegister<1>(REG_CF));
01136 write16(operands[0], result);
01137 break;
01138 }
01139 case 4: {
01140 Word(32) result = doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true,
01141 readRegister<1>(REG_CF));
01142 write32(operands[0], result);
01143 break;
01144 }
01145 default:
01146 throw Exception("size not implemented", insn);
01147 break;
01148 }
01149 break;
01150 }
01151
01152 case x86_cmp: {
01153 if (operands.size()!=2)
01154 throw Exception("instruction must have two operands", insn);
01155 switch (numBytesInAsmType(operands[0]->get_type())) {
01156 case 1: {
01157 doAddOperation<8>(read8(operands[0]), policy.invert(read8(operands[1])), true, policy.false_());
01158 break;
01159 }
01160 case 2: {
01161 doAddOperation<16>(read16(operands[0]), policy.invert(read16(operands[1])), true, policy.false_());
01162 break;
01163 }
01164 case 4: {
01165 doAddOperation<32>(read32(operands[0]), policy.invert(read32(operands[1])), true, policy.false_());
01166 break;
01167 }
01168 default:
01169 throw Exception("size not implemented", insn);
01170 break;
01171 }
01172 break;
01173 }
01174
01175 case x86_neg: {
01176 if (operands.size()!=1)
01177 throw Exception("instruction must have one operand", insn);
01178 switch (numBytesInAsmType(operands[0]->get_type())) {
01179 case 1: {
01180 Word(8) result = doAddOperation<8>(number<8>(0), policy.invert(read8(operands[0])), true,
01181 policy.false_());
01182 write8(operands[0], result);
01183 break;
01184 }
01185 case 2: {
01186 Word(16) result = doAddOperation<16>(number<16>(0), policy.invert(read16(operands[0])), true,
01187 policy.false_());
01188 write16(operands[0], result);
01189 break;
01190 }
01191 case 4: {
01192 Word(32) result = doAddOperation<32>(number<32>(0), policy.invert(read32(operands[0])), true,
01193 policy.false_());
01194 write32(operands[0], result);
01195 break;
01196 }
01197 default:
01198 throw Exception("size not implemented", insn);
01199 break;
01200 }
01201 break;
01202 }
01203
01204 case x86_inc: {
01205 if (operands.size()!=1)
01206 throw Exception("instruction must have one operand", insn);
01207 switch (numBytesInAsmType(operands[0]->get_type())) {
01208 case 1: {
01209 Word(8) result = doIncOperation<8>(read8(operands[0]), false, false);
01210 write8(operands[0], result);
01211 break;
01212 }
01213 case 2: {
01214 Word(16) result = doIncOperation<16>(read16(operands[0]), false, false);
01215 write16(operands[0], result);
01216 break;
01217 }
01218 case 4: {
01219 Word(32) result = doIncOperation<32>(read32(operands[0]), false, false);
01220 write32(operands[0], result);
01221 break;
01222 }
01223 default:
01224 throw Exception("size not implemented", insn);
01225 break;
01226 }
01227 break;
01228 }
01229
01230 case x86_dec: {
01231 if (operands.size()!=1)
01232 throw Exception("instruction must have one operand", insn);
01233 switch (numBytesInAsmType(operands[0]->get_type())) {
01234 case 1: {
01235 Word(8) result = doIncOperation<8>(read8(operands[0]), true, false);
01236 write8(operands[0], result);
01237 break;
01238 }
01239 case 2: {
01240 Word(16) result = doIncOperation<16>(read16(operands[0]), true, false);
01241 write16(operands[0], result);
01242 break;
01243 }
01244 case 4: {
01245 Word(32) result = doIncOperation<32>(read32(operands[0]), true, false);
01246 write32(operands[0], result);
01247 break;
01248 }
01249 default:
01250 throw Exception("size not implemented", insn);
01251 break;
01252 }
01253 break;
01254 }
01255
01256 case x86_cmpxchg: {
01257 if (operands.size()!=2)
01258 throw Exception("instruction must have two operands", insn);
01259 switch (numBytesInAsmType(operands[0]->get_type())) {
01260 case 1: {
01261 Word(8) op0 = read8(operands[0]);
01262 Word(8) oldAx = readRegister<8>(REG_AL);
01263 doAddOperation<8>(oldAx, policy.invert(op0), true, policy.false_());
01264 write8(operands[0], policy.ite(readRegister<1>(REG_ZF), read8(operands[1]), op0));
01265 writeRegister(REG_AL, policy.ite(readRegister<1>(REG_ZF), oldAx, op0));
01266 break;
01267 }
01268 case 2: {
01269 Word(16) op0 = read16(operands[0]);
01270 Word(16) oldAx = readRegister<16>(REG_AX);
01271 doAddOperation<16>(oldAx, policy.invert(op0), true, policy.false_());
01272 write16(operands[0], policy.ite(readRegister<1>(REG_ZF), read16(operands[1]), op0));
01273 writeRegister(REG_AX, policy.ite(readRegister<1>(REG_ZF), oldAx, op0));
01274 break;
01275 }
01276 case 4: {
01277 Word(32) op0 = read32(operands[0]);
01278 Word(32) oldAx = readRegister<32>(REG_EAX);
01279 doAddOperation<32>(oldAx, policy.invert(op0), true, policy.false_());
01280 write32(operands[0], policy.ite(readRegister<1>(REG_ZF), read32(operands[1]), op0));
01281 writeRegister(REG_EAX, policy.ite(readRegister<1>(REG_ZF), oldAx, op0));
01282 break;
01283 }
01284 default:
01285 throw Exception("size not implemented", insn);
01286 break;
01287 }
01288 break;
01289 }
01290
01291 case x86_shl:
01292 case x86_sar:
01293 case x86_shr: {
01294 switch (numBytesInAsmType(operands[0]->get_type())) {
01295 case 1: {
01296 WordType<8> output = shift_semantics<8, 5>(kind, read8(operands[0]), read8(operands[1]));
01297 write8(operands[0], output);
01298 break;
01299 }
01300 case 2: {
01301 WordType<16> output = shift_semantics<16, 5>(kind, read16(operands[0]), read8(operands[1]));
01302 write16(operands[0], output);
01303 break;
01304 }
01305 case 4: {
01306 WordType<32> output = shift_semantics<32, 5>(kind, read32(operands[0]), read8(operands[1]));
01307 write32(operands[0], output);
01308 break;
01309 }
01310 default:
01311 throw Exception("size not implemented", insn);
01312 }
01313 break;
01314 }
01315
01316 case x86_rol: {
01317 switch (numBytesInAsmType(operands[0]->get_type())) {
01318 case 1: {
01319 Word(8) op = read8(operands[0]);
01320 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01321 Word(8) output = policy.rotateLeft(op, shiftCount);
01322 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01323 readRegister<1>(REG_CF),
01324 extract<0, 1>(output)));
01325 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01326 readRegister<1>(REG_OF),
01327 policy.xor_(extract<0, 1>(output), extract<7, 8>(output))));
01328 write8(operands[0], output);
01329 break;
01330 }
01331 case 2: {
01332 Word(16) op = read16(operands[0]);
01333 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01334 Word(16) output = policy.rotateLeft(op, shiftCount);
01335 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01336 readRegister<1>(REG_CF),
01337 extract<0, 1>(output)));
01338 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01339 readRegister<1>(REG_OF),
01340 policy.xor_(extract<0, 1>(output), extract<15, 16>(output))));
01341 write16(operands[0], output);
01342 break;
01343 }
01344 case 4: {
01345 Word(32) op = read32(operands[0]);
01346 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01347 Word(32) output = policy.rotateLeft(op, shiftCount);
01348 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01349 readRegister<1>(REG_CF),
01350 extract<0, 1>(output)));
01351 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01352 readRegister<1>(REG_OF),
01353 policy.xor_(extract<0, 1>(output), extract<31, 32>(output))));
01354 write32(operands[0], output);
01355 break;
01356 }
01357 default:
01358 throw Exception("size not implemented", insn);
01359 }
01360 break;
01361 }
01362
01363 case x86_ror: {
01364 switch (numBytesInAsmType(operands[0]->get_type())) {
01365 case 1: {
01366 Word(8) op = read8(operands[0]);
01367 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01368 Word(8) output = policy.rotateRight(op, shiftCount);
01369 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01370 readRegister<1>(REG_CF),
01371 extract<7, 8>(output)));
01372 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01373 readRegister<1>(REG_OF),
01374 policy.xor_(extract<6, 7>(output), extract<7, 8>(output))));
01375 write8(operands[0], output);
01376 break;
01377 }
01378 case 2: {
01379 Word(16) op = read16(operands[0]);
01380 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01381 Word(16) output = policy.rotateRight(op, shiftCount);
01382 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01383 readRegister<1>(REG_CF),
01384 extract<15, 16>(output)));
01385 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01386 readRegister<1>(REG_OF),
01387 policy.xor_(extract<14, 15>(output), extract<15, 16>(output))));
01388 write16(operands[0], output);
01389 break;
01390 }
01391 case 4: {
01392 Word(32) op = read32(operands[0]);
01393 Word(5) shiftCount = extract<0, 5>(read8(operands[1]));
01394 Word(32) output = policy.rotateRight(op, shiftCount);
01395 writeRegister(REG_CF, policy.ite(policy.equalToZero(shiftCount),
01396 readRegister<1>(REG_CF),
01397 extract<31, 32>(output)));
01398 writeRegister(REG_OF, policy.ite(policy.equalToZero(shiftCount),
01399 readRegister<1>(REG_OF),
01400 policy.xor_(extract<30, 31>(output), extract<31, 32>(output))));
01401 write32(operands[0], output);
01402 break;
01403 }
01404 default:
01405 throw Exception("size not implemented", insn);
01406 }
01407 break;
01408 }
01409
01410 case x86_shld: {
01411 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
01412 switch (numBytesInAsmType(operands[0]->get_type())) {
01413 case 2: {
01414 Word(16) op1 = read16(operands[0]);
01415 Word(16) op2 = read16(operands[1]);
01416 Word(16) output1 = policy.shiftLeft(op1, shiftCount);
01417 Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
01418 number<16>(0),
01419 policy.shiftRight(op2, policy.negate(shiftCount)));
01420 Word(16) output = policy.or_(output1, output2);
01421 Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
01422 readRegister<1>(REG_CF),
01423 extract<15, 16>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(15)))));
01424 writeRegister(REG_CF, newCf);
01425 Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
01426 readRegister<1>(REG_OF),
01427 policy.xor_(extract<15, 16>(output), newCf));
01428 writeRegister(REG_OF, newOf);
01429 write16(operands[0], output);
01430 setFlagsForResult<16>(output);
01431 writeRegister(REG_AF, policy.ite(policy.equalToZero(shiftCount),
01432 readRegister<1>(REG_AF),
01433 policy.undefined_()));
01434 break;
01435 }
01436 case 4: {
01437 Word(32) op1 = read32(operands[0]);
01438 Word(32) op2 = read32(operands[1]);
01439 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
01440 Word(32) output1 = policy.shiftLeft(op1, shiftCount);
01441 Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
01442 number<32>(0),
01443 policy.shiftRight(op2, policy.negate(shiftCount)));
01444 Word(32) output = policy.or_(output1, output2);
01445 Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
01446 readRegister<1>(REG_CF),
01447 extract<31, 32>(policy.shiftLeft(op1, policy.add(shiftCount, number<5>(31)))));
01448 writeRegister(REG_CF, newCf);
01449 Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
01450 readRegister<1>(REG_OF),
01451 policy.xor_(extract<31, 32>(output), newCf));
01452 writeRegister(REG_OF, newOf);
01453 write32(operands[0], output);
01454 setFlagsForResult<32>(output);
01455 writeRegister(REG_AF, policy.ite(policy.equalToZero(shiftCount),
01456 readRegister<1>(REG_AF),
01457 policy.undefined_()));
01458 break;
01459 }
01460 default:
01461 throw Exception("size not implemented", insn);
01462 }
01463 break;
01464 }
01465
01466 case x86_shrd: {
01467 Word(5) shiftCount = extract<0, 5>(read8(operands[2]));
01468 switch (numBytesInAsmType(operands[0]->get_type())) {
01469 case 2: {
01470 Word(16) op1 = read16(operands[0]);
01471 Word(16) op2 = read16(operands[1]);
01472 Word(16) output1 = policy.shiftRight(op1, shiftCount);
01473 Word(16) output2 = policy.ite(policy.equalToZero(shiftCount),
01474 number<16>(0),
01475 policy.shiftLeft(op2, policy.negate(shiftCount)));
01476 Word(16) output = policy.or_(output1, output2);
01477 Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
01478 readRegister<1>(REG_CF),
01479 extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(15)))));
01480 writeRegister(REG_CF, newCf);
01481 Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
01482 readRegister<1>(REG_OF),
01483 policy.xor_(extract<15, 16>(output),
01484 extract<15, 16>(op1)));
01485 writeRegister(REG_OF, newOf);
01486 write16(operands[0], output);
01487 setFlagsForResult<16>(output);
01488 writeRegister(REG_AF, policy.ite(policy.equalToZero(shiftCount),
01489 readRegister<1>(REG_AF),
01490 policy.undefined_()));
01491 break;
01492 }
01493 case 4: {
01494 Word(32) op1 = read32(operands[0]);
01495 Word(32) op2 = read32(operands[1]);
01496 Word(32) output1 = policy.shiftRight(op1, shiftCount);
01497 Word(32) output2 = policy.ite(policy.equalToZero(shiftCount),
01498 number<32>(0),
01499 policy.shiftLeft(op2, policy.negate(shiftCount)));
01500 Word(32) output = policy.or_(output1, output2);
01501 Word(1) newCf = policy.ite(policy.equalToZero(shiftCount),
01502 readRegister<1>(REG_CF),
01503 extract<0, 1>(policy.shiftRight(op1, policy.add(shiftCount, number<5>(31)))));
01504 writeRegister(REG_CF, newCf);
01505 Word(1) newOf = policy.ite(policy.equalToZero(shiftCount),
01506 readRegister<1>(REG_OF),
01507 policy.xor_(extract<31, 32>(output),
01508 extract<31, 32>(op1)));
01509 writeRegister(REG_OF, newOf);
01510 write32(operands[0], output);
01511 setFlagsForResult<32>(output);
01512 writeRegister(REG_AF, policy.ite(policy.equalToZero(shiftCount),
01513 readRegister<1>(REG_AF),
01514 policy.undefined_()));
01515 break;
01516 }
01517 default:
01518 throw Exception("size not implemented", insn);
01519 }
01520 break;
01521 }
01522
01523 case x86_bsf: {
01524 writeRegister(REG_OF, policy.undefined_());
01525 writeRegister(REG_SF, policy.undefined_());
01526 writeRegister(REG_AF, policy.undefined_());
01527 writeRegister(REG_PF, policy.undefined_());
01528 writeRegister(REG_CF, policy.undefined_());
01529 switch (numBytesInAsmType(operands[0]->get_type())) {
01530 case 2: {
01531 Word(16) op = read16(operands[1]);
01532 writeRegister(REG_ZF, policy.equalToZero(op));
01533 Word(16) result = policy.ite(readRegister<1>(REG_ZF),
01534 read16(operands[0]),
01535 policy.leastSignificantSetBit(op));
01536 write16(operands[0], result);
01537 break;
01538 }
01539 case 4: {
01540 Word(32) op = read32(operands[1]);
01541 writeRegister(REG_ZF, policy.equalToZero(op));
01542 Word(32) result = policy.ite(readRegister<1>(REG_ZF),
01543 read32(operands[0]),
01544 policy.leastSignificantSetBit(op));
01545 write32(operands[0], result);
01546 break;
01547 }
01548 default:
01549 throw Exception("size not implemented", insn);
01550 }
01551 break;
01552 }
01553
01554 case x86_bsr: {
01555 writeRegister(REG_OF, policy.undefined_());
01556 writeRegister(REG_SF, policy.undefined_());
01557 writeRegister(REG_AF, policy.undefined_());
01558 writeRegister(REG_PF, policy.undefined_());
01559 writeRegister(REG_CF, policy.undefined_());
01560 switch (numBytesInAsmType(operands[0]->get_type())) {
01561 case 2: {
01562 Word(16) op = read16(operands[1]);
01563 writeRegister(REG_ZF, policy.equalToZero(op));
01564 Word(16) result = policy.ite(readRegister<1>(REG_ZF),
01565 read16(operands[0]),
01566 policy.mostSignificantSetBit(op));
01567 write16(operands[0], result);
01568 break;
01569 }
01570 case 4: {
01571 Word(32) op = read32(operands[1]);
01572 writeRegister(REG_ZF, policy.equalToZero(op));
01573 Word(32) result = policy.ite(readRegister<1>(REG_ZF),
01574 read32(operands[0]),
01575 policy.mostSignificantSetBit(op));
01576 write32(operands[0], result);
01577 break;
01578 }
01579 default:
01580 throw Exception("size not implemented", insn);
01581 }
01582 break;
01583 }
01584
01585 case x86_bt: {
01586 if (operands.size()!=2)
01587 throw Exception("instruction must have two operands", insn);
01588
01589
01590 writeRegister(REG_OF, policy.undefined_());
01591 writeRegister(REG_SF, policy.undefined_());
01592 writeRegister(REG_ZF, policy.undefined_());
01593 writeRegister(REG_AF, policy.undefined_());
01594 writeRegister(REG_PF, policy.undefined_());
01595
01596 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
01597
01598 Word(32) addr = readEffectiveAddress(operands[0]);
01599 int numBytes = numBytesInAsmType(operands[1]->get_type());
01600 Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
01601 Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
01602 Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
01603 adjustedAddr, policy.true_());
01604 Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
01605 writeRegister(REG_CF, bitval);
01606 } else {
01607
01608 switch (numBytesInAsmType(operands[0]->get_type())) {
01609 case 2: {
01610 Word(16) op0 = read16(operands[0]);
01611 Word(4) bitnum = extract<0, 4>(read16(operands[1]));
01612 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01613 writeRegister(REG_CF, bitval);
01614 break;
01615 }
01616 case 4: {
01617 Word(32) op0 = read32(operands[0]);
01618 Word(5) bitnum = extract<0, 5>(read32(operands[1]));
01619 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01620 writeRegister(REG_CF, bitval);
01621 break;
01622 }
01623 default:
01624 throw Exception("size not implemented", insn);
01625 }
01626 }
01627 break;
01628 }
01629
01630 case x86_btr: {
01631 if (operands.size()!=2)
01632 throw Exception("instruction must have two operands", insn);
01633
01634
01635 writeRegister(REG_OF, policy.undefined_());
01636 writeRegister(REG_SF, policy.undefined_());
01637 writeRegister(REG_ZF, policy.undefined_());
01638 writeRegister(REG_AF, policy.undefined_());
01639 writeRegister(REG_PF, policy.undefined_());
01640
01641 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
01642
01643 Word(32) addr = readEffectiveAddress(operands[0]);
01644 int numBytes = numBytesInAsmType(operands[1]->get_type());
01645 Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
01646 Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
01647 Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
01648 adjustedAddr, policy.true_());
01649 Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
01650 Word(8) result = policy.and_(val,
01651 policy.invert(policy.rotateLeft(number<8>(1),
01652 extract<0, 3>(bitnum))));
01653 writeRegister(REG_CF, bitval);
01654 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
01655 adjustedAddr, result, policy.true_());
01656 } else {
01657
01658 switch (numBytesInAsmType(operands[0]->get_type())) {
01659 case 2: {
01660 Word(16) op0 = read16(operands[0]);
01661 Word(4) bitnum = extract<0, 4>(read16(operands[1]));
01662 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01663 Word(16) result = policy.and_(op0, policy.invert(policy.rotateLeft(number<16>(1), bitnum)));
01664 writeRegister(REG_CF, bitval);
01665 write16(operands[0], result);
01666 break;
01667 }
01668 case 4: {
01669 Word(32) op0 = read32(operands[0]);
01670 Word(5) bitnum = extract<0, 5>(read32(operands[1]));
01671 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01672 Word(32) result = policy.and_(op0, policy.invert(policy.rotateLeft(number<32>(1), bitnum)));
01673 writeRegister(REG_CF, bitval);
01674 write32(operands[0], result);
01675 break;
01676 }
01677 default:
01678 throw Exception("size not implemented", insn);
01679 }
01680 }
01681 break;
01682 }
01683
01684 case x86_bts: {
01685 if (operands.size()!=2)
01686 throw Exception("instruction must have two operands", insn);
01687
01688
01689 writeRegister(REG_OF, policy.undefined_());
01690 writeRegister(REG_SF, policy.undefined_());
01691 writeRegister(REG_ZF, policy.undefined_());
01692 writeRegister(REG_AF, policy.undefined_());
01693 writeRegister(REG_PF, policy.undefined_());
01694
01695 if (isSgAsmMemoryReferenceExpression(operands[0]) && isSgAsmx86RegisterReferenceExpression(operands[1])) {
01696
01697 Word(32) addr = readEffectiveAddress(operands[0]);
01698 int numBytes = numBytesInAsmType(operands[1]->get_type());
01699 Word(32) bitnum = numBytes == 2 ? signExtend<16, 32>(read16(operands[1])) : read32(operands[1]);
01700 Word(32) adjustedAddr = policy.add(addr, signExtend<29, 32>(extract<3, 32>(bitnum)));
01701 Word(8) val = readMemory<8>(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
01702 adjustedAddr, policy.true_());
01703 Word(1) bitval = extract<0, 1>(policy.rotateRight(val, extract<0, 3>(bitnum)));
01704 Word(8) result = policy.or_(val, policy.rotateLeft(number<8>(1), extract<0, 3>(bitnum)));
01705 writeRegister(REG_CF, bitval);
01706 policy.writeMemory(getSegregFromMemoryReference(isSgAsmMemoryReferenceExpression(operands[0])),
01707 adjustedAddr, result, policy.true_());
01708 } else {
01709
01710 switch (numBytesInAsmType(operands[0]->get_type())) {
01711 case 2: {
01712 Word(16) op0 = read16(operands[0]);
01713 Word(4) bitnum = extract<0, 4>(read16(operands[1]));
01714 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01715 Word(16) result = policy.or_(op0, policy.rotateLeft(number<16>(1), bitnum));
01716 writeRegister(REG_CF, bitval);
01717 write16(operands[0], result);
01718 break;
01719 }
01720 case 4: {
01721 Word(32) op0 = read32(operands[0]);
01722 Word(5) bitnum = extract<0, 5>(read32(operands[1]));
01723 Word(1) bitval = extract<0, 1>(policy.rotateRight(op0, bitnum));
01724 Word(32) result = policy.or_(op0, policy.rotateLeft(number<32>(1), bitnum));
01725 writeRegister(REG_CF, bitval);
01726 write32(operands[0], result);
01727 break;
01728 }
01729 default:
01730 throw Exception("size not implemented", insn);
01731 }
01732 }
01733 break;
01734 }
01735
01736 case x86_imul: {
01737 switch (numBytesInAsmType(operands[0]->get_type())) {
01738 case 1: {
01739 Word(8) op0 = readRegister<8>(REG_AL);
01740 Word(8) op1 = read8(operands[0]);
01741 Word(16) mulResult = policy.signedMultiply(op0, op1);
01742 writeRegister(REG_AX, mulResult);
01743 Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 16>(mulResult))),
01744 policy.equalToZero(extract<7, 16>(mulResult))));
01745 writeRegister(REG_CF, carry);
01746 writeRegister(REG_OF, carry);
01747 break;
01748 }
01749 case 2: {
01750 Word(16) op0 = operands.size() == 1 ?
01751 readRegister<16>(REG_AX) :
01752 read16(operands[operands.size() - 2]);
01753 Word(16) op1 = read16(operands[operands.size() - 1]);
01754 Word(32) mulResult = policy.signedMultiply(op0, op1);
01755 if (operands.size() == 1) {
01756 writeRegister(REG_AX, extract<0, 16>(mulResult));
01757 writeRegister(REG_DX, extract<16, 32>(mulResult));
01758 } else {
01759 write16(operands[0], extract<0, 16>(mulResult));
01760 }
01761 Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 32>(mulResult))),
01762 policy.equalToZero(extract<7, 32>(mulResult))));
01763 writeRegister(REG_CF, carry);
01764 writeRegister(REG_OF, carry);
01765 break;
01766 }
01767 case 4: {
01768 Word(32) op0 = operands.size() == 1 ?
01769 readRegister<32>(REG_EAX) :
01770 read32(operands[operands.size() - 2]);
01771 Word(32) op1 = read32(operands[operands.size() - 1]);
01772 Word(64) mulResult = policy.signedMultiply(op0, op1);
01773 if (operands.size() == 1) {
01774 writeRegister(REG_EAX, extract<0, 32>(mulResult));
01775 writeRegister(REG_EDX, extract<32, 64>(mulResult));
01776 } else {
01777 write32(operands[0], extract<0, 32>(mulResult));
01778 }
01779 Word(1) carry = policy.invert(policy.or_(policy.equalToZero(policy.invert(extract<7, 64>(mulResult))),
01780 policy.equalToZero(extract<7, 64>(mulResult))));
01781 writeRegister(REG_CF, carry);
01782 writeRegister(REG_OF, carry);
01783 break;
01784 }
01785 default:
01786 throw Exception("size not implemented", insn);
01787 }
01788 writeRegister(REG_SF, policy.undefined_());
01789 writeRegister(REG_ZF, policy.undefined_());
01790 writeRegister(REG_AF, policy.undefined_());
01791 writeRegister(REG_PF, policy.undefined_());
01792 break;
01793 }
01794
01795 case x86_mul: {
01796 switch (numBytesInAsmType(operands[0]->get_type())) {
01797 case 1: {
01798 Word(8) op0 = readRegister<8>(REG_AL);
01799 Word(8) op1 = read8(operands[0]);
01800 Word(16) mulResult = policy.unsignedMultiply(op0, op1);
01801 writeRegister(REG_AX, mulResult);
01802 Word(1) carry = policy.invert(policy.equalToZero(extract<8, 16>(mulResult)));
01803 writeRegister(REG_CF, carry);
01804 writeRegister(REG_OF, carry);
01805 break;
01806 }
01807 case 2: {
01808 Word(16) op0 = readRegister<16>(REG_AX);
01809 Word(16) op1 = read16(operands[0]);
01810 Word(32) mulResult = policy.unsignedMultiply(op0, op1);
01811 writeRegister(REG_AX, extract<0, 16>(mulResult));
01812 writeRegister(REG_DX, extract<16, 32>(mulResult));
01813 Word(1) carry = policy.invert(policy.equalToZero(extract<16, 32>(mulResult)));
01814 writeRegister(REG_CF, carry);
01815 writeRegister(REG_OF, carry);
01816 break;
01817 }
01818 case 4: {
01819 Word(32) op0 = readRegister<32>(REG_EAX);
01820 Word(32) op1 = read32(operands[0]);
01821 Word(64) mulResult = policy.unsignedMultiply(op0, op1);
01822 writeRegister(REG_EAX, extract<0, 32>(mulResult));
01823 writeRegister(REG_EDX, extract<32, 64>(mulResult));
01824 Word(1) carry = policy.invert(policy.equalToZero(extract<32, 64>(mulResult)));
01825 writeRegister(REG_CF, carry);
01826 writeRegister(REG_OF, carry);
01827 break;
01828 }
01829 default:
01830 throw Exception("size not implemented", insn);
01831 }
01832 writeRegister(REG_SF, policy.undefined_());
01833 writeRegister(REG_ZF, policy.undefined_());
01834 writeRegister(REG_AF, policy.undefined_());
01835 writeRegister(REG_PF, policy.undefined_());
01836 break;
01837 }
01838
01839 case x86_idiv: {
01840 switch (numBytesInAsmType(operands[0]->get_type())) {
01841 case 1: {
01842 Word(16) op0 = readRegister<16>(REG_AX);
01843 Word(8) op1 = read8(operands[0]);
01844
01845 Word(16) divResult = policy.signedDivide(op0, op1);
01846 Word(8) modResult = policy.signedModulo(op0, op1);
01847
01848 writeRegister(REG_AX, policy.concat(extract<0, 8>(divResult), modResult));
01849 break;
01850 }
01851 case 2: {
01852 Word(32) op0 = policy.concat(readRegister<16>(REG_AX), readRegister<16>(REG_DX));
01853 Word(16) op1 = read16(operands[0]);
01854
01855 Word(32) divResult = policy.signedDivide(op0, op1);
01856 Word(16) modResult = policy.signedModulo(op0, op1);
01857
01858 writeRegister(REG_AX, extract<0, 16>(divResult));
01859 writeRegister(REG_DX, modResult);
01860 break;
01861 }
01862 case 4: {
01863 Word(64) op0 = policy.concat(readRegister<32>(REG_EAX), readRegister<32>(REG_EDX));
01864 Word(32) op1 = read32(operands[0]);
01865
01866 Word(64) divResult = policy.signedDivide(op0, op1);
01867 Word(32) modResult = policy.signedModulo(op0, op1);
01868
01869 writeRegister(REG_EAX, extract<0, 32>(divResult));
01870 writeRegister(REG_EDX, modResult);
01871 break;
01872 }
01873 default:
01874 throw Exception("size not implemented", insn);
01875 }
01876 writeRegister(REG_SF, policy.undefined_());
01877 writeRegister(REG_ZF, policy.undefined_());
01878 writeRegister(REG_AF, policy.undefined_());
01879 writeRegister(REG_PF, policy.undefined_());
01880 writeRegister(REG_CF, policy.undefined_());
01881 writeRegister(REG_OF, policy.undefined_());
01882 break;
01883 }
01884
01885 case x86_div: {
01886 switch (numBytesInAsmType(operands[0]->get_type())) {
01887 case 1: {
01888 Word(16) op0 = readRegister<16>(REG_AX);
01889 Word(8) op1 = read8(operands[0]);
01890
01891 Word(16) divResult = policy.unsignedDivide(op0, op1);
01892 Word(8) modResult = policy.unsignedModulo(op0, op1);
01893
01894 writeRegister(REG_AX, policy.concat(extract<0, 8>(divResult), modResult));
01895 break;
01896 }
01897 case 2: {
01898 Word(32) op0 = policy.concat(readRegister<16>(REG_AX), readRegister<16>(REG_DX));
01899 Word(16) op1 = read16(operands[0]);
01900
01901 Word(32) divResult = policy.unsignedDivide(op0, op1);
01902 Word(16) modResult = policy.unsignedModulo(op0, op1);
01903
01904 writeRegister(REG_AX, extract<0, 16>(divResult));
01905 writeRegister(REG_DX, modResult);
01906 break;
01907 }
01908 case 4: {
01909 Word(64) op0 = policy.concat(readRegister<32>(REG_EAX), readRegister<32>(REG_EDX));
01910 Word(32) op1 = read32(operands[0]);
01911
01912 Word(64) divResult = policy.unsignedDivide(op0, op1);
01913 Word(32) modResult = policy.unsignedModulo(op0, op1);
01914
01915 writeRegister(REG_EAX, extract<0, 32>(divResult));
01916 writeRegister(REG_EDX, modResult);
01917 break;
01918 }
01919 default:
01920 throw Exception("size not implemented", insn);
01921 }
01922 writeRegister(REG_SF, policy.undefined_());
01923 writeRegister(REG_ZF, policy.undefined_());
01924 writeRegister(REG_AF, policy.undefined_());
01925 writeRegister(REG_PF, policy.undefined_());
01926 writeRegister(REG_CF, policy.undefined_());
01927 writeRegister(REG_OF, policy.undefined_());
01928 break;
01929 }
01930
01931 case x86_aaa: {
01932 if (operands.size()!=0)
01933 throw Exception("instruction must have no operands", insn);
01934 Word(1) incAh = policy.or_(readRegister<1>(REG_AF),
01935 greaterOrEqualToTen(extract<0, 4>(readRegister<8>(REG_AL))));
01936 writeRegister(REG_AX,
01937 policy.concat(policy.add(policy.ite(incAh, number<4>(6), number<4>(0)),
01938 extract<0, 4>(readRegister<8>(REG_AL))),
01939 policy.concat(number<4>(0),
01940 policy.add(policy.ite(incAh, number<8>(1), number<8>(0)),
01941 readRegister<8>(REG_AH)))));
01942 writeRegister(REG_OF, policy.undefined_());
01943 writeRegister(REG_SF, policy.undefined_());
01944 writeRegister(REG_ZF, policy.undefined_());
01945 writeRegister(REG_PF, policy.undefined_());
01946 writeRegister(REG_AF, incAh);
01947 writeRegister(REG_CF, incAh);
01948 break;
01949 }
01950
01951 case x86_aas: {
01952 if (operands.size()!=0)
01953 throw Exception("instruction must have no operands", insn);
01954 Word(1) decAh = policy.or_(readRegister<1>(REG_AF),
01955 greaterOrEqualToTen(extract<0, 4>(readRegister<8>(REG_AL))));
01956 writeRegister(REG_AX,
01957 policy.concat(policy.add(policy.ite(decAh, number<4>(-6), number<4>(0)),
01958 extract<0, 4>(readRegister<8>(REG_AL))),
01959 policy.concat(number<4>(0),
01960 policy.add(policy.ite(decAh, number<8>(-1), number<8>(0)),
01961 readRegister<8>(REG_AH)))));
01962 writeRegister(REG_OF, policy.undefined_());
01963 writeRegister(REG_SF, policy.undefined_());
01964 writeRegister(REG_ZF, policy.undefined_());
01965 writeRegister(REG_PF, policy.undefined_());
01966 writeRegister(REG_AF, decAh);
01967 writeRegister(REG_CF, decAh);
01968 break;
01969 }
01970
01971 case x86_aam: {
01972 if (operands.size()!=1)
01973 throw Exception("instruction must have one operand", insn);
01974 Word(8) al = readRegister<8>(REG_AL);
01975 Word(8) divisor = read8(operands[0]);
01976 Word(8) newAh = policy.unsignedDivide(al, divisor);
01977 Word(8) newAl = policy.unsignedModulo(al, divisor);
01978 writeRegister(REG_AX, policy.concat(newAl, newAh));
01979 writeRegister(REG_OF, policy.undefined_());
01980 writeRegister(REG_AF, policy.undefined_());
01981 writeRegister(REG_CF, policy.undefined_());
01982 setFlagsForResult<8>(newAl);
01983 break;
01984 }
01985
01986 case x86_aad: {
01987 if (operands.size()!=1)
01988 throw Exception("instruction must have one operand", insn);
01989 Word(8) al = readRegister<8>(REG_AL);
01990 Word(8) ah = readRegister<8>(REG_AH);
01991 Word(8) divisor = read8(operands[0]);
01992 Word(8) newAl = policy.add(al, extract<0, 8>(policy.unsignedMultiply(ah, divisor)));
01993 writeRegister(REG_AX, policy.concat(newAl, number<8>(0)));
01994 writeRegister(REG_OF, policy.undefined_());
01995 writeRegister(REG_AF, policy.undefined_());
01996 writeRegister(REG_CF, policy.undefined_());
01997 setFlagsForResult<8>(newAl);
01998 break;
01999 }
02000
02001 case x86_bswap: {
02002 if (operands.size()!=1)
02003 throw Exception("instruction must have one operand", insn);
02004 Word(32) oldVal = read32(operands[0]);
02005 Word(32) newVal = policy.concat(extract<24, 32>(oldVal),
02006 policy.concat(extract<16, 24>(oldVal),
02007 policy.concat(extract<8, 16>(oldVal),
02008 extract<0, 8>(oldVal))));
02009 write32(operands[0], newVal);
02010 break;
02011 }
02012
02013 case x86_push: {
02014 if (operands.size()!=1)
02015 throw Exception("instruction must have one operand", insn);
02016 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02017 throw Exception("size not implemented", insn);
02018 Word(32) oldSp = readRegister<32>(REG_ESP);
02019 Word(32) newSp = policy.add(oldSp, number<32>(-4));
02020 policy.writeMemory(x86_segreg_ss, newSp, read32(operands[0]), policy.true_());
02021 writeRegister(REG_ESP, newSp);
02022 break;
02023 }
02024
02025 case x86_pushad: {
02026 if (operands.size()!=0)
02027 throw Exception("instruction must have no operands", insn);
02028 if (insn->get_addressSize() != x86_insnsize_32)
02029 throw Exception("size not implemented", insn);
02030 Word(32) oldSp = readRegister<32>(REG_ESP);
02031 Word(32) newSp = policy.add(oldSp, number<32>(-32));
02032 policy.writeMemory(x86_segreg_ss, newSp,
02033 readRegister<32>(REG_EDI), policy.true_());
02034 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(4)),
02035 readRegister<32>(REG_ESI), policy.true_());
02036 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(8)),
02037 readRegister<32>(REG_EBP), policy.true_());
02038 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(12)),
02039 oldSp, policy.true_());
02040 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(16)),
02041 readRegister<32>(REG_EBX), policy.true_());
02042 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(20)),
02043 readRegister<32>(REG_EDX), policy.true_());
02044 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(24)),
02045 readRegister<32>(REG_ECX), policy.true_());
02046 policy.writeMemory(x86_segreg_ss, policy.add(newSp, number<32>(28)),
02047 readRegister<32>(REG_EAX), policy.true_());
02048 writeRegister(REG_ESP, newSp);
02049 break;
02050 }
02051
02052 case x86_pushfd: {
02053 if (operands.size()!=0)
02054 throw Exception("instruction must have no operands", insn);
02055 if (insn->get_addressSize() != x86_insnsize_32)
02056 throw Exception("size not implemented", insn);
02057 Word(32) oldSp = readRegister<32>(REG_ESP);
02058 Word(32) newSp = policy.add(oldSp, number<32>(-4));
02059 policy.writeMemory(x86_segreg_ss, newSp, readRegister<32>(REG_EFLAGS), policy.true_());
02060 writeRegister(REG_ESP, newSp);
02061 break;
02062 }
02063
02064 case x86_pop: {
02065 if (operands.size()!=1)
02066 throw Exception("instruction must have one operand", insn);
02067 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02068 throw Exception("size not implemented", insn);
02069 Word(32) oldSp = readRegister<32>(REG_ESP);
02070 Word(32) newSp = policy.add(oldSp, number<32>(4));
02071 writeRegister(REG_ESP, newSp);
02072 write32(operands[0], readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
02073 break;
02074 }
02075
02076 case x86_popad: {
02077 if (operands.size()!=0)
02078 throw Exception("instruction must have no operands", insn);
02079 if (insn->get_addressSize() != x86_insnsize_32)
02080 throw Exception("size not implemented", insn);
02081 Word(32) oldSp = readRegister<32>(REG_ESP);
02082 Word(32) newSp = policy.add(oldSp, number<32>(32));
02083 writeRegister(REG_EDI, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
02084 writeRegister(REG_ESI, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(4)), policy.true_()));
02085 writeRegister(REG_EBP, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(8)), policy.true_()));
02086 writeRegister(REG_EBX, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(16)), policy.true_()));
02087 writeRegister(REG_EDX, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(20)), policy.true_()));
02088 writeRegister(REG_ECX, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(24)), policy.true_()));
02089 writeRegister(REG_EAX, readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(28)), policy.true_()));
02090 readMemory<32>(x86_segreg_ss, policy.add(oldSp, number<32>(12)), policy.true_());
02091 writeRegister(REG_ESP, newSp);
02092 break;
02093 }
02094
02095 case x86_leave: {
02096 if (operands.size()!=0)
02097 throw Exception("instruction must have no operands", insn);
02098 writeRegister(REG_ESP, readRegister<32>(REG_EBP));
02099 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02100 throw Exception("size not implemented", insn);
02101 Word(32) oldSp = readRegister<32>(REG_ESP);
02102 Word(32) newSp = policy.add(oldSp, number<32>(4));
02103 writeRegister(REG_EBP, readMemory<32>(x86_segreg_ss, oldSp, policy.true_()));
02104 writeRegister(REG_ESP, newSp);
02105 break;
02106 }
02107
02108 case x86_call: {
02109 if (operands.size()!=1)
02110 throw Exception("instruction must have one operand", insn);
02111 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02112 throw Exception("size not implemented", insn);
02113 Word(32) oldSp = readRegister<32>(REG_ESP);
02114 Word(32) newSp = policy.add(oldSp, number<32>(-4));
02115 policy.writeMemory(x86_segreg_ss, newSp, readRegister<32>(REG_EIP), policy.true_());
02116 writeRegister(REG_EIP, policy.filterCallTarget(read32(operands[0])));
02117 writeRegister(REG_ESP, newSp);
02118 break;
02119 }
02120
02121 case x86_ret: {
02122 if (operands.size()>1)
02123 throw Exception("instruction must have zero or one operand", insn);
02124 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02125 throw Exception("size not implemented", insn);
02126 Word(32) extraBytes = (operands.size() == 1 ? read32(operands[0]) : number<32>(0));
02127 Word(32) oldSp = readRegister<32>(REG_ESP);
02128 Word(32) newSp = policy.add(oldSp, policy.add(number<32>(4), extraBytes));
02129 writeRegister(REG_EIP, policy.filterReturnTarget(readMemory<32>(x86_segreg_ss, oldSp, policy.true_())));
02130 writeRegister(REG_ESP, newSp);
02131 break;
02132 }
02133
02134 case x86_loop: {
02135 if (operands.size()!=1)
02136 throw Exception("instruction must have one operand", insn);
02137 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02138 throw Exception("size not implemented", insn);
02139 Word(32) oldCx = readRegister<32>(REG_ECX);
02140 Word(32) newCx = policy.add(number<32>(-1), oldCx);
02141 writeRegister(REG_ECX, newCx);
02142 Word(1) doLoop = policy.invert(policy.equalToZero(newCx));
02143 writeRegister(REG_EIP, policy.ite(doLoop, read32(operands[0]), readRegister<32>(REG_EIP)));
02144 break;
02145 }
02146 case x86_loopz: {
02147 if (operands.size()!=1)
02148 throw Exception("instruction must have one operand", insn);
02149 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02150 throw Exception("size not implemented", insn);
02151 Word(32) oldCx = readRegister<32>(REG_ECX);
02152 Word(32) newCx = policy.add(number<32>(-1), oldCx);
02153 writeRegister(REG_ECX, newCx);
02154 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)), readRegister<1>(REG_ZF));
02155 writeRegister(REG_EIP, policy.ite(doLoop, read32(operands[0]), readRegister<32>(REG_EIP)));
02156 break;
02157 }
02158 case x86_loopnz: {
02159 if (operands.size()!=1)
02160 throw Exception("instruction must have one operand", insn);
02161 if (insn->get_addressSize() != x86_insnsize_32 || insn->get_operandSize() != x86_insnsize_32)
02162 throw Exception("size not implemented", insn);
02163 Word(32) oldCx = readRegister<32>(REG_ECX);
02164 Word(32) newCx = policy.add(number<32>(-1), oldCx);
02165 writeRegister(REG_ECX, newCx);
02166 Word(1) doLoop = policy.and_(policy.invert(policy.equalToZero(newCx)),
02167 policy.invert(readRegister<1>(REG_ZF)));
02168 writeRegister(REG_EIP, policy.ite(doLoop, read32(operands[0]), readRegister<32>(REG_EIP)));
02169 break;
02170 }
02171
02172 case x86_jmp: {
02173 if (operands.size()!=1)
02174 throw Exception("instruction must have one operand", insn);
02175 writeRegister(REG_EIP, policy.filterIndirectJumpTarget(read32(operands[0])));
02176 break;
02177 }
02178
02179
02180
02181 # define FLAGCOMBO_ne policy.invert(readRegister<1>(REG_ZF))
02182 # define FLAGCOMBO_e readRegister<1>(REG_ZF)
02183 # define FLAGCOMBO_no policy.invert(readRegister<1>(REG_OF))
02184 # define FLAGCOMBO_o readRegister<1>(REG_OF)
02185 # define FLAGCOMBO_ns policy.invert(readRegister<1>(REG_SF))
02186 # define FLAGCOMBO_s readRegister<1>(REG_SF)
02187 # define FLAGCOMBO_po policy.invert(readRegister<1>(REG_PF))
02188 # define FLAGCOMBO_pe readRegister<1>(REG_PF)
02189 # define FLAGCOMBO_ae policy.invert(readRegister<1>(REG_CF))
02190 # define FLAGCOMBO_b readRegister<1>(REG_CF)
02191 # define FLAGCOMBO_be policy.or_(FLAGCOMBO_b, FLAGCOMBO_e)
02192 # define FLAGCOMBO_a policy.and_(FLAGCOMBO_ae, FLAGCOMBO_ne)
02193 # define FLAGCOMBO_l policy.xor_(readRegister<1>(REG_SF), readRegister<1>(REG_OF))
02194 # define FLAGCOMBO_ge policy.invert(policy.xor_(readRegister<1>(REG_SF), readRegister<1>(REG_OF)))
02195 # define FLAGCOMBO_le policy.or_(FLAGCOMBO_e, FLAGCOMBO_l)
02196 # define FLAGCOMBO_g policy.and_(FLAGCOMBO_ge, FLAGCOMBO_ne)
02197 # define FLAGCOMBO_cxz policy.equalToZero(readRegister<16>(REG_CX))
02198 # define FLAGCOMBO_ecxz policy.equalToZero(readRegister<32>(REG_ECX))
02199
02200 # define JUMP(tag) { \
02201 if (operands.size()!=1) \
02202 throw Exception("instruction must have one operand", insn); \
02203 writeRegister(REG_EIP, policy.ite(FLAGCOMBO_##tag, \
02204 read32(operands[0]), \
02205 readRegister<32>(REG_EIP))); \
02206 }
02207 case x86_jne: JUMP(ne); break;
02208 case x86_je: JUMP(e); break;
02209 case x86_jno: JUMP(no); break;
02210 case x86_jo: JUMP(o); break;
02211 case x86_jpo: JUMP(po); break;
02212 case x86_jpe: JUMP(pe); break;
02213 case x86_jns: JUMP(ns); break;
02214 case x86_js: JUMP(s); break;
02215 case x86_jae: JUMP(ae); break;
02216 case x86_jb: JUMP(b); break;
02217 case x86_jbe: JUMP(be); break;
02218 case x86_ja: JUMP(a); break;
02219 case x86_jle: JUMP(le); break;
02220 case x86_jg: JUMP(g); break;
02221 case x86_jge: JUMP(ge); break;
02222 case x86_jl: JUMP(l); break;
02223 case x86_jcxz: JUMP(cxz); break;
02224 case x86_jecxz: JUMP(ecxz); break;
02225 # undef JUMP
02226
02227 # define SET(tag) { \
02228 if (operands.size()!=1) \
02229 throw Exception("instruction must have one operand", insn); \
02230 write8(operands[0], policy.concat(FLAGCOMBO_##tag, number<7>(0))); \
02231 }
02232 case x86_setne: SET(ne); break;
02233 case x86_sete: SET(e); break;
02234 case x86_setno: SET(no); break;
02235 case x86_seto: SET(o); break;
02236 case x86_setpo: SET(po); break;
02237 case x86_setpe: SET(pe); break;
02238 case x86_setns: SET(ns); break;
02239 case x86_sets: SET(s); break;
02240 case x86_setae: SET(ae); break;
02241 case x86_setb: SET(b); break;
02242 case x86_setbe: SET(be); break;
02243 case x86_seta: SET(a); break;
02244 case x86_setle: SET(le); break;
02245 case x86_setg: SET(g); break;
02246 case x86_setge: SET(ge); break;
02247 case x86_setl: SET(l); break;
02248 # undef SET
02249
02250 # define CMOV(tag) { \
02251 if (operands.size()!=2) \
02252 throw Exception("instruction must have two operands", insn); \
02253 switch (numBytesInAsmType(operands[0]->get_type())) { \
02254 case 2: write16(operands[0], policy.ite(FLAGCOMBO_##tag, read16(operands[1]), read16(operands[0]))); break; \
02255 case 4: write32(operands[0], policy.ite(FLAGCOMBO_##tag, read32(operands[1]), read32(operands[0]))); break; \
02256 default: throw Exception("size not implemented", insn); \
02257 \
02258 } \
02259 }
02260 case x86_cmovne: CMOV(ne); break;
02261 case x86_cmove: CMOV(e); break;
02262 case x86_cmovno: CMOV(no); break;
02263 case x86_cmovo: CMOV(o); break;
02264 case x86_cmovpo: CMOV(po); break;
02265 case x86_cmovpe: CMOV(pe); break;
02266 case x86_cmovns: CMOV(ns); break;
02267 case x86_cmovs: CMOV(s); break;
02268 case x86_cmovae: CMOV(ae); break;
02269 case x86_cmovb: CMOV(b); break;
02270 case x86_cmovbe: CMOV(be); break;
02271 case x86_cmova: CMOV(a); break;
02272 case x86_cmovle: CMOV(le); break;
02273 case x86_cmovg: CMOV(g); break;
02274 case x86_cmovge: CMOV(ge); break;
02275 case x86_cmovl: CMOV(l); break;
02276 # undef CMOV
02277
02278
02279 # undef FLAGCOMBO_ne
02280 # undef FLAGCOMBO_e
02281 # undef FLAGCOMBO_ns
02282 # undef FLAGCOMBO_s
02283 # undef FLAGCOMBO_ae
02284 # undef FLAGCOMBO_b
02285 # undef FLAGCOMBO_be
02286 # undef FLAGCOMBO_a
02287 # undef FLAGCOMBO_l
02288 # undef FLAGCOMBO_ge
02289 # undef FLAGCOMBO_le
02290 # undef FLAGCOMBO_g
02291 # undef FLAGCOMBO_cxz
02292 # undef FLAGCOMBO_ecxz
02293
02294 case x86_cld: {
02295 if (operands.size()!=0)
02296 throw Exception("instruction must have no operands", insn);
02297 writeRegister(REG_DF, policy.false_());
02298 break;
02299 }
02300
02301 case x86_std: {
02302 if (operands.size()!=0)
02303 throw Exception("instruction must have no operands", insn);
02304 writeRegister(REG_DF, policy.true_());
02305 break;
02306 }
02307
02308 case x86_clc: {
02309 if (operands.size()!=0)
02310 throw Exception("instruction must have no operands", insn);
02311 writeRegister(REG_CF, policy.false_());
02312 break;
02313 }
02314
02315 case x86_stc: {
02316 if (operands.size()!=0)
02317 throw Exception("instruction must have no operands", insn);
02318 writeRegister(REG_CF, policy.true_());
02319 break;
02320 }
02321
02322 case x86_cmc: {
02323 if (operands.size()!=0)
02324 throw Exception("instruction must have no operands", insn);
02325 writeRegister(REG_CF, policy.invert(readRegister<1>(REG_CF)));
02326 break;
02327 }
02328
02329 case x86_nop:
02330 break;
02331
02332
02333 case x86_repne_scasb: repne_scas_semantics<1>(insn); break;
02334 case x86_repne_scasw: repne_scas_semantics<2>(insn); break;
02335 case x86_repne_scasd: repne_scas_semantics<4>(insn); break;
02336 case x86_repe_scasb: repe_scas_semantics<1>(insn); break;
02337 case x86_repe_scasw: repe_scas_semantics<2>(insn); break;
02338 case x86_repe_scasd: repe_scas_semantics<4>(insn); break;
02339
02340 case x86_scasb: scas_semantics<1>(insn, policy.true_()); break;
02341 case x86_scasw: scas_semantics<2>(insn, policy.true_()); break;
02342 case x86_scasd: scas_semantics<4>(insn, policy.true_()); break;
02343
02344 case x86_repne_cmpsb: repne_cmps_semantics<1>(insn); break;
02345 case x86_repne_cmpsw: repne_cmps_semantics<2>(insn); break;
02346 case x86_repne_cmpsd: repne_cmps_semantics<4>(insn); break;
02347 case x86_repe_cmpsb: repe_cmps_semantics<1>(insn); break;
02348 case x86_repe_cmpsw: repe_cmps_semantics<2>(insn); break;
02349 case x86_repe_cmpsd: repe_cmps_semantics<4>(insn); break;
02350
02351 case x86_cmpsb: cmps_semantics<1>(insn, policy.true_()); break;
02352 case x86_cmpsw: cmps_semantics<2>(insn, policy.true_()); break;
02353 case x86_cmpsd:
02354
02355
02356
02357
02358 if (0==operands.size()) {
02359 cmps_semantics<4>(insn, policy.true_()); break;
02360 } else {
02361
02362 throw Exception("instruction not implemented", insn);
02363 }
02364 break;
02365
02366 case x86_movsb: movs_semantics<1>(insn, policy.true_()); break;
02367 case x86_movsw: movs_semantics<2>(insn, policy.true_()); break;
02368 case x86_movsd: movs_semantics<4>(insn, policy.true_()); break;
02369
02370 case x86_rep_movsb: rep_movs_semantics<1>(insn); break;
02371 case x86_rep_movsw: rep_movs_semantics<2>(insn); break;
02372 case x86_rep_movsd: rep_movs_semantics<4>(insn); break;
02373
02374 case x86_stosb: stos_semantics<1>(insn, policy.true_()); break;
02375 case x86_stosw: stos_semantics<2>(insn, policy.true_()); break;
02376 case x86_stosd: stos_semantics<4>(insn, policy.true_()); break;
02377
02378 case x86_rep_stosb: rep_stos_semantics<1>(insn); break;
02379 case x86_rep_stosw: rep_stos_semantics<2>(insn); break;
02380 case x86_rep_stosd: rep_stos_semantics<4>(insn); break;
02381
02382 case x86_lodsb: lods_semantics<1>(insn); break;
02383 case x86_lodsw: lods_semantics<2>(insn); break;
02384 case x86_lodsd: lods_semantics<4>(insn); break;
02385
02386 case x86_hlt: {
02387 if (operands.size()!=0)
02388 throw Exception("instruction must have no operands", insn);
02389 policy.hlt();
02390 writeRegister(REG_EIP, orig_eip);
02391 break;
02392 }
02393
02394 case x86_cpuid: {
02395 if (operands.size()!=0)
02396 throw Exception("instruction must have no operands", insn);
02397 policy.cpuid();
02398 break;
02399 }
02400
02401 case x86_rdtsc: {
02402 if (operands.size()!=0)
02403 throw Exception("instruction must have no operands", insn);
02404 Word(64) tsc = policy.rdtsc();
02405 writeRegister(REG_EAX, extract<0, 32>(tsc));
02406 writeRegister(REG_EDX, extract<32, 64>(tsc));
02407 break;
02408 }
02409
02410 case x86_int: {
02411 if (operands.size()!=1)
02412 throw Exception("instruction must have one operand", insn);
02413 SgAsmByteValueExpression* bv = isSgAsmByteValueExpression(operands[0]);
02414 if (!bv)
02415 throw Exception("operand must be a byte value expression", insn);
02416 policy.interrupt(bv->get_value());
02417 break;
02418 }
02419
02420
02421 case x86_fnstcw: {
02422 if (operands.size()!=1)
02423 throw Exception("instruction must have one operand", insn);
02424 write16(operands[0], number<16>(0x37f));
02425 break;
02426 }
02427
02428 case x86_fldcw: {
02429 if (operands.size()!=1)
02430 throw Exception("instruction must have one operand", insn);
02431 read16(operands[0]);
02432 break;
02433 }
02434
02435 case x86_sysenter: {
02436 if (operands.size()!=0)
02437 throw Exception("instruction must have no operands", insn);
02438 policy.sysenter();
02439 break;
02440 }
02441
02442 default: {
02443 throw Exception("instruction not implemented", insn);
02444 break;
02445 }
02446 }
02447 } catch(Exception e) {
02448 if (!e.insn)
02449 e.insn = insn;
02450 throw e;
02451 }
02452 #endif
02453
02454 void processInstruction(SgAsmx86Instruction* insn) {
02455 ROSE_ASSERT(insn);
02456 current_instruction = insn;
02457 policy.startInstruction(insn);
02458 translate(insn);
02459 policy.finishInstruction(insn);
02460 }
02461
02462 void processBlock(const SgAsmStatementPtrList& stmts, size_t begin, size_t end) {
02463 if (begin == end) return;
02464 policy.startBlock(stmts[begin]->get_address());
02465 for (size_t i = begin; i < end; ++i) {
02466 processInstruction(isSgAsmx86Instruction(stmts[i]));
02467 }
02468 policy.finishBlock(stmts[begin]->get_address());
02469 }
02470
02471 static bool isRepeatedStringOp(SgAsmStatement* s) {
02472 SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
02473 if (!insn) return false;
02474 switch (insn->get_kind()) {
02475 case x86_repe_cmpsb: return true;
02476 case x86_repe_cmpsd: return true;
02477 case x86_repe_cmpsq: return true;
02478 case x86_repe_cmpsw: return true;
02479 case x86_repe_scasb: return true;
02480 case x86_repe_scasd: return true;
02481 case x86_repe_scasq: return true;
02482 case x86_repe_scasw: return true;
02483 case x86_rep_insb: return true;
02484 case x86_rep_insd: return true;
02485 case x86_rep_insw: return true;
02486 case x86_rep_lodsb: return true;
02487 case x86_rep_lodsd: return true;
02488 case x86_rep_lodsq: return true;
02489 case x86_rep_lodsw: return true;
02490 case x86_rep_movsb: return true;
02491 case x86_rep_movsd: return true;
02492 case x86_rep_movsq: return true;
02493 case x86_rep_movsw: return true;
02494 case x86_repne_cmpsb: return true;
02495 case x86_repne_cmpsd: return true;
02496 case x86_repne_cmpsq: return true;
02497 case x86_repne_cmpsw: return true;
02498 case x86_repne_scasb: return true;
02499 case x86_repne_scasd: return true;
02500 case x86_repne_scasq: return true;
02501 case x86_repne_scasw: return true;
02502 case x86_rep_outsb: return true;
02503 case x86_rep_outsd: return true;
02504 case x86_rep_outsw: return true;
02505 case x86_rep_stosb: return true;
02506 case x86_rep_stosd: return true;
02507 case x86_rep_stosq: return true;
02508 case x86_rep_stosw: return true;
02509 default: return false;
02510 }
02511 }
02512
02513 static bool isHltOrInt(SgAsmStatement* s) {
02514 SgAsmx86Instruction* insn = isSgAsmx86Instruction(s);
02515 if (!insn) return false;
02516 switch (insn->get_kind()) {
02517 case x86_hlt: return true;
02518 case x86_int: return true;
02519 default: return false;
02520 }
02521 }
02522
02523 void processBlock(SgAsmBlock* b) {
02524 const SgAsmStatementPtrList& stmts = b->get_statementList();
02525 if (stmts.empty()) return;
02526 if (!isSgAsmInstruction(stmts[0])) return;
02527 size_t i = 0;
02528 while (i < stmts.size()) {
02529 size_t oldI = i;
02530
02531 while (i < stmts.size() && !isRepeatedStringOp(stmts[i]) && (i == oldI || !isHltOrInt(stmts[i - 1]))) ++i;
02532 processBlock(stmts, oldI, i);
02533 if (i >= stmts.size()) break;
02534 if (isRepeatedStringOp(stmts[i])) {
02535 processBlock(stmts, i, i + 1);
02536 ++i;
02537 }
02538 ROSE_ASSERT(i != oldI);
02539 }
02540 }
02541
02542 };
02543
02544 #undef Word
02545
02546 }
02547 }
02548 #endif