Index: vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp (working copy) @@ -102,6 +102,7 @@ Constraint Constraint::getAliasConstraint(OpndSize s, uint32 offset)const { OpndSize sz=(OpndSize)size; + OpndExt e = (OpndExt)ext; if (s==OpndSize_Default){ s=getDefaultSize(kind); if (s==OpndSize_Any) @@ -134,7 +135,7 @@ newMask=mask; } if (newMask==0) newKind&=~OpndKind_Reg; - return newKind==OpndKind_Null?Constraint():Constraint( (OpndKind)newKind, s, newMask); + return newKind==OpndKind_Null?Constraint():Constraint( (OpndKind)newKind, s, e, newMask); } //_________________________________________________________________________________________________ Index: vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h (working copy) @@ -72,7 +72,7 @@ For OpndKind_Reg and sub-kinds initializes the mask field to 0xffff */ Constraint(OpndKind k) - :mask(OpndKind_Reg&k?0xffff:0), size(OpndSize_Any), kind(k) + :mask(OpndKind_Reg&k?0xffff:0), size(OpndSize_Any), ext(OpndExt_None), kind(k) { assert(k!=OpndKind_Null); } /** Creates a constraint of the specified OpndKind k and OpndSize s @@ -82,17 +82,27 @@ If k contains OpndKind_Reg the constructor initializes the mask field to 0xffff */ Constraint(OpndKind k, OpndSize s) - :mask(OpndKind_Reg&k?0xffff:0), size(s), kind(k) + :mask(OpndKind_Reg&k?0xffff:0), size(s), ext(OpndExt_None), kind(k) { assert(k!=OpndKind_Null && size!=OpndSize_Null); } - /** Creates a constraint of the specified OpndKind, OpndSize, and register mask m + /** Creates a constraint of the specified OpndKind k, OpndSize s and OpndExt e + Both k and s cannot be _Null. + + If k contains OpndKind_Reg the constructor initializes the mask field to 0xffff + */ + Constraint(OpndKind k, OpndSize s, OpndExt e) + :mask(OpndKind_Reg&k?0xffff:0), size(s), ext(e), kind(k) + { assert(k!=OpndKind_Null && size!=OpndSize_Null); } + + /** Creates a constraint of the specified OpndKind, OpndSize, OpndExt and register mask m + Both k and s cannot be _Null, and k must contain be OpndKind_Reg if mask is not null For OpndKind_Reg and sub-kinds initializes the mask field to 0xffff */ - Constraint(OpndKind k, OpndSize s, uint32 m) - :mask(m), size(s), kind(k) + Constraint(OpndKind k, OpndSize s, OpndExt e, uint32 m) + :mask(m), size(s), ext(e), kind(k) { assert(k!=OpndKind_Null && size!=OpndSize_Null); assert(mask==0||(OpndKind_Reg&k)!=0); } /** Creates a constraint corresponding to the specified physical register RegName @@ -103,8 +113,8 @@ The mask field of the constraint is initialized to the mask corresponding to the specified register */ - Constraint(RegName reg) - :mask(getRegMask(reg)), size(getRegSize(reg)), kind(getRegKind(reg)) {} + Constraint(RegName reg, OpndExt e = OpndExt_None) + :mask(getRegMask(reg)), size(getRegSize(reg)), ext(e), kind(getRegKind(reg)) {} Constraint(const char * str){ fullValue = 0; str=parse(str); assert(str!=NULL); } @@ -119,6 +129,9 @@ /** returns the mask field of the constraint */ uint32 getMask()const{ return mask; } + /** reurns the ext field of the constraint */ + OpndExt getExt()const {return (OpndExt)ext; } + /** sets the mask field of the constraint */ void setMask(uint32 m){ mask=m; } @@ -217,7 +230,8 @@ union{ struct { uint32 mask:16; - uint32 size:8; + uint32 size:6; + uint32 ext:2; uint32 kind:8; }; uint32 fullValue; Index: vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp (working copy) @@ -99,16 +99,16 @@ switch(regKind) { case OpndKind_GPReg: return Constraint(OpndKind_GPReg, - Constraint::getDefaultSize(OpndKind_GPReg), 0xff); + Constraint::getDefaultSize(OpndKind_GPReg), OpndExt_None, 0xff); case OpndKind_XMMReg: return Constraint(OpndKind_XMMReg, - Constraint::getDefaultSize(OpndKind_XMMReg), 0xff); + Constraint::getDefaultSize(OpndKind_XMMReg), OpndExt_None, 0xff); case OpndKind_FPReg: return Constraint(OpndKind_FPReg, - Constraint::getDefaultSize(OpndKind_FPReg), 0x1); + Constraint::getDefaultSize(OpndKind_FPReg), OpndExt_None, 0x1); case OpndKind_StatusReg: return Constraint(OpndKind_StatusReg, - Constraint::getDefaultSize(OpndKind_StatusReg), 0x1); + Constraint::getDefaultSize(OpndKind_StatusReg), OpndExt_None, 0x1); default: break; } @@ -129,14 +129,6 @@ }; //_________________________________________________________________________________________________ -bool Encoder::matches(Constraint co, Constraint ci, uint32 opndRoles, - bool allowAliases) -{ - return co.isNull() || !(ci&co).isNull() || - (allowAliases && !(ci.getAliasConstraint(co.getSize())&co).isNull()); -} - -//_________________________________________________________________________________________________ const Encoder::OpcodeGroup * Encoder::findOpcodeGroup(const FindInfo& fi) { @@ -178,10 +170,7 @@ } for (uint32 i = 0, n = fi.opndCount; i < n; i++) { uint32 idx = fi.isExtended ? og->extendedToNativeMap[i] : i; - Constraint co=fi.opndConstraints[idx]; - if (any) { - co = Constraint(OpndKind_Any, co.getSize()); - } + Constraint co = fi.opndConstraints[idx]; if (!isOpndAllowed(og, i, co, fi.isExtended, any)) return false; } @@ -189,6 +178,29 @@ } //_________________________________________________________________________________________________ +bool Encoder::matches(Constraint co, Constraint ci) +{ + Constraint cc = ci&co; + return co.isNull() || (!cc.isNull() && (ci.getExt() == OpndExt_None || cc.getExt() != OpndExt_None)); +} + +Constraint +Encoder::expandImmediate(Constraint co) { + assert(co.getKind() == OpndKind_Imm); + OpndSize newSize = OpndSize_Null; + switch (co.getSize()) { + case OpndSize_8: + newSize = OpndSize_16; + break; + case OpndSize_16: + newSize = OpndSize_32; + break; + default:; + } + return newSize == OpndSize_Null ? Constraint() : + Constraint((OpndKind)co.getKind(), newSize, co.getExt(), co.getMask()); +} +//_________________________________________________________________________________________________ bool Encoder::isOpndAllowed(const Encoder::OpcodeGroup * og, uint32 i, Constraint co, bool isExtended, bool any) { @@ -197,10 +209,22 @@ Constraint ci=og->opndConstraints[idx]; - if (!matches(co, ci, Encoder::getOpndRoles(og->opndRoles,idx), any && (!(Encoder::getOpndRoles(og->opndRoles,idx)&Inst::OpndRole_Def) || getBaseConditionMnemonic(og->mnemonic) == Mnemonic_SETcc))) { - return false; + assert(!ci.isNull()); + + // Strict matching + if (matches(co, ci)) { + return true; } - return true; + + // Try to match with extended immediate. + if (any && co.getKind() == OpndKind_Imm) { + while (!(co = expandImmediate(co)).isNull()) { + if (matches(co, ci)) { + return true; + } + } + } + return false; } //_________________________________________________________________________________________________ @@ -223,7 +247,7 @@ switch( c.getKind() ) { case OpndKind_Imm: - args.add(EncoderBase::Operand(sz, p->getImmValue())); + args.add(EncoderBase::Operand(sz, p->getImmValue(), c.getExt())); break; case OpndKind_Mem: { @@ -329,8 +353,8 @@ if(!((Constraint)og.opndConstraints[j]).canBeMergedWith(od.opndConstraints[j])) return false; - Constraint ogConstr = ((Constraint)og.opndConstraints[j]).intersectWith(Constraint((OpndKind)(OpndKind_Reg|OpndKind_Imm),OpndSize_Any,0xFFFF)); - Constraint odConstr = ((Constraint)od.opndConstraints[j]).intersectWith(Constraint((OpndKind)(OpndKind_Reg|OpndKind_Imm),OpndSize_Any,0xFFFF)); + Constraint ogConstr = ((Constraint)og.opndConstraints[j]).intersectWith(Constraint((OpndKind)(OpndKind_Reg|OpndKind_Imm), OpndSize_Any, OpndExt_Any, 0xFFFF)); + Constraint odConstr = ((Constraint)od.opndConstraints[j]).intersectWith(Constraint((OpndKind)(OpndKind_Reg|OpndKind_Imm), OpndSize_Any, OpndExt_Any, 0xFFFF)); Constraint::CompareResult compareResult = ogConstr.compare(odConstr); @@ -419,12 +443,14 @@ for (unsigned k=0; kopnds[k].reg != RegName_Null) { // exact Register specified - od.opndConstraints[k] = Constraint(opcode->opnds[k].reg); + od.opndConstraints[k] = Constraint(opcode->opnds[k].reg, opcode->opnds[k].ext); } else { - od.opndConstraints[k] = Constraint(opcode->opnds[k].kind, - opcode->opnds[k].size == OpndSize_Null ? - OpndSize_Any : opcode->opnds[k].size); + od.opndConstraints[k] = Constraint( + opcode->opnds[k].kind, + opcode->opnds[k].size == OpndSize_Null ? OpndSize_Any : opcode->opnds[k].size, + opcode->opnds[k].ext + ); } } } Index: vm/jitrino/src/codegenerator/ia32/Ia32Encoder.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Encoder.h (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32Encoder.h (working copy) @@ -68,7 +68,8 @@ const OpcodeGroup * opcodeGroup; }; - static bool matches(Constraint co, Constraint ci, uint32 opndRoles, bool allowAliases); + static bool matches(Constraint co, Constraint ci); + static Constraint expandImmediate(Constraint co); static const OpcodeGroup* findOpcodeGroup(const FindInfo& fi); static bool matches(const OpcodeGroup* og, const FindInfo& fi, bool any); static bool isOpndAllowed(const Encoder::OpcodeGroup * og, uint32 i, Constraint co, bool isExtended, bool any); Index: vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (working copy) @@ -338,7 +338,7 @@ } int32 GCSafePointsInfo::getOffsetFromImmediate(Opnd* offsetOpnd) const { - if (offsetOpnd->isPlacedIn(OpndKind_Immediate)) { + if (offsetOpnd->isPlacedIn(OpndKind_Imm)) { if (offsetOpnd->getImmValue() == 0 && offsetOpnd->getRuntimeInfo()!=NULL) { irm.resolveRuntimeInfo(offsetOpnd); } Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (working copy) @@ -291,7 +291,7 @@ } } if (removeMemory) - c = Constraint((OpndKind)(c.getKind() &~ OpndKind_Mem), c.getSize(), c.getMask()); + c = Constraint((OpndKind)(c.getKind() &~ OpndKind_Mem), c.getSize(), c.getExt(), c.getMask()); } }else{ c = opnds[(idx - opndCount) / 4]->getMemOpndSubOpndConstraint((MemOpndSubOpndKind)((idx - opndCount) & 3)); Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (working copy) @@ -1051,20 +1051,22 @@ OpndSize sourceSize=sourceConstraint.getSize(); uint32 sourceByteSize=getByteSize(sourceSize); - OpndKind targetKind=(OpndKind)targetConstraint.getKind(); - OpndKind sourceKind=(OpndKind)sourceConstraint.getKind(); #if defined(_DEBUG) || !defined(_EM64T_) OpndSize targetSize=targetConstraint.getSize(); assert(targetSize<=sourceSize); // only same size or truncating conversions are allowed #endif - if (targetKind&OpndKind_Reg) { - if(sourceOpnd->isPlacedIn(OpndKind_Imm) && sourceOpnd->getImmValue()==0 && targetKind==OpndKind_GPReg && - !sourceOpnd->getRuntimeInfo() && !(getRegMask(RegName_EFLAGS)&flagsRegUsageMask)) { - return newInst(Mnemonic_XOR,targetOpnd, targetOpnd); + if (targetOpnd->isPlacedIn(OpndKind_Reg)) { + if(sourceOpnd->isPlacedIn(OpndKind_Imm) + && sourceOpnd->getImmValue()==0 + && targetOpnd->isPlacedIn(OpndKind_GPReg) + && !sourceOpnd->getRuntimeInfo() + && !(getRegMask(RegName_EFLAGS)&flagsRegUsageMask)) { + return newInst(Mnemonic_XOR,targetOpnd, targetOpnd); } - else if (targetKind==OpndKind_XMMReg && sourceOpnd->getMemOpndKind()==MemOpndKind_ConstantArea) { + else if (targetOpnd->isPlacedIn(OpndKind_XMMReg) + && sourceOpnd->getMemOpndKind()==MemOpndKind_ConstantArea) { #ifdef _EM64T_ Opnd * addr = NULL; Opnd * base = sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Base); @@ -1105,10 +1107,10 @@ } } - if ( (targetKind==OpndKind_GPReg||targetKind==OpndKind_Mem) && - (sourceKind==OpndKind_GPReg||sourceKind==OpndKind_Mem||sourceKind==OpndKind_Imm) + if ( targetOpnd->isPlacedIn(OpndKind_GPReg_Mem) && + (sourceOpnd->isPlacedIn(OpndKind_GPReg_Mem) || sourceOpnd->isPlacedIn(OpndKind_Imm)) ){ - if (sourceKind==OpndKind_Mem && targetKind==OpndKind_Mem){ + if (sourceOpnd->isPlacedIn(OpndKind_Mem) && targetOpnd->isPlacedIn(OpndKind_Mem)){ Inst * instList=NULL; #ifndef _EM64T_ uint32 targetByteSize=getByteSize(targetSize); @@ -1136,7 +1138,8 @@ return instList; }else{ #ifdef _EM64T_ - if((targetOpnd->getMemOpndKind() == MemOpndKind_StackAutoLayout) && (sourceKind==OpndKind_Imm) && (sourceOpnd->getSize() == OpndSize_64)) + if((targetOpnd->getMemOpndKind() == MemOpndKind_StackAutoLayout) + && (sourceOpnd->isPlacedIn(OpndKind_Imm)) && (sourceOpnd->getSize() == OpndSize_64)) return newMemMovSequence(targetOpnd, sourceOpnd, regUsageMask, false); else #else @@ -1144,10 +1147,8 @@ #endif return newInst(Mnemonic_MOV, targetOpnd, sourceOpnd); // must satisfy constraints } - }else if ( - (targetKind==OpndKind_XMMReg||targetKind==OpndKind_Mem) && - (sourceKind==OpndKind_XMMReg||sourceKind==OpndKind_Mem) - ){ + }else if (targetOpnd->isPlacedIn(OpndKind_XMMReg_Mem) + && sourceOpnd->isPlacedIn(OpndKind_XMMReg_Mem)){ targetOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); sourceOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); if (sourceByteSize==4){ @@ -1155,15 +1156,15 @@ }else if (sourceByteSize==8){ return newInst(Mnemonic_MOVSD,targetOpnd, sourceOpnd); } - }else if (targetKind==OpndKind_FPReg && sourceKind==OpndKind_Mem){ + }else if (targetOpnd->isPlacedIn(OpndKind_FPReg) && sourceOpnd->isPlacedIn(OpndKind_Mem)){ sourceOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); return newInst(Mnemonic_FLD, targetOpnd, sourceOpnd); - }else if (targetKind==OpndKind_Mem && sourceKind==OpndKind_FPReg){ + }else if (targetOpnd->isPlacedIn(OpndKind_Mem) && sourceOpnd->isPlacedIn(OpndKind_FPReg)){ targetOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); return newInst(Mnemonic_FSTP, targetOpnd, sourceOpnd); }else if ( - (targetKind==OpndKind_FPReg && sourceKind==OpndKind_XMMReg)|| - (targetKind==OpndKind_XMMReg && sourceKind==OpndKind_FPReg) + (targetOpnd->isPlacedIn(OpndKind_FPReg) && sourceOpnd->isPlacedIn(OpndKind_XMMReg)) + || (targetOpnd->isPlacedIn(OpndKind_XMMReg) && sourceOpnd->isPlacedIn(OpndKind_FPReg)) ){ Inst * instList=NULL; Opnd * tmp = newMemOpnd(targetOpnd->getType(), MemOpndKind_StackAutoLayout, getRegOpnd(STACK_REG), 0); @@ -1182,35 +1183,34 @@ Inst * IRManager::newPushPopSequence(Mnemonic mn, Opnd * opnd, uint32 regUsageMask) { - assert(opnd!=NULL); + assert(opnd != NULL); - Constraint constraint = opnd->getConstraint(Opnd::ConstraintKind_Location); - if (constraint.isNull()) + if (opnd->isPlacedIn(OpndKind_Null)) return newCopyPseudoInst(mn, opnd); - OpndKind kind=(OpndKind)constraint.getKind(); - OpndSize size=constraint.getSize(); + OpndSize size = opnd->getConstraint(Opnd::ConstraintKind_Location).getSize(); - Inst * instList=NULL; + Inst * instList = NULL; #ifdef _EM64T_ - if ( ((kind==OpndKind_GPReg ||kind==OpndKind_Mem)&& size!=OpndSize_32)||(kind==OpndKind_Imm && sizeisPlacedIn(OpndKind_GPReg_Mem && size != OpndSize_32) + ||(opnd->isPlacedIn(OpndKind_Imm) && size < OpndSize_32)){ return newInst(mn, opnd); #else - if ( kind==OpndKind_GPReg||kind==OpndKind_Mem||kind==OpndKind_Imm ){ - if (size==OpndSize_32){ + if (opnd->isPlacedIn(OpndKind_GPReg_Mem) || opnd->isPlacedIn(OpndKind_Imm)){ + if (size == OpndSize_32){ return newInst(mn, opnd); - }else if (sizegetType(), MemOpndKind_StackManualLayout, espOpnd, 0); + Opnd * espOpnd = getRegOpnd(STACK_REG); + Opnd * tmp = newMemOpnd(opnd->getType(), MemOpndKind_StackManualLayout, espOpnd, 0); #ifdef _EM64T_ - Opnd * sizeOpnd=newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)); - if(kind==OpndKind_Imm) { - assert(mn==Mnemonic_PUSH); + Opnd * sizeOpnd = newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)); + if(opnd->isPlacedIn(OpndKind_Imm)) { + assert(mn == Mnemonic_PUSH); appendToInstList(instList, newInst(Mnemonic_SUB, espOpnd, sizeOpnd)); appendToInstList(instList, newMemMovSequence(tmp, opnd, regUsageMask)); - } else if (kind == OpndKind_GPReg){ - assert(mn==Mnemonic_PUSH); + } else if (opnd->isPlacedIn(OpndKind_GPReg){ + assert(mn == Mnemonic_PUSH); appendToInstList(instList, newInst(Mnemonic_SUB, espOpnd, sizeOpnd)); appendToInstList(instList, newInst(Mnemonic_MOV, tmp, opnd)); } else { - if (mn==Mnemonic_PUSH){ + if (mn == Mnemonic_PUSH){ appendToInstList(instList, newInst(Mnemonic_SUB, espOpnd, sizeOpnd)); appendToInstList(instList, newCopySequence(tmp, opnd, regUsageMask)); }else{ @@ -1241,11 +1241,11 @@ } } #else - uint32 cb=getByteSize(size); - uint32 slotSize=4; - cb=(cb+slotSize-1)&~(slotSize-1); - Opnd * sizeOpnd=newImmOpnd(typeManager.getInt32Type(), cb); - if (mn==Mnemonic_PUSH){ + uint32 cb = getByteSize(size); + uint32 slotSize = 4; + cb = (cb+slotSize-1)&~(slotSize-1); + Opnd * sizeOpnd = newImmOpnd(typeManager.getInt32Type(), cb); + if (mn == Mnemonic_PUSH){ appendToInstList(instList, newInst(Mnemonic_SUB, espOpnd, sizeOpnd)); appendToInstList(instList, newCopySequence(tmp, opnd, regUsageMask)); }else{ Index: vm/jitrino/src/codegenerator/ia32/Ia32RegAlloc2.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32RegAlloc2.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32RegAlloc2.cpp (working copy) @@ -454,6 +454,7 @@ OpndKind k = (OpndKind)constrs.getKind(); OpndSize s = constrs.getSize(); + OpndExt e = constrs.getExt(); registers.clear(); RegMask mask = constrs.getMask(); @@ -464,7 +465,7 @@ Register* r = new (mm) Register(mm); r->regmask = m, r->regname = getRegName(k, s, x); - r->constraint = Constraint(k, s, m); + r->constraint = Constraint(k, s, e, m); r->length = 0; r->beg=(Instnb)UINT_MAX; r->end=(Instnb)0; Index: vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp (revision 618914) +++ vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp (working copy) @@ -1015,7 +1015,7 @@ return false; Constraint cx = c.getAliasConstraint(OpndSize_Default) & registers[opline.idx]; - Constraint cr((OpndKind)cx.getKind(), c.getSize(), cx.getMask()); + Constraint cr((OpndKind)cx.getKind(), c.getSize(), c.getExt(), cx.getMask()); // handle first instruction of the interval @@ -1120,7 +1120,7 @@ return false; Constraint cx = c.getAliasConstraint(OpndSize_Default) & registers[opline.idx]; - Constraint cr((OpndKind)cx.getKind(), c.getSize(), cx.getMask()); + Constraint cr((OpndKind)cx.getKind(), c.getSize(), c.getExt(), cx.getMask()); Instx* begx = opline.instx; Instx* endx = begx; @@ -1168,7 +1168,7 @@ return false; Constraint ca = c.getAliasConstraint(OpndSize_Default) & registers[opline.idx]; - Constraint cr((OpndKind)ca.getKind(), c.getSize(), ca.getMask()); + Constraint cr((OpndKind)ca.getKind(), c.getSize(), c.getExt(), ca.getMask()); Inst* inst = opline.instx->inst; Index: vm/port/src/encoder/ia32_em64t/enc_base.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.cpp (revision 618914) +++ vm/port/src/encoder/ia32_em64t/enc_base.cpp (working copy) @@ -638,32 +638,29 @@ /** * */ -static bool try_match(const EncoderBase::OpcodeDesc& odesc, - const EncoderBase::Operands& opnds, bool strict) { +static bool match(const EncoderBase::OpcodeDesc& odesc, + const EncoderBase::Operands& opnds) { assert(odesc.roles.count == opnds.count()); - for(unsigned j=0; jlast); assert(odesc->roles.count == opnds.count()); - assert(odesc->platf != OpcodeInfo::decoder); + assert(odesc->platf != OpcodeInfo::decoder); + assert(match(*odesc, opnds)); #if !defined(_EM64T_) // tuning was done for IA32 only, so no size restriction on EM64T //assert(sizeof(OpcodeDesc)==128); Index: vm/port/src/encoder/ia32_em64t/enc_base.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.h (revision 618914) +++ vm/port/src/encoder/ia32_em64t/enc_base.h (working copy) @@ -153,6 +153,10 @@ */ OpndSize size; /** + * @brief Extention of the operand. + */ + OpndExt ext; + /** * @brief Appropriate RegName if operand must reside on a particular * register (i.e. CWD/CDQ instructions), RegName_Null * otherwise. @@ -301,12 +305,13 @@ /** * @brief Initializes the instance with empty size and kind. */ - Operand() : m_kind(OpndKind_Null), m_size(OpndSize_Null), m_need_rex(false) {} + Operand() : m_kind(OpndKind_Null), m_size(OpndSize_Null), m_ext(OpndExt_None), m_need_rex(false) {} /** * @brief Creates register operand from given RegName. */ - Operand(RegName reg) : m_kind(getRegKind(reg)), - m_size(getRegSize(reg)), m_reg(reg) + Operand(RegName reg, OpndExt ext = OpndExt_None) : m_kind(getRegKind(reg)), + m_size(getRegSize(reg)), + m_ext(ext), m_reg(reg) { hash_it(); } @@ -318,9 +323,8 @@ * size and kind from the RegName. * The provided size and kind must match the RegName's ones though. */ - Operand(OpndSize sz, OpndKind kind, RegName reg) : m_kind(kind), - m_size(sz), - m_reg(reg) + Operand(OpndSize sz, OpndKind kind, RegName reg, OpndExt ext = OpndExt_None) : + m_kind(kind), m_size(sz), m_ext(ext), m_reg(reg) { assert(m_size == getRegSize(reg)); assert(m_kind == getRegKind(reg)); @@ -329,24 +333,24 @@ /** * @brief Creates immediate operand with the given size and value. */ - Operand(OpndSize size, long long ival) : m_kind(OpndKind_Imm), - m_size(size), m_imm64(ival) + Operand(OpndSize size, long long ival, OpndExt ext = OpndExt_None) : + m_kind(OpndKind_Imm), m_size(size), m_ext(ext), m_imm64(ival) { hash_it(); } /** * @brief Creates immediate operand of OpndSize_32. */ - Operand(int ival) : m_kind(OpndKind_Imm), m_size(OpndSize_32), - m_imm64(ival) + Operand(int ival, OpndExt ext = OpndExt_None) : + m_kind(OpndKind_Imm), m_size(OpndSize_32), m_ext(ext), m_imm64(ival) { hash_it(); } /** * @brief Creates immediate operand of OpndSize_16. */ - Operand(short ival) : m_kind(OpndKind_Imm), m_size(OpndSize_16), - m_imm64(ival) + Operand(short ival, OpndExt ext = OpndExt_None) : + m_kind(OpndKind_Imm), m_size(OpndSize_16), m_ext(ext), m_imm64(ival) { hash_it(); } @@ -354,8 +358,8 @@ /** * @brief Creates immediate operand of OpndSize_8. */ - Operand(char ival) : m_kind(OpndKind_Imm), m_size(OpndSize_8), - m_imm64(ival) + Operand(char ival, OpndExt ext = OpndExt_None) : + m_kind(OpndKind_Imm), m_size(OpndSize_8), m_ext(ext), m_imm64(ival) { hash_it(); } @@ -364,7 +368,7 @@ * @brief Creates memory operand. */ Operand(OpndSize size, RegName base, RegName index, unsigned scale, - int disp) : m_kind(OpndKind_Mem), m_size(size) + int disp) : m_kind(OpndKind_Mem), m_size(size), m_ext(OpndExt_None) { m_base = base; m_index = index; @@ -376,8 +380,8 @@ /** * @brief Creates memory operand with only base and displacement. */ - Operand(OpndSize size, RegName base, int disp) : - m_kind(OpndKind_Mem), m_size(size) + Operand(OpndSize size, RegName base, int disp) : + m_kind(OpndKind_Mem), m_size(size), m_ext(OpndExt_None) { m_base = base; m_index = RegName_Null; @@ -397,6 +401,10 @@ */ OpndSize size(void) const { return m_size; } /** + * @brief Returns extention of the operand. + */ + OpndExt ext(void) const { return m_ext; } + /** * @brief Returns hash of the operand. */ unsigned hash(void) const { return m_hash; } @@ -437,6 +445,11 @@ bool is_mmxreg(void) const { return is_placed_in(OpndKind_MMXReg); } #endif /** + * @brief Tests whether operand is signed immediate operand. + */ + //bool is_signed(void) const { assert(is_imm()); return m_is_signed; } + + /** * @brief Returns base of memory operand (RegName_Null if not memory). */ RegName base(void) const { return is_mem() ? m_base : RegName_Null; } @@ -490,6 +503,7 @@ // general info OpndKind m_kind; OpndSize m_size; + OpndExt m_ext; // complex address form support RegName m_base; RegName m_index; @@ -564,7 +578,7 @@ #ifdef _DEBUG /** * Verifies some presumptions about encoding data table. - * Called automagicaly during statics initialization. + * Called automaticaly during statics initialization. */ static int verify(void); #endif Index: vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 618914) +++ vm/port/src/encoder/ia32_em64t/enc_defs.h (working copy) @@ -104,7 +104,7 @@ OpndKind_MaxRegKind = OpndKind_StatusReg, // a max existing kind of register OpndKind_MaxReg, // -'- + 1 to be used in array defs // - OpndKind_Immediate = 0x20, OpndKind_Imm=OpndKind_Immediate, + OpndKind_Imm = 0x20, OpndKind_Memory = 0x40, OpndKind_Mem=OpndKind_Memory, // OpndKind_Reg = 0x1F, @@ -137,10 +137,23 @@ OpndSize_128 = 0x20, #endif OpndSize_Max, - OpndSize_Any = 0xFF, + OpndSize_Any = 0x3F, OpndSize_Default = OpndSize_Any }; +/** + * Defines type of extention allowed for particular operand. + * For example imul r32,r_m32,imm8 sign extend imm8 before performing multiplication. + * To satisfy instruction constraints immediate operand should be either OpndExt_Signed + * or OpndExt_Any. + */ +enum OpndExt { + OpndExt_None = 0x0, + OpndExt_Signed = 0x1, + OpndExt_Zero = 0x2, + OpndExt_Any = 0x3, +}; + /** * enum OpndRole defines the role of an operand in an instruction * Can be used as mask to combine def and use. The complete def+use Index: vm/port/src/encoder/ia32_em64t/enc_prvt.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_prvt.h (revision 618914) +++ vm/port/src/encoder/ia32_em64t/enc_prvt.h (working copy) @@ -136,94 +136,111 @@ #define rw OpcodeByteKind_rw #define rd OpcodeByteKind_rd -#define AL {OpndKind_GPReg, OpndSize_8, RegName_AL} -#define AH {OpndKind_GPReg, OpndSize_8, RegName_AH} -#define AX {OpndKind_GPReg, OpndSize_16, RegName_AX} -#define EAX {OpndKind_GPReg, OpndSize_32, RegName_EAX} +#define AL {OpndKind_GPReg, OpndSize_8, OpndExt_None, RegName_AL} +#define AH {OpndKind_GPReg, OpndSize_8, OpndExt_None, RegName_AH} +#define AX {OpndKind_GPReg, OpndSize_16, OpndExt_None, RegName_AX} +#define EAX {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_EAX} #ifdef _EM64T_ - #define RAX {OpndKind_GPReg, OpndSize_64, RegName_RAX } + #define RAX {OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_RAX } #endif -#define CL {OpndKind_GPReg, OpndSize_8, RegName_CL} -#define ECX {OpndKind_GPReg, OpndSize_32, RegName_ECX} +#define CL {OpndKind_GPReg, OpndSize_8, OpndExt_None, RegName_CL} +#define ECX {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_ECX} #ifdef _EM64T_ - #define RCX {OpndKind_GPReg, OpndSize_64, RegName_RCX} + #define RCX {OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_RCX} #endif -#define DX {OpndKind_GPReg, OpndSize_16, RegName_DX} -#define EDX {OpndKind_GPReg, OpndSize_32, RegName_EDX} +#define DX {OpndKind_GPReg, OpndSize_16, OpndExt_None, RegName_DX} +#define EDX {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_EDX} #ifdef _EM64T_ - #define RDX { OpndKind_GPReg, OpndSize_64, RegName_RDX } + #define RDX { OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_RDX } #endif -#define ESI {OpndKind_GPReg, OpndSize_32, RegName_ESI} +#define ESI {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_ESI} #ifdef _EM64T_ - #define RSI { OpndKind_GPReg, OpndSize_64, RegName_RSI } + #define RSI { OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_RSI } #endif -#define EDI {OpndKind_GPReg, OpndSize_32, RegName_EDI} +#define EDI {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_EDI} #ifdef _EM64T_ - #define RDI { OpndKind_GPReg, OpndSize_64, RegName_RDI } + #define RDI { OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_RDI } #endif -#define r8 {OpndKind_GPReg, OpndSize_8, RegName_Null} -#define r16 {OpndKind_GPReg, OpndSize_16, RegName_Null} -#define r32 {OpndKind_GPReg, OpndSize_32, RegName_Null} +#define r8 {OpndKind_GPReg, OpndSize_8, OpndExt_None, RegName_Null} +#define r16 {OpndKind_GPReg, OpndSize_16, OpndExt_None, RegName_Null} +#define r32 {OpndKind_GPReg, OpndSize_32, OpndExt_None, RegName_Null} #ifdef _EM64T_ - #define r64 { OpndKind_GPReg, OpndSize_64, RegName_Null } + #define r64 { OpndKind_GPReg, OpndSize_64, OpndExt_None, RegName_Null } #endif -#define r_m8 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, RegName_Null} -#define r_m16 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, RegName_Null} -#define r_m32 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, RegName_Null} +#define r_m8 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_None, RegName_Null} +#define r_m16 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_None, RegName_Null} +#define r_m32 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_None, RegName_Null} +#define r_m8s {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Signed, RegName_Null} +#define r_m16s {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Signed, RegName_Null} +#define r_m32s {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Signed, RegName_Null} + +#define r_m8u {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Zero, RegName_Null} +#define r_m16u {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Zero, RegName_Null} +#define r_m32u {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Zero, RegName_Null} + //'m' was only used in LEA mnemonic, but is replaced with // set of exact sizes. See more comments for LEA instruction in TheTable. //#define m {OpndKind_Mem, OpndSize_Null, RegName_Null} -#define m8 {OpndKind_Mem, OpndSize_8, RegName_Null} -#define m16 {OpndKind_Mem, OpndSize_16, RegName_Null} -#define m32 {OpndKind_Mem, OpndSize_32, RegName_Null} -#define m64 {OpndKind_Mem, OpndSize_64, RegName_Null} +#define m8 {OpndKind_Mem, OpndSize_8, OpndExt_None, RegName_Null} +#define m16 {OpndKind_Mem, OpndSize_16, OpndExt_None, RegName_Null} +#define m32 {OpndKind_Mem, OpndSize_32, OpndExt_None, RegName_Null} +#define m64 {OpndKind_Mem, OpndSize_64, OpndExt_None, RegName_Null} #ifdef _EM64T_ - #define r_m64 { (OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_64, RegName_Null } + #define r_m64 { (OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_64, OpndExt_None, RegName_Null } #endif -#define imm8 {OpndKind_Imm, OpndSize_8, RegName_Null} -#define imm16 {OpndKind_Imm, OpndSize_16, RegName_Null} -#define imm32 {OpndKind_Imm, OpndSize_32, RegName_Null} +#define imm8 {OpndKind_Imm, OpndSize_8, OpndExt_None, RegName_Null} +#define imm16 {OpndKind_Imm, OpndSize_16, OpndExt_None, RegName_Null} +#define imm32 {OpndKind_Imm, OpndSize_32, OpndExt_None, RegName_Null} + +#define imm8s {OpndKind_Imm, OpndSize_8, OpndExt_Signed, RegName_Null} +#define imm16s {OpndKind_Imm, OpndSize_16, OpndExt_Signed, RegName_Null} +#define imm32s {OpndKind_Imm, OpndSize_32, OpndExt_Signed, RegName_Null} + +#define imm8u {OpndKind_Imm, OpndSize_8, OpndExt_Zero, RegName_Null} +#define imm16u {OpndKind_Imm, OpndSize_16, OpndExt_Zero, RegName_Null} +#define imm32u {OpndKind_Imm, OpndSize_32, OpndExt_Zero, RegName_Null} + #ifdef _EM64T_ - #define imm64 {OpndKind_Imm, OpndSize_64, RegName_Null } + #define imm64 {OpndKind_Imm, OpndSize_64, OpndExt_None, RegName_Null } #endif //FIXME: moff-s are in fact memory refs, but presented as immediate. // Need to specify this in OpndDesc. -#define moff8 {OpndKind_Imm, OpndSize_32, RegName_Null} -#define moff16 {OpndKind_Imm, OpndSize_32, RegName_Null} -#define moff32 {OpndKind_Imm, OpndSize_32, RegName_Null} +#define moff8 {OpndKind_Imm, OpndSize_32, OpndExt_None, RegName_Null} +#define moff16 {OpndKind_Imm, OpndSize_32, OpndExt_None, RegName_Null} +#define moff32 {OpndKind_Imm, OpndSize_32, OpndExt_None, RegName_Null} #ifdef _EM64T_ - #define moff64 {OpndKind_Imm, OpndSize_64, RegName_Null} + #define moff64 {OpndKind_Imm, OpndSize_64, OpndExt_None, RegName_Null} #endif -#define rel8 {OpndKind_Imm, OpndSize_8, RegName_Null} -#define rel16 {OpndKind_Imm, OpndSize_16, RegName_Null} -#define rel32 {OpndKind_Imm, OpndSize_32, RegName_Null} +#define rel8 {OpndKind_Imm, OpndSize_8, OpndExt_None, RegName_Null} +#define rel16 {OpndKind_Imm, OpndSize_16, OpndExt_None, RegName_Null} +#define rel32 {OpndKind_Imm, OpndSize_32, OpndExt_None, RegName_Null} -#define mm64 {OpndKind_MMXReg, OpndSize_64, RegName_Null} -#define mm_m64 {(OpndKind)(OpndKind_MMXReg|OpndKind_Mem), OpndSize_64, RegName_Null} +#define mm64 {OpndKind_MMXReg, OpndSize_64, OpndExt_None, RegName_Null} +#define mm_m64 {(OpndKind)(OpndKind_MMXReg|OpndKind_Mem), OpndSize_64, OpndExt_None, RegName_Null} -#define xmm64 {OpndKind_XMMReg, OpndSize_64, RegName_Null} -#define xmm_m64 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_64, RegName_Null} +#define xmm64 {OpndKind_XMMReg, OpndSize_64, OpndExt_None, RegName_Null} +#define xmm_m64 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_64, OpndExt_None, RegName_Null} -#define xmm32 {OpndKind_XMMReg, OpndSize_32, RegName_Null} -#define xmm_m32 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_32, RegName_Null} +#define xmm32 {OpndKind_XMMReg, OpndSize_32, OpndExt_None, RegName_Null} +#define xmm_m32 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_32, OpndExt_None, RegName_Null} -#define FP0S {OpndKind_FPReg, OpndSize_32, RegName_FP0S} -#define FP0D {OpndKind_FPReg, OpndSize_64, RegName_FP0D} -#define FP1S {OpndKind_FPReg, OpndSize_32, RegName_FP1S} -#define FP1D {OpndKind_FPReg, OpndSize_64, RegName_FP1D} -#define fp32 {OpndKind_FPReg, OpndSize_32, RegName_Null} -#define fp64 {OpndKind_FPReg, OpndSize_64, RegName_Null} +#define FP0S {OpndKind_FPReg, OpndSize_32, OpndExt_None, RegName_FP0S} +#define FP0D {OpndKind_FPReg, OpndSize_64, OpndExt_None, RegName_FP0D} +#define FP1S {OpndKind_FPReg, OpndSize_32, OpndExt_None, RegName_FP1S} +#define FP1D {OpndKind_FPReg, OpndSize_64, OpndExt_None, RegName_FP1D} +#define fp32 {OpndKind_FPReg, OpndSize_32, OpndExt_None, RegName_Null} +#define fp64 {OpndKind_FPReg, OpndSize_64, OpndExt_None, RegName_Null} #ifdef _EM64T_ #define io OpcodeByteKind_io Index: vm/port/src/encoder/ia32_em64t/enc_tabl.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (revision 618914) +++ vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (working copy) @@ -328,7 +328,7 @@ BEGIN_MNEMONIC(LAHF, MF_USES_FLAGS, D) BEGIN_OPCODES() // TheManual says it's not always supported in em64t mode, thus excluding it - {OpcodeInfo::ia32, {0x9F}, {EAX}, D }, + {OpcodeInfo::ia32, {0x9F}, {EAX}, D }, END_OPCODES() END_MNEMONIC() // @@ -348,28 +348,28 @@ {OpcodeInfo::decoder, {opcode_starts_from + 4, ib}, {AL, imm8}, DU_U },\ {OpcodeInfo::decoder, {Size16, opcode_starts_from + 5, iw}, {AX, imm16}, DU_U },\ {OpcodeInfo::decoder, {opcode_starts_from + 5, id}, {EAX, imm32}, DU_U },\ - {OpcodeInfo::decoder64, {REX_W, opcode_starts_from+5, id}, {RAX, imm32}, DU_U },\ + {OpcodeInfo::decoder64, {REX_W, opcode_starts_from+5, id}, {RAX, imm32s},DU_U },\ \ - {OpcodeInfo::all, {0x80, opc_ext, ib}, {r_m8, imm8}, def_use },\ - {OpcodeInfo::all, {Size16, 0x81, opc_ext, iw}, {r_m16, imm16}, def_use },\ - {OpcodeInfo::all, {0x81, opc_ext, id}, {r_m32, imm32}, def_use },\ - {OpcodeInfo::em64t, {REX_W, 0x81, opc_ext, id}, {r_m64, imm32}, def_use },\ + {OpcodeInfo::all, {0x80, opc_ext, ib}, {r_m8, imm8}, def_use },\ + {OpcodeInfo::all, {Size16, 0x81, opc_ext, iw}, {r_m16, imm16}, def_use },\ + {OpcodeInfo::all, {0x81, opc_ext, id}, {r_m32, imm32}, def_use },\ + {OpcodeInfo::em64t, {REX_W, 0x81, opc_ext, id}, {r_m64, imm32s}, def_use },\ \ - {OpcodeInfo::all, {Size16, 0x83, opc_ext, ib}, {r_m16, imm8}, def_use },\ - {OpcodeInfo::all, {0x83, opc_ext, ib}, {r_m32, imm8}, def_use },\ - {OpcodeInfo::em64t, {REX_W, 0x83, opc_ext, ib}, {r_m64, imm8}, def_use },\ + {OpcodeInfo::all, {Size16, 0x83, opc_ext, ib}, {r_m16, imm8s}, def_use },\ + {OpcodeInfo::all, {0x83, opc_ext, ib}, {r_m32, imm8s}, def_use },\ + {OpcodeInfo::em64t, {REX_W, 0x83, opc_ext, ib}, {r_m64, imm8s}, def_use },\ \ - {OpcodeInfo::all, {first_opcode, _r}, {r_m8, r8}, def_use },\ + {OpcodeInfo::all, {first_opcode, _r}, {r_m8, r8}, def_use },\ \ - {OpcodeInfo::all, {Size16, opcode_starts_from+1, _r}, {r_m16, r16}, def_use },\ - {OpcodeInfo::all, {opcode_starts_from+1, _r}, {r_m32, r32}, def_use },\ - {OpcodeInfo::em64t, {REX_W, opcode_starts_from+1, _r}, {r_m64, r64}, def_use },\ + {OpcodeInfo::all, {Size16, opcode_starts_from+1, _r}, {r_m16, r16}, def_use },\ + {OpcodeInfo::all, {opcode_starts_from+1, _r}, {r_m32, r32}, def_use },\ + {OpcodeInfo::em64t, {REX_W, opcode_starts_from+1, _r}, {r_m64, r64}, def_use },\ \ - {OpcodeInfo::all, {opcode_starts_from+2, _r}, {r8, r_m8}, def_use },\ + {OpcodeInfo::all, {opcode_starts_from+2, _r}, {r8, r_m8}, def_use },\ \ - {OpcodeInfo::all, {Size16, opcode_starts_from+3, _r}, {r16, r_m16}, def_use },\ - {OpcodeInfo::all, {opcode_starts_from+3, _r}, {r32, r_m32}, def_use },\ - {OpcodeInfo::em64t, {REX_W, opcode_starts_from+3, _r}, {r64, r_m64}, def_use }, + {OpcodeInfo::all, {Size16, opcode_starts_from+3, _r}, {r16, r_m16}, def_use },\ + {OpcodeInfo::all, {opcode_starts_from+3, _r}, {r32, r_m32}, def_use },\ + {OpcodeInfo::em64t, {REX_W, opcode_starts_from+3, _r}, {r64, r_m64}, def_use }, BEGIN_MNEMONIC(ADD, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U) BEGIN_OPCODES() @@ -423,16 +423,16 @@ BEGIN_MNEMONIC(CMPXCHG, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xB0, _r}, {r_m8, r8, AL}, DU_DU_DU }, - {OpcodeInfo::all, {Size16, 0x0F, 0xB1, _r}, {r_m16, r16, AX}, DU_DU_DU }, - {OpcodeInfo::all, {0x0F, 0xB1, _r}, {r_m32, r32, EAX}, DU_DU_DU}, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r},{r_m64, r64, RAX}, DU_DU_DU }, + {OpcodeInfo::all, {0x0F, 0xB0, _r}, {r_m8, r8, AL}, DU_DU_DU }, + {OpcodeInfo::all, {Size16, 0x0F, 0xB1, _r}, {r_m16, r16, AX}, DU_DU_DU }, + {OpcodeInfo::all, {0x0F, 0xB1, _r}, {r_m32, r32, EAX}, DU_DU_DU}, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r}, {r_m64, r64, RAX}, DU_DU_DU }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(CMPXCHG8B, MF_AFFECTS_FLAGS, D) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xC7, _1}, {m64}, DU }, + {OpcodeInfo::all, {0x0F, 0xC7, _1}, {m64}, DU }, END_OPCODES() END_MNEMONIC() @@ -442,50 +442,50 @@ // BEGIN_MNEMONIC(ADDSD, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x58, _r}, {xmm64, xmm_m64}, DU_U}, + {OpcodeInfo::all, {0xF2, 0x0F, 0x58, _r}, {xmm64, xmm_m64}, DU_U}, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(ADDSS, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x58, _r}, {xmm32, xmm_m32}, DU_U}, + {OpcodeInfo::all, {0xF3, 0x0F, 0x58, _r}, {xmm32, xmm_m32}, DU_U}, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(BSF, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() -{OpcodeInfo::all, {0x0F, 0xBC}, {r32, r_m32}, D_U}, + {OpcodeInfo::all, {0x0F, 0xBC}, {r32, r_m32}, D_U}, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(BSR, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xBD}, {r32, r_m32}, D_U}, + {OpcodeInfo::all, {0x0F, 0xBD}, {r32, r_m32}, D_U}, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(CALL, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xE8, cd}, {rel32}, U }, - {OpcodeInfo::ia32, {0xFF, _2}, {r_m32}, U }, - {OpcodeInfo::em64t, {REX_W, 0xFF, _2}, {r_m64}, U }, + {OpcodeInfo::all, {0xE8, cd}, {rel32}, U }, + {OpcodeInfo::ia32, {0xFF, _2}, {r_m32}, U }, + {OpcodeInfo::em64t, {REX_W, 0xFF, _2}, {r_m64}, U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(CMC, MF_USES_FLAGS|MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::decoder, {0xF5}, {}, N }, + {OpcodeInfo::decoder, {0xF5}, {}, N }, END_OPCODES() END_MNEMONIC() //TODO: Workaround. Actually, it's D_DU, but Jitrino's CG thinks it's D_U BEGIN_MNEMONIC(CDQ, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0x99}, {DX, AX}, D_U }, - {OpcodeInfo::all, {0x99}, {EDX, EAX}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x99}, {RDX, RAX}, D_U }, + {OpcodeInfo::all, {0x99}, {DX, AX}, D_U }, + {OpcodeInfo::all, {0x99}, {EDX, EAX}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x99}, {RDX, RAX}, D_U }, END_OPCODES() END_MNEMONIC() @@ -524,62 +524,62 @@ // double -> float BEGIN_MNEMONIC(CVTSD2SS, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x5A, _r}, {xmm32, xmm_m64}, D_U }, + {OpcodeInfo::all, {0xF2, 0x0F, 0x5A, _r}, {xmm32, xmm_m64}, D_U }, END_OPCODES() END_MNEMONIC() // double -> int32 BEGIN_MNEMONIC(CVTSD2SI, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x2D, _r}, {r32, xmm_m64}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2D, _r}, {r64, xmm_m64}, D_U }, + {OpcodeInfo::all, {0xF2, 0x0F, 0x2D, _r}, {r32, xmm_m64}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2D, _r}, {r64, xmm_m64}, D_U }, END_OPCODES() END_MNEMONIC() // double [truncated] -> int32 BEGIN_MNEMONIC(CVTTSD2SI, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x2C, _r}, {r32, xmm_m64}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2C, _r}, {r64, xmm_m64}, D_U }, + {OpcodeInfo::all, {0xF2, 0x0F, 0x2C, _r}, {r32, xmm_m64}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2C, _r}, {r64, xmm_m64}, D_U }, END_OPCODES() END_MNEMONIC() // float -> double BEGIN_MNEMONIC(CVTSS2SD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x5A, _r}, {xmm64, xmm_m32}, D_U }, + {OpcodeInfo::all, {0xF3, 0x0F, 0x5A, _r}, {xmm64, xmm_m32}, D_U }, END_OPCODES() END_MNEMONIC() // float -> int32 BEGIN_MNEMONIC(CVTSS2SI, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x2D, _r}, {r32, xmm_m32}, D_U}, - {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2D, _r}, {r64, xmm_m32}, D_U}, + {OpcodeInfo::all, {0xF3, 0x0F, 0x2D, _r}, {r32, xmm_m32}, D_U}, + {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2D, _r}, {r64, xmm_m32}, D_U}, END_OPCODES() END_MNEMONIC() // float [truncated] -> int32 BEGIN_MNEMONIC(CVTTSS2SI, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x2C, _r}, {r32, xmm_m32}, D_U}, - {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2C, _r}, {r64, xmm_m32}, D_U}, + {OpcodeInfo::all, {0xF3, 0x0F, 0x2C, _r}, {r32, xmm_m32}, D_U}, + {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2C, _r}, {r64, xmm_m32}, D_U}, END_OPCODES() END_MNEMONIC() // int32 -> double BEGIN_MNEMONIC(CVTSI2SD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m32}, D_U}, - {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m64}, D_U}, + {OpcodeInfo::all, {0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m32}, D_U}, + {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m64}, D_U}, END_OPCODES() END_MNEMONIC() // int32 -> float BEGIN_MNEMONIC(CVTSI2SS, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m32}, D_U}, - {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m64}, D_U}, + {OpcodeInfo::all, {0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m32}, D_U}, + {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m64}, D_U}, END_OPCODES() END_MNEMONIC() @@ -603,14 +603,14 @@ BEGIN_MNEMONIC(DIVSD, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x5E, _r}, {xmm64, xmm_m64}, DU_U }, + {OpcodeInfo::all, {0xF2, 0x0F, 0x5E, _r}, {xmm64, xmm_m64}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(DIVSS, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x5E, _r}, {xmm32, xmm_m32}, DU_U }, + {OpcodeInfo::all, {0xF3, 0x0F, 0x5E, _r}, {xmm32, xmm_m32}, DU_U }, END_OPCODES() END_MNEMONIC() @@ -620,114 +620,114 @@ BEGIN_MNEMONIC(FADDP, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xC1}, {FP0D, FP1D}, DU_U }, - {OpcodeInfo::all, {0xDE, 0xC1}, {FP0S, FP1S}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xC1}, {FP0D, FP1D}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xC1}, {FP0S, FP1S}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FLDZ, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xEE}, {FP0D}, D }, - {OpcodeInfo::all, {0xD9, 0xEE}, {FP0S}, D }, + {OpcodeInfo::all, {0xD9, 0xEE}, {FP0D}, D }, + {OpcodeInfo::all, {0xD9, 0xEE}, {FP0S}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FADD, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDC, _0}, {FP0D, m64}, DU_U }, - {OpcodeInfo::all, {0xD8, _0}, {FP0S, m32}, DU_U }, + {OpcodeInfo::all, {0xDC, _0}, {FP0D, m64}, DU_U }, + {OpcodeInfo::all, {0xD8, _0}, {FP0S, m32}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FSUBP, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xE9}, {FP0D, FP1D}, DU_U }, - {OpcodeInfo::all, {0xDE, 0xE9}, {FP0S, FP1S}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xE9}, {FP0D, FP1D}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xE9}, {FP0S, FP1S}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FSUB, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDC, _4}, {FP0D, m64}, DU_U }, - {OpcodeInfo::all, {0xD8, _4}, {FP0S, m32}, DU_U }, + {OpcodeInfo::all, {0xDC, _4}, {FP0D, m64}, DU_U }, + {OpcodeInfo::all, {0xD8, _4}, {FP0S, m32}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FMUL, MF_NONE, DU_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD8, _1}, {FP0S, m32}, DU_U }, - {OpcodeInfo::all, {0xDC, _1}, {FP0D, m64}, DU_U }, + {OpcodeInfo::all, {0xD8, _1}, {FP0S, m32}, DU_U }, + {OpcodeInfo::all, {0xDC, _1}, {FP0D, m64}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FMULP, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xC9}, {FP0D, FP1D}, DU_U }, - {OpcodeInfo::all, {0xDE, 0xC9}, {FP0S, FP1S}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xC9}, {FP0D, FP1D}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xC9}, {FP0S, FP1S}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FDIVP, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xF9}, {FP0D, FP1D}, DU_U }, - {OpcodeInfo::all, {0xDE, 0xF9}, {FP0S, FP1S}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xF9}, {FP0D, FP1D}, DU_U }, + {OpcodeInfo::all, {0xDE, 0xF9}, {FP0S, FP1S}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FDIV, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDC, _6}, {FP0D, m64}, DU_U }, - {OpcodeInfo::all, {0xD8, _6}, {FP0S, m32}, DU_U }, + {OpcodeInfo::all, {0xDC, _6}, {FP0D, m64}, DU_U }, + {OpcodeInfo::all, {0xD8, _6}, {FP0S, m32}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FUCOMPP, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDA, 0xE9}, {FP0D, FP1D}, DU_U }, - {OpcodeInfo::all, {0xDA, 0xE9}, {FP0S, FP1S}, DU_U }, + {OpcodeInfo::all, {0xDA, 0xE9}, {FP0D, FP1D}, DU_U }, + {OpcodeInfo::all, {0xDA, 0xE9}, {FP0S, FP1S}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FLDCW, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, _5}, {m16}, U }, + {OpcodeInfo::all, {0xD9, _5}, {m16}, U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FNSTCW, MF_NONE, D) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, _7}, {m16}, D }, + {OpcodeInfo::all, {0xD9, _7}, {m16}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FSTSW, MF_NONE, D) BEGIN_OPCODES() - {OpcodeInfo::all, {0x9B, 0xDF, 0xE0}, {EAX}, D }, + {OpcodeInfo::all, {0x9B, 0xDF, 0xE0}, {EAX}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FNSTSW, MF_NONE, D) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDF, 0xE0}, {EAX}, D }, + {OpcodeInfo::all, {0xDF, 0xE0}, {EAX}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FCHS, MF_NONE, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xE0}, {FP0D}, DU }, - {OpcodeInfo::all, {0xD9, 0xE0}, {FP0S}, DU }, + {OpcodeInfo::all, {0xD9, 0xE0}, {FP0D}, DU }, + {OpcodeInfo::all, {0xD9, 0xE0}, {FP0S}, DU }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FCLEX, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x9B, 0xDB, 0xE2}, {}, N }, + {OpcodeInfo::all, {0x9B, 0xDB, 0xE2}, {}, N }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FNCLEX, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDB, 0xE2}, {}, N }, + {OpcodeInfo::all, {0xDB, 0xE2}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -739,7 +739,7 @@ BEGIN_MNEMONIC(FILD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, + {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, END_OPCODES() END_MNEMONIC() @@ -751,35 +751,35 @@ BEGIN_MNEMONIC(FIST, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDB, _2}, {m32, FP0S}, D_U }, + {OpcodeInfo::all, {0xDB, _2}, {m32, FP0S}, D_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FISTP, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDB, _3}, {m32, FP0S}, D_U }, - {OpcodeInfo::all, {0xDF, _7}, {m64, FP0D}, D_U }, + {OpcodeInfo::all, {0xDB, _3}, {m32, FP0S}, D_U }, + {OpcodeInfo::all, {0xDF, _7}, {m64, FP0D}, D_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FISTTP, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDD, _1}, {m64, FP0D}, D_U }, - {OpcodeInfo::all, {0xDB, _1}, {m32, FP0S}, D_U }, + {OpcodeInfo::all, {0xDD, _1}, {m64, FP0D}, D_U }, + {OpcodeInfo::all, {0xDB, _1}, {m32, FP0S}, D_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FRNDINT, MF_NONE, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xFC}, {FP0S}, DU }, - {OpcodeInfo::all, {0xD9, 0xFC}, {FP0D}, DU }, + {OpcodeInfo::all, {0xD9, 0xFC}, {FP0S}, DU }, + {OpcodeInfo::all, {0xD9, 0xFC}, {FP0D}, DU }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FLD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, _0}, {FP0S, m32}, D_U }, - {OpcodeInfo::all, {0xDD, _0}, {FP0D, m64}, D_U }, + {OpcodeInfo::all, {0xD9, _0}, {FP0S, m32}, D_U }, + {OpcodeInfo::all, {0xDD, _0}, {FP0D, m64}, D_U }, END_OPCODES() END_MNEMONIC() @@ -791,7 +791,7 @@ BEGIN_MNEMONIC(FPREM1, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xF5}, {}, N }, + {OpcodeInfo::all, {0xD9, 0xF5}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -837,7 +837,7 @@ #endif {OpcodeInfo::all, {0xF7, _7}, {EDX, EAX, r_m32}, DU_DU_U }, {OpcodeInfo::em64t, {REX_W, 0xF7, _7}, {RDX, RAX, r_m64}, DU_DU_U }, - END_OPCODES() +END_OPCODES() END_MNEMONIC() @@ -853,53 +853,53 @@ // revisit the hash implementation // {OpcodeInfo::em64t, {REX_W, 0xF7, _5}, {RDX, RAX, r_m64}, D_DU_U }, // - {OpcodeInfo::all, {Size16, 0x0F, 0xAF, _r}, {r16,r_m16}, DU_U }, - {OpcodeInfo::all, {0x0F, 0xAF, _r}, {r32,r_m32}, DU_U }, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xAF, _r}, {r64,r_m64}, DU_U }, - {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,r_m16,imm8}, D_DU_U }, - {OpcodeInfo::all, {0x6B, _r, ib}, {r32,r_m32,imm8}, D_DU_U }, - {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,r_m64,imm8}, D_DU_U }, - {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,imm8}, DU_U }, - {OpcodeInfo::all, {0x6B, _r, ib}, {r32,imm8}, DU_U }, - {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,imm8}, DU_U }, - {OpcodeInfo::all, {Size16, 0x69, _r, iw}, {r16,r_m16,imm16}, D_U_U }, - {OpcodeInfo::all, {0x69, _r, id}, {r32,r_m32,imm32}, D_U_U }, - {OpcodeInfo::em64t, {REX_W, 0x69, _r, id}, {r64,r_m64,imm32}, D_U_U }, + {OpcodeInfo::all, {Size16, 0x0F, 0xAF, _r}, {r16,r_m16}, DU_U }, + {OpcodeInfo::all, {0x0F, 0xAF, _r}, {r32,r_m32}, DU_U }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xAF, _r}, {r64,r_m64}, DU_U }, + {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,r_m16,imm8s}, D_DU_U }, + {OpcodeInfo::all, {0x6B, _r, ib}, {r32,r_m32,imm8s}, D_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,r_m64,imm8s}, D_DU_U }, + {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,imm8s}, DU_U }, + {OpcodeInfo::all, {0x6B, _r, ib}, {r32,imm8s}, DU_U }, + {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,imm8s}, DU_U }, + {OpcodeInfo::all, {Size16, 0x69, _r, iw}, {r16,r_m16,imm16}, D_U_U }, + {OpcodeInfo::all, {0x69, _r, id}, {r32,r_m32,imm32}, D_U_U }, + {OpcodeInfo::em64t, {REX_W, 0x69, _r, id}, {r64,r_m64,imm32s}, D_U_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(MUL, MF_AFFECTS_FLAGS, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF6, _4}, {AX, AL, r_m8}, D_DU_U }, - {OpcodeInfo::all, {Size16, 0xF7, _4}, {DX, AX, r_m16}, D_DU_U }, - {OpcodeInfo::all, {0xF7, _4}, {EDX, EAX, r_m32}, D_DU_U }, - {OpcodeInfo::em64t, {REX_W, 0xF7, _4}, {RDX, RAX, r_m64}, D_DU_U }, + {OpcodeInfo::all, {0xF6, _4}, {AX, AL, r_m8}, D_DU_U }, + {OpcodeInfo::all, {Size16, 0xF7, _4}, {DX, AX, r_m16}, D_DU_U }, + {OpcodeInfo::all, {0xF7, _4}, {EDX, EAX, r_m32}, D_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0xF7, _4}, {RDX, RAX, r_m64}, D_DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(INC, MF_AFFECTS_FLAGS, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xFE, _0}, {r_m8}, DU }, - {OpcodeInfo::all, {Size16, 0xFF, _0}, {r_m16}, DU }, - {OpcodeInfo::all, {0xFF, _0}, {r_m32}, DU }, - {OpcodeInfo::em64t, {REX_W, 0xFF, _0}, {r_m64}, DU }, - {OpcodeInfo::ia32, {Size16, 0x40|rw}, {r16}, DU }, - {OpcodeInfo::ia32, {0x40|rd}, {r32}, DU }, + {OpcodeInfo::all, {0xFE, _0}, {r_m8}, DU }, + {OpcodeInfo::all, {Size16, 0xFF, _0}, {r_m16}, DU }, + {OpcodeInfo::all, {0xFF, _0}, {r_m32}, DU }, + {OpcodeInfo::em64t, {REX_W, 0xFF, _0}, {r_m64}, DU }, + {OpcodeInfo::ia32, {Size16, 0x40|rw}, {r16}, DU }, + {OpcodeInfo::ia32, {0x40|rd}, {r32}, DU }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(INT3, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xCC}, {}, N }, + {OpcodeInfo::all, {0xCC}, {}, N }, END_OPCODES() END_MNEMONIC() #define DEFINE_Jcc_MNEMONIC( cc ) \ BEGIN_MNEMONIC(J##cc, MF_USES_FLAGS|MF_CONDITIONAL, U ) \ BEGIN_OPCODES() \ - {OpcodeInfo::all, {0x70 + ConditionMnemonic_##cc, cb }, { rel8 }, U }, \ - {OpcodeInfo::ia32, {Size16, 0x0F, 0x80 + ConditionMnemonic_##cc, cw}, { rel16 }, U }, \ - {OpcodeInfo::all, {0x0F, 0x80 + ConditionMnemonic_##cc, cd}, { rel32 }, U }, \ + {OpcodeInfo::all, {0x70 + ConditionMnemonic_##cc, cb }, { rel8 }, U }, \ + {OpcodeInfo::ia32, {Size16, 0x0F, 0x80 + ConditionMnemonic_##cc, cw}, { rel16 }, U }, \ + {OpcodeInfo::all, {0x0F, 0x80 + ConditionMnemonic_##cc, cd}, { rel32 }, U }, \ END_OPCODES() \ END_MNEMONIC() @@ -962,45 +962,43 @@ BEGIN_MNEMONIC(LOOP, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xE2, cb}, {ECX, rel8}, DU_U }, + {OpcodeInfo::all, {0xE2, cb}, {ECX, rel8}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(LOOPE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xE1, cb}, {ECX, rel8}, DU_U }, + {OpcodeInfo::all, {0xE1, cb}, {ECX, rel8}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(LOOPNE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xE0, cb}, {ECX, rel8}, DU_U }, + {OpcodeInfo::all, {0xE0, cb}, {ECX, rel8}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(MOV, MF_NONE, D_U) BEGIN_OPCODES() {OpcodeInfo::all, {0x88, _r}, {r_m8,r8}, D_U }, - {OpcodeInfo::all, {Size16, 0x89, _r}, {r_m16,r16}, D_U }, {OpcodeInfo::all, {0x89, _r}, {r_m32,r32}, D_U }, {OpcodeInfo::em64t, {REX_W, 0x89, _r}, {r_m64,r64}, D_U }, + {OpcodeInfo::all, {0x8A, _r}, {r8,r_m8}, D_U }, - {OpcodeInfo::all, {Size16, 0x8B, _r}, {r16,r_m16}, D_U }, {OpcodeInfo::all, {0x8B, _r}, {r32,r_m32}, D_U }, {OpcodeInfo::em64t, {REX_W, 0x8B, _r}, {r64,r_m64}, D_U }, {OpcodeInfo::all, {0xB0|rb}, {r8,imm8}, D_U }, - {OpcodeInfo::all, {Size16, 0xB8|rw}, {r16,imm16}, D_U }, {OpcodeInfo::all, {0xB8|rd}, {r32,imm32}, D_U }, {OpcodeInfo::em64t, {REX_W, 0xB8|rd}, {r64,imm64}, D_U }, + {OpcodeInfo::all, {0xC6, _0}, {r_m8,imm8}, D_U }, - {OpcodeInfo::all, {Size16, 0xC7, _0}, {r_m16,imm16}, D_U }, {OpcodeInfo::all, {0xC7, _0}, {r_m32,imm32}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0xC7, _0}, {r_m64,imm32}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0xC7, _0}, {r_m64,imm32u}, D_U }, {OpcodeInfo::decoder, {0xA0}, {AL, moff8}, D_U }, {OpcodeInfo::decoder, {Size16, 0xA1}, {AX, moff16}, D_U }, @@ -1018,7 +1016,7 @@ BEGIN_MNEMONIC(XCHG, MF_NONE, DU_DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0x87, _r}, {r_m32,r32}, DU_DU }, + {OpcodeInfo::all, {0x87, _r}, {r_m32,r32}, DU_DU }, END_OPCODES() END_MNEMONIC() @@ -1026,11 +1024,11 @@ BEGIN_MNEMONIC(MOVQ, MF_NONE, D_U ) BEGIN_OPCODES() #ifdef _HAVE_MMX_ - {OpcodeInfo::all, {0x0F, 0x6F, _r}, {mm64, mm_m64}, D_U }, - {OpcodeInfo::all, {0x0F, 0x7F, _r}, {mm_m64, mm64}, D_U }, + {OpcodeInfo::all, {0x0F, 0x6F, _r}, {mm64, mm_m64}, D_U }, + {OpcodeInfo::all, {0x0F, 0x7F, _r}, {mm_m64, mm64}, D_U }, #endif - {OpcodeInfo::all, {0xF3, 0x0F, 0x7E }, {xmm64, xmm_m64}, D_U }, - {OpcodeInfo::all, {0x66, 0x0F, 0xD6 }, {xmm_m64, xmm64}, D_U }, + {OpcodeInfo::all, {0xF3, 0x0F, 0x7E }, {xmm64, xmm_m64}, D_U }, + {OpcodeInfo::all, {0x66, 0x0F, 0xD6 }, {xmm_m64, xmm64}, D_U }, // {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r}, {xmm64, r_m64}, D_U }, // {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x7E, _r}, {r_m64, xmm64}, D_U }, {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r}, {xmm64, r64}, D_U }, @@ -1053,7 +1051,7 @@ BEGIN_MNEMONIC(EMMS, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0x77}, {}, N }, + {OpcodeInfo::all, {0x0F, 0x77}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1109,28 +1107,28 @@ BEGIN_MNEMONIC(MOVSX, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {Size16, 0x0F, 0xBE, _r}, {r16, r_m8}, D_U }, - {OpcodeInfo::all, {0x0F, 0xBE, _r}, {r32, r_m8}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBE, _r}, {r64, r_m8}, D_U }, + {OpcodeInfo::all, {Size16, 0x0F, 0xBE, _r}, {r16, r_m8s}, D_U }, + {OpcodeInfo::all, {0x0F, 0xBE, _r}, {r32, r_m8s}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBE, _r}, {r64, r_m8s}, D_U }, - {OpcodeInfo::all, {0x0F, 0xBF, _r}, {r32, r_m16}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBF, _r}, {r64, r_m16}, D_U }, + {OpcodeInfo::all, {0x0F, 0xBF, _r}, {r32, r_m16s}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBF, _r}, {r64, r_m16s}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x63, _r}, {r64, r_m32}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x63, _r}, {r64, r_m32s}, D_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(MOVZX, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {Size16, 0x0F, 0xB6, _r}, {r16, r_m8}, D_U }, - {OpcodeInfo::all, {0x0F, 0xB6, _r}, {r32, r_m8}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB6, _r}, {r64, r_m8}, D_U }, + {OpcodeInfo::all, {Size16, 0x0F, 0xB6, _r}, {r16, r_m8u}, D_U }, + {OpcodeInfo::all, {0x0F, 0xB6, _r}, {r32, r_m8u}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB6, _r}, {r64, r_m8u}, D_U }, - {OpcodeInfo::all, {0x0F, 0xB7, _r}, {r32, r_m16}, D_U }, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB7, _r}, {r64, r_m16}, D_U }, + {OpcodeInfo::all, {0x0F, 0xB7, _r}, {r32, r_m16u}, D_U }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB7, _r}, {r64, r_m16u}, D_U }, //workaround to get r/rm32->r64 ZX mov functionality: //simple 32bit reg copying zeros high bits in 64bit reg - {OpcodeInfo::em64t, {0x8B, _r}, {r64, r_m32}, D_U }, + {OpcodeInfo::em64t, {0x8B, _r}, {r64, r_m32u}, D_U }, END_OPCODES() END_MNEMONIC() @@ -1142,7 +1140,7 @@ BEGIN_MNEMONIC(MULSS, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x59, _r}, {xmm32, xmm_m32}, DU_U }, + {OpcodeInfo::all, {0xF3, 0x0F, 0x59, _r}, {xmm32, xmm_m32}, DU_U }, END_OPCODES() END_MNEMONIC() @@ -1158,16 +1156,16 @@ BEGIN_MNEMONIC(NOP, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x90}, {}, N }, + {OpcodeInfo::all, {0x90}, {}, N }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(NOT, MF_AFFECTS_FLAGS, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF6, _2}, {r_m8}, DU }, - {OpcodeInfo::all, {Size16, 0xF7, _2}, {r_m16}, DU }, - {OpcodeInfo::all, {0xF7, _2}, {r_m32}, DU }, - {OpcodeInfo::em64t, {REX_W, 0xF7, _2}, {r_m64}, DU }, + {OpcodeInfo::all, {0xF6, _2}, {r_m8}, DU }, + {OpcodeInfo::all, {Size16, 0xF7, _2}, {r_m16}, DU }, + {OpcodeInfo::all, {0xF7, _2}, {r_m32}, DU }, + {OpcodeInfo::em64t, {REX_W, 0xF7, _2}, {r_m64}, DU }, END_OPCODES() END_MNEMONIC() @@ -1191,7 +1189,7 @@ BEGIN_MNEMONIC(PREFETCH, MF_NONE, U) BEGIN_OPCODES() -{OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U }, + {OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U }, END_OPCODES() END_MNEMONIC() @@ -1214,22 +1212,22 @@ BEGIN_MNEMONIC(PUSHFD, MF_USES_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x9C}, {}, N }, + {OpcodeInfo::all, {0x9C}, {}, N }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(RET, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xC3}, {}, N }, - {OpcodeInfo::all, {0xC2, iw}, {imm16}, U }, + {OpcodeInfo::all, {0xC3}, {}, N }, + {OpcodeInfo::all, {0xC2, iw}, {imm16}, U }, END_OPCODES() END_MNEMONIC() #define DEFINE_SETcc_MNEMONIC( cc ) \ BEGIN_MNEMONIC(SET##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU) \ BEGIN_OPCODES() \ - {OpcodeInfo::all, {0x0F, 0x90 + ConditionMnemonic_##cc}, {r_m8}, DU }, \ + {OpcodeInfo::all, {0x0F, 0x90 + ConditionMnemonic_##cc}, {r_m8}, DU }, \ END_OPCODES() \ END_MNEMONIC() @@ -1258,22 +1256,22 @@ BEGIN_OPCODES()\ /* D0 & D1 opcodes are added w/o 2nd operand (1) because */\ /* they are used for decoding only so only instruction length is needed */\ - {OpcodeInfo::decoder, {0xD0, slash_num}, {r_m8/*,const_1*/}, DU },\ - {OpcodeInfo::all, {0xD2, slash_num}, {r_m8, CL}, DU_U },\ - {OpcodeInfo::all, {0xC0, slash_num, ib}, {r_m8, imm8}, DU_U },\ + {OpcodeInfo::decoder, {0xD0, slash_num}, {r_m8/*,const_1*/}, DU },\ + {OpcodeInfo::all, {0xD2, slash_num}, {r_m8, CL}, DU_U },\ + {OpcodeInfo::all, {0xC0, slash_num, ib}, {r_m8, imm8}, DU_U },\ \ - {OpcodeInfo::decoder, {Size16, 0xD1, slash_num}, {r_m16/*,const_1*/}, DU },\ - {OpcodeInfo::all, {Size16, 0xD3, slash_num}, {r_m16, CL}, DU_U },\ - {OpcodeInfo::all, {Size16, 0xC1, slash_num, ib}, {r_m16, imm8 }, DU_U },\ + {OpcodeInfo::decoder, {Size16, 0xD1, slash_num}, {r_m16/*,const_1*/}, DU },\ + {OpcodeInfo::all, {Size16, 0xD3, slash_num}, {r_m16, CL}, DU_U },\ + {OpcodeInfo::all, {Size16, 0xC1, slash_num, ib}, {r_m16, imm8 }, DU_U },\ \ {OpcodeInfo::decoder, {0xD1, slash_num}, {r_m32/*,const_1*/}, DU },\ {OpcodeInfo::decoder64, {REX_W, 0xD1, slash_num}, {r_m64/*,const_1*/}, DU },\ \ - {OpcodeInfo::all, {0xD3, slash_num}, {r_m32, CL}, DU_U },\ - {OpcodeInfo::em64t, {REX_W, 0xD3, slash_num}, {r_m64, CL}, DU_U },\ + {OpcodeInfo::all, {0xD3, slash_num}, {r_m32, CL}, DU_U },\ + {OpcodeInfo::em64t, {REX_W, 0xD3, slash_num}, {r_m64, CL}, DU_U },\ \ - {OpcodeInfo::all, {0xC1, slash_num, ib}, {r_m32, imm8}, DU_U },\ - {OpcodeInfo::em64t, {REX_W, 0xC1, slash_num, ib}, {r_m64, imm8}, DU_U },\ + {OpcodeInfo::all, {0xC1, slash_num, ib}, {r_m32, imm8}, DU_U },\ + {OpcodeInfo::em64t, {REX_W, 0xC1, slash_num, ib}, {r_m64, imm8}, DU_U },\ END_OPCODES()\ END_MNEMONIC() @@ -1291,74 +1289,74 @@ BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, ECX}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, ECX}, DU_DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(SHRD, MF_AFFECTS_FLAGS, N) // TODO: the def/use info is wrong BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xAD}, {r_m32, r32, ECX}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xAD}, {r_m32, r32, ECX}, DU_DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(SUBSD, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF2, 0x0F, 0x5C, _r}, {xmm64, xmm_m64}, DU_U }, + {OpcodeInfo::all, {0xF2, 0x0F, 0x5C, _r}, {xmm64, xmm_m64}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(SUBSS, MF_NONE, DU_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF3, 0x0F, 0x5C, _r}, {xmm32, xmm_m32}, DU_U }, + {OpcodeInfo::all, {0xF3, 0x0F, 0x5C, _r}, {xmm32, xmm_m32}, DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(TEST, MF_AFFECTS_FLAGS, U_U) BEGIN_OPCODES() - {OpcodeInfo::decoder, {0xA8, ib}, { AL, imm8}, U_U }, - {OpcodeInfo::decoder, {0xA9, iw}, { AX, imm16}, U_U }, - {OpcodeInfo::decoder, {0xA9, id}, { EAX, imm32}, U_U }, - {OpcodeInfo::decoder64, {REX_W, 0xA9, id}, { RAX, imm32}, U_U }, + {OpcodeInfo::decoder, {0xA8, ib}, { AL, imm8}, U_U }, + {OpcodeInfo::decoder, {0xA9, iw}, { AX, imm16}, U_U }, + {OpcodeInfo::decoder, {0xA9, id}, { EAX, imm32}, U_U }, + {OpcodeInfo::decoder64, {REX_W, 0xA9, id}, { RAX, imm32s}, U_U }, - {OpcodeInfo::all, {0xF6, _0, ib}, {r_m8,imm8}, U_U }, + {OpcodeInfo::all, {0xF6, _0, ib}, {r_m8,imm8}, U_U }, - {OpcodeInfo::all, {Size16, 0xF7, _0, iw}, {r_m16,imm16}, U_U }, - {OpcodeInfo::all, {0xF7, _0, id}, {r_m32,imm32}, U_U }, - {OpcodeInfo::em64t, {REX_W, 0xF7, _0, id}, {r_m64,imm32}, U_U }, + {OpcodeInfo::all, {Size16, 0xF7, _0, iw}, {r_m16,imm16}, U_U }, + {OpcodeInfo::all, {0xF7, _0, id}, {r_m32,imm32}, U_U }, + {OpcodeInfo::em64t, {REX_W, 0xF7, _0, id}, {r_m64,imm32s}, U_U }, - {OpcodeInfo::all, {0x84, _r}, {r_m8,r8}, U_U }, + {OpcodeInfo::all, {0x84, _r}, {r_m8,r8}, U_U }, - {OpcodeInfo::all, {Size16, 0x85, _r}, {r_m16,r16}, U_U }, - {OpcodeInfo::all, {0x85, _r}, {r_m32,r32}, U_U }, - {OpcodeInfo::em64t, {REX_W, 0x85, _r}, {r_m64,r64}, U_U }, + {OpcodeInfo::all, {Size16, 0x85, _r}, {r_m16,r16}, U_U }, + {OpcodeInfo::all, {0x85, _r}, {r_m32,r32}, U_U }, + {OpcodeInfo::em64t, {REX_W, 0x85, _r}, {r_m64,r64}, U_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(UCOMISD, MF_AFFECTS_FLAGS, U_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0x66, 0x0F, 0x2E, _r}, {xmm64, xmm_m64}, U_U }, + {OpcodeInfo::all, {0x66, 0x0F, 0x2E, _r}, {xmm64, xmm_m64}, U_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(UCOMISS, MF_AFFECTS_FLAGS, U_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0x2E, _r}, {xmm32, xmm_m32}, U_U }, + {OpcodeInfo::all, {0x0F, 0x2E, _r}, {xmm32, xmm_m32}, U_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(COMISD, MF_AFFECTS_FLAGS, U_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0x66, 0x0F, 0x2F, _r}, {xmm64, xmm_m64}, U_U }, + {OpcodeInfo::all, {0x66, 0x0F, 0x2F, _r}, {xmm64, xmm_m64}, U_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(COMISS, MF_AFFECTS_FLAGS, U_U) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0x2F, _r}, {xmm32, xmm_m32}, U_U }, + {OpcodeInfo::all, {0x0F, 0x2F, _r}, {xmm32, xmm_m32}, U_U }, END_OPCODES() END_MNEMONIC() @@ -1409,13 +1407,13 @@ // BEGIN_MNEMONIC(STD, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xFD}, {}, N }, + {OpcodeInfo::all, {0xFD}, {}, N }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(CLD, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xFC}, {}, N }, + {OpcodeInfo::all, {0xFC}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1424,7 +1422,7 @@ // but as long, as Jitrino's CG does not use the mnemonic, leaving it // in its natural form BEGIN_OPCODES() - {OpcodeInfo::all, {0xAF}, {}, N }, + {OpcodeInfo::all, {0xAF}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1495,7 +1493,7 @@ BEGIN_MNEMONIC(WAIT, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x9B}, {}, N }, + {OpcodeInfo::all, {0x9B}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1509,13 +1507,13 @@ // BEGIN_MNEMONIC(LEAVE, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::decoder, {0xC9}, {}, N }, + {OpcodeInfo::decoder, {0xC9}, {}, N }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(ENTER, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::decoder, {0xC8, iw, ib}, {imm16, imm8}, N }, + {OpcodeInfo::decoder, {0xC8, iw, ib}, {imm16, imm8}, N }, END_OPCODES() END_MNEMONIC() Index: vm/port/src/encoder/ia32_em64t/encoder.h =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.h (revision 618914) +++ vm/port/src/encoder/ia32_em64t/encoder.h (working copy) @@ -193,7 +193,7 @@ class Opnd { protected: - enum Tag { Imm, Reg, Mem, FP, XMM }; + enum Tag { SignedImm, UnsignedImm, Reg, Mem, FP, XMM }; const Tag tag; @@ -229,18 +229,28 @@ Opnd_Size size; public: - Imm_Opnd(int32 val): Opnd(Imm), value(val), size(size_32) { - if (CHAR_MIN <= val && val <= CHAR_MAX) { - size = size_8; + Imm_Opnd(int32 val, bool isSigned = true): + Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(size_32) { + if (isSigned) { + if (CHAR_MIN <= val && val <= CHAR_MAX) { + size = size_8; + } else if (SHRT_MIN <= val && val <= SHRT_MAX) { + size = size_16; + } + } else { + assert(val >= 0); + if (val <= UCHAR_MAX) { + size = size_8; + } else if (val <= USHRT_MAX) { + size = size_16; + } } - else if (SHRT_MIN <= val && val <= SHRT_MAX) { - size = size_16; - } } - Imm_Opnd(const Imm_Opnd& that): Opnd(Imm), value(that.value), size(that.size) {}; + Imm_Opnd(const Imm_Opnd& that): Opnd(that.tag), value(that.value), size(that.size) {}; #ifdef _EM64T_ - Imm_Opnd(Opnd_Size sz, int64 val): Opnd(Imm), value(val), size(sz) { + Imm_Opnd(Opnd_Size sz, int64 val, bool isSigned = true): + Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) { #ifndef NDEBUG switch (size) { case size_8: @@ -265,7 +275,8 @@ #else - Imm_Opnd(Opnd_Size sz, int32 val): Opnd(Imm), value(val), size(sz) { + Imm_Opnd(Opnd_Size sz, int32 val, int isSigned = true): + Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) { #ifndef NDEBUG switch (size) { case size_8: @@ -287,13 +298,14 @@ int32 get_value() const { return value; } #endif - Opnd_Size get_size(void) const { return size; } + Opnd_Size get_size() const { return size; } + bool is_signed() const { return tag == SignedImm; } }; class RM_Opnd: public Opnd { public: - bool is_reg() const { return tag != Imm && tag != Mem; } + bool is_reg() const { return tag != SignedImm && tag != UnsignedImm && tag != Mem; } protected: RM_Opnd(Tag t): Opnd(t) {} Index: vm/port/src/encoder/ia32_em64t/encoder.inl =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.inl (revision 618914) +++ vm/port/src/encoder/ia32_em64t/encoder.inl (working copy) @@ -98,7 +98,8 @@ inline static void add_imm(EncoderBase::Operands & args, const Imm_Opnd & imm) { assert(n_size != imm.get_size()); - args.add(EncoderBase::Operand(map_size(imm.get_size()), imm.get_value())); + args.add(EncoderBase::Operand(map_size(imm.get_size()), imm.get_value(), + imm.is_signed() ? OpndExt_Signed : OpndExt_Zero)); } ENCODER_DECLARE_EXPORT char * prefix(char * stream, InstrPrefix p) { @@ -736,7 +737,7 @@ ENCODER_DECLARE_EXPORT char * ret(char * stream, unsigned short pop) { // TheManual says it can only be imm16 - EncoderBase::Operands args(EncoderBase::Operand(OpndSize_16, pop)); + EncoderBase::Operands args(EncoderBase::Operand(OpndSize_16, pop, OpndExt_Zero)); return (char*)EncoderBase::encode(stream, Mnemonic_RET, args); }