Index: vm/port/src/encoder/ia32_em64t/enc_base.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.cpp (revision 654458) +++ vm/port/src/encoder/ia32_em64t/enc_base.cpp (working copy) @@ -638,32 +638,41 @@ /** * */ -static bool try_match(const EncoderBase::OpcodeDesc& odesc, - const EncoderBase::Operands& opnds, bool strict) { +bool EncoderBase::extAllowed(OpndExt opndExt, OpndExt instExt) { + if (instExt == opndExt || instExt == OpndExt_Any || opndExt == OpndExt_Any) { + return true; + } +asm("int3"); +//assert(0); + return false; +} + +/** + * + */ +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/encoder.inl =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.inl (revision 654458) +++ vm/port/src/encoder/ia32_em64t/encoder.inl (working copy) @@ -60,7 +60,7 @@ return (INT_MIN <= val) && (val <= INT_MAX); } -inline static void add_r(EncoderBase::Operands & args, const R_Opnd & r, Opnd_Size sz) { +inline static void add_r(EncoderBase::Operands & args, const R_Opnd & r, Opnd_Size sz, OpndExt ext = OpndExt_None) { RegName reg = map_reg(r.reg_no()); if (sz != n_size) { OpndSize size = map_size(sz); @@ -68,18 +68,18 @@ reg = getAliasReg(reg, size); } } - args.add(EncoderBase::Operand(reg)); + args.add(EncoderBase::Operand(reg, ext)); } -inline static void add_m(EncoderBase::Operands & args, const M_Opnd & m, Opnd_Size sz) { +inline static void add_m(EncoderBase::Operands & args, const M_Opnd & m, Opnd_Size sz, OpndExt ext = OpndExt_None) { assert(n_size != sz); args.add(EncoderBase::Operand(map_size(sz), map_reg(m.base().reg_no()), map_reg(m.index().reg_no()), - (unsigned)m.scale().get_value(), (int)m.disp().get_value())); + (unsigned)m.scale().get_value(), (int)m.disp().get_value(), ext)); } -inline static void add_rm(EncoderBase::Operands & args, const RM_Opnd & rm, Opnd_Size sz) { - rm.is_reg() ? add_r(args, (R_Opnd &)rm, sz) : add_m(args, (M_Opnd &)rm, sz); +inline static void add_rm(EncoderBase::Operands & args, const RM_Opnd & rm, Opnd_Size sz, OpndExt ext = OpndExt_None) { + rm.is_reg() ? add_r(args, (R_Opnd &)rm, sz, ext) : add_m(args, (M_Opnd &)rm, sz, ext); } inline static void add_xmm(EncoderBase::Operands & args, const XMM_Opnd & xmm, bool dbl) { @@ -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) { @@ -209,7 +210,7 @@ EncoderBase::Operands args; add_rm(args, rm, sz); assert(imm.get_size() <= sz); - args.add(EncoderBase::Operand(map_size(size_32), imm.get_value())); + add_imm(args, imm); return (char*)EncoderBase::encode(stream, Mnemonic_TEST, args); } @@ -364,7 +365,7 @@ // movzx r64, r/m32 is not available on em64t // mov r32, r/m32 should zero out upper bytes assert(sz <= size_16); - add_rm(args, rm, sz); + add_rm(args, rm, sz, OpndExt_Zero); return (char*)EncoderBase::encode(stream, Mnemonic_MOVZX, args); } @@ -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); } Index: vm/port/src/encoder/ia32_em64t/enc_base.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.h (revision 654458) +++ vm/port/src/encoder/ia32_em64t/enc_base.h (working copy) @@ -103,6 +103,11 @@ static char * prefix(char* stream, InstPrefix pref); /** + * @brief Determines if operand with opndExt suites the position with instExt. + */ + static bool extAllowed(OpndExt opndExt, OpndExt instExt); + + /** * @brief Returns #MnemonicDesc by the given Mnemonic. */ static const MnemonicDesc * getMnemonicDesc(Mnemonic mn) @@ -153,6 +158,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 +310,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 +328,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 +338,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 +363,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 +373,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, OpndExt ext = OpndExt_None) : m_kind(OpndKind_Mem), m_size(size), m_ext(ext) { m_base = base; m_index = index; @@ -376,8 +385,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, OpndExt ext = OpndExt_None) : + m_kind(OpndKind_Mem), m_size(size), m_ext(ext) { m_base = base; m_index = RegName_Null; @@ -397,6 +406,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 +450,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 +508,7 @@ // general info OpndKind m_kind; OpndSize m_size; + OpndExt m_ext; // complex address form support RegName m_base; RegName m_index; @@ -564,7 +583,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/encoder.h =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.h (revision 654458) +++ 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/enc_prvt.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_prvt.h (revision 654458) +++ 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_Any, RegName_AL} +#define AH {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_AH} +#define AX {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_AX} +#define EAX {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EAX} #ifdef _EM64T_ - #define RAX {OpndKind_GPReg, OpndSize_64, RegName_RAX } + #define RAX {OpndKind_GPReg, OpndSize_64, OpndExt_Any, 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_Any, RegName_CL} +#define ECX {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ECX} #ifdef _EM64T_ - #define RCX {OpndKind_GPReg, OpndSize_64, RegName_RCX} + #define RCX {OpndKind_GPReg, OpndSize_64, OpndExt_Any, 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_Any, RegName_DX} +#define EDX {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDX} #ifdef _EM64T_ - #define RDX { OpndKind_GPReg, OpndSize_64, RegName_RDX } + #define RDX { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RDX } #endif -#define ESI {OpndKind_GPReg, OpndSize_32, RegName_ESI} +#define ESI {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ESI} #ifdef _EM64T_ - #define RSI { OpndKind_GPReg, OpndSize_64, RegName_RSI } + #define RSI { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RSI } #endif -#define EDI {OpndKind_GPReg, OpndSize_32, RegName_EDI} +#define EDI {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDI} #ifdef _EM64T_ - #define RDI { OpndKind_GPReg, OpndSize_64, RegName_RDI } + #define RDI { OpndKind_GPReg, OpndSize_64, OpndExt_Any, 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_Any, RegName_Null} +#define r16 {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_Null} +#define r32 {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_Null} #ifdef _EM64T_ - #define r64 { OpndKind_GPReg, OpndSize_64, RegName_Null } + #define r64 { OpndKind_GPReg, OpndSize_64, OpndExt_Any, 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_Any, RegName_Null} +#define r_m16 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Any, RegName_Null} +#define r_m32 {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, 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_Any, RegName_Null} +#define m16 {OpndKind_Mem, OpndSize_16, OpndExt_Any, RegName_Null} +#define m32 {OpndKind_Mem, OpndSize_32, OpndExt_Any, RegName_Null} +#define m64 {OpndKind_Mem, OpndSize_64, OpndExt_Any, 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_Any, 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_Any, RegName_Null} +#define imm16 {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null} +#define imm32 {OpndKind_Imm, OpndSize_32, OpndExt_Any, 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_Any, 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_Any, RegName_Null} +#define moff16 {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null} +#define moff32 {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null} #ifdef _EM64T_ - #define moff64 {OpndKind_Imm, OpndSize_64, RegName_Null} + #define moff64 {OpndKind_Imm, OpndSize_64, OpndExt_Any, 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_Any, RegName_Null} +#define rel16 {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null} +#define rel32 {OpndKind_Imm, OpndSize_32, OpndExt_Any, 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_Any, RegName_Null} +#define mm_m64 {(OpndKind)(OpndKind_MMXReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, 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_Any, RegName_Null} +#define xmm_m64 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, 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_Any, RegName_Null} +#define xmm_m32 {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, 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_Any, RegName_FP0S} +#define FP0D {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP0D} +#define FP1S {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_FP1S} +#define FP1D {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP1D} +#define fp32 {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_Null} +#define fp64 {OpndKind_FPReg, OpndSize_64, OpndExt_Any, 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 654458) +++ 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, {0xFF, _2}, {r_m64}, U }, + {OpcodeInfo::all, {0xE8, cd}, {rel32}, U }, + {OpcodeInfo::ia32, {0xFF, _2}, {r_m32}, U }, + {OpcodeInfo::em64t, {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() @@ -620,43 +620,43 @@ BEGIN_MNEMONIC(FADDP, MF_NONE, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xC1}, {FP0D}, DU }, - {OpcodeInfo::all, {0xDE, 0xC1}, {FP0S}, DU }, + {OpcodeInfo::all, {0xDE, 0xC1}, {FP0D}, DU }, + {OpcodeInfo::all, {0xDE, 0xC1}, {FP0S}, DU }, 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, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xE9}, {FP0D}, DU }, - {OpcodeInfo::all, {0xDE, 0xE9}, {FP0S}, DU }, + {OpcodeInfo::all, {0xDE, 0xE9}, {FP0D}, DU }, + {OpcodeInfo::all, {0xDE, 0xE9}, {FP0S}, DU }, 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(FISUB, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDA, _4}, {FP0S, m32}, DU_U }, -// {OpcodeInfo::all, {0xDE, _4}, {FP0S, m16}, DU_U }, + {OpcodeInfo::all, {0xDA, _4}, {FP0S, m32}, DU_U }, +// {OpcodeInfo::all, {0xDE, _4}, {FP0S, m16}, DU_U }, END_OPCODES() END_MNEMONIC() @@ -664,79 +664,79 @@ 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, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xC9}, {FP0D}, DU }, - {OpcodeInfo::all, {0xDE, 0xC9}, {FP0S}, DU }, + {OpcodeInfo::all, {0xDE, 0xC9}, {FP0D}, DU }, + {OpcodeInfo::all, {0xDE, 0xC9}, {FP0S}, DU }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FDIVP, MF_NONE, DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDE, 0xF9}, {FP0D}, DU }, - {OpcodeInfo::all, {0xDE, 0xF9}, {FP0S}, DU }, + {OpcodeInfo::all, {0xDE, 0xF9}, {FP0D}, DU }, + {OpcodeInfo::all, {0xDE, 0xF9}, {FP0S}, DU }, 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() @@ -748,9 +748,9 @@ BEGIN_MNEMONIC(FILD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, - {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, - {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, + {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, + {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, + {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, END_OPCODES() END_MNEMONIC() @@ -762,56 +762,56 @@ 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() BEGIN_MNEMONIC(FLDLG2, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xEC}, {FP0S}, D }, - {OpcodeInfo::all, {0xD9, 0xEC}, {FP0D}, D }, + {OpcodeInfo::all, {0xD9, 0xEC}, {FP0S}, D }, + {OpcodeInfo::all, {0xD9, 0xEC}, {FP0D}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FLDLN2, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xED}, {FP0S}, D }, - {OpcodeInfo::all, {0xD9, 0xED}, {FP0D}, D }, + {OpcodeInfo::all, {0xD9, 0xED}, {FP0S}, D }, + {OpcodeInfo::all, {0xD9, 0xED}, {FP0D}, D }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(FLD1, MF_NONE, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xE8}, {FP0S}, D }, - {OpcodeInfo::all, {0xD9, 0xE8}, {FP0D}, D }, + {OpcodeInfo::all, {0xD9, 0xE8}, {FP0S}, D }, + {OpcodeInfo::all, {0xD9, 0xE8}, {FP0D}, D }, END_OPCODES() END_MNEMONIC() @@ -824,7 +824,7 @@ BEGIN_MNEMONIC(FPREM1, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0xD9, 0xF5}, {}, N }, + {OpcodeInfo::all, {0xD9, 0xF5}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -949,7 +949,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() @@ -965,53 +965,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() @@ -1074,45 +1074,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, {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, {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 }, @@ -1130,7 +1128,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() @@ -1138,11 +1136,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 }, @@ -1165,7 +1163,7 @@ BEGIN_MNEMONIC(EMMS, MF_NONE, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0x77}, {}, N }, + {OpcodeInfo::all, {0x0F, 0x77}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1207,8 +1205,8 @@ BEGIN_MNEMONIC(MOVAPD, MF_NONE, D_U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0x66, 0x0F, 0x28, _r}, {xmm64, xmm_m64}, D_U }, - {OpcodeInfo::all, {0x66, 0x0F, 0x29, _r}, {xmm_m64, xmm64}, D_U }, + {OpcodeInfo::all, {0x66, 0x0F, 0x28, _r}, {xmm64, xmm_m64}, D_U }, + {OpcodeInfo::all, {0x66, 0x0F, 0x29, _r}, {xmm_m64, xmm64}, D_U }, END_OPCODES() END_MNEMONIC() @@ -1229,28 +1227,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() @@ -1262,7 +1260,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() @@ -1278,16 +1276,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() @@ -1311,7 +1309,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() @@ -1334,22 +1332,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() @@ -1378,22 +1376,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() @@ -1411,50 +1409,50 @@ BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, ECX}, DU_DU_U }, - {OpcodeInfo::all, {0x0F, 0xA4}, {r_m32, r32, imm8}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, CL}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xA4}, {r_m32, r32, imm8}, 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, CL}, 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() @@ -1467,19 +1465,19 @@ 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() @@ -1530,13 +1528,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() @@ -1545,7 +1543,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() @@ -1617,7 +1615,7 @@ BEGIN_MNEMONIC(WAIT, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() - {OpcodeInfo::all, {0x9B}, {}, N }, + {OpcodeInfo::all, {0x9B}, {}, N }, END_OPCODES() END_MNEMONIC() @@ -1631,13 +1629,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/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 654458) +++ 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/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp =================================================================== --- vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp (revision 654458) +++ vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp (working copy) @@ -900,7 +900,7 @@ case LOLT_Immed: { R_Opnd* tmp = get_temp_register(c, *temp_reg); ++*temp_reg; - *buf = mov(*buf, *tmp, Imm_Opnd(loc->u.v)); + *buf = mov(*buf, *tmp, Imm_Opnd(size_32, loc->u.v)); return tmp;} default: DIE(("Unknown type")); for(;;); } @@ -922,9 +922,9 @@ } break;} case LOLT_Immed: { - *buf = mov(*buf, *reg1, Imm_Opnd(loc->u.v)); + *buf = mov(*buf, *reg1, Imm_Opnd(size_32, loc->u.v)); if (two) { - *buf = mov(*buf, *reg2, Imm_Opnd(0)); + *buf = mov(*buf, *reg2, Imm_Opnd(size_32,0)); } break;} case LOLT_Tofs:{ @@ -1053,7 +1053,7 @@ case LO_Mov: // Treat immed->stack specially, the others are done by the movs o1->r->dst if (ii->loc1.t==LOLT_Stack && ii->loc2.t==LOLT_Immed) { - *buf = mov(*buf, M_Base_Opnd(esp_reg, ii->loc1.u.v), Imm_Opnd(ii->loc2.u.v)); + *buf = mov(*buf, M_Base_Opnd(esp_reg, ii->loc1.u.v), Imm_Opnd(size_32,ii->loc2.u.v)); if (type_in_two_regs(ii->t)) { *buf = mov(*buf, M_Base_Opnd(esp_reg, ii->loc1.u.v+4), Imm_Opnd(0)); } @@ -1197,7 +1197,7 @@ { *buf = addr_emit_moves(*buf, &ii->u.address); if (ii->loc3.t==LOLT_Immed) { - Imm_Opnd imm(ii->loc3.u.v); + Imm_Opnd imm(type_to_opnd_size(t),ii->loc3.u.v); *buf = mov(*buf, *(ii->u.address.addr), imm, type_to_opnd_size(t)); } else { R_Opnd* r = move_location_to_a_register(buf, &ctxt, &ii->loc3, &ii->temp_register); Index: vm/vmcore/src/lil/ia32/m2n_ia32.cpp =================================================================== --- vm/vmcore/src/lil/ia32/m2n_ia32.cpp (revision 654458) +++ vm/vmcore/src/lil/ia32/m2n_ia32.cpp (working copy) @@ -204,7 +204,7 @@ buf = push(buf, Imm_Opnd(current_frame_type)); int last_m2n_frame_offset = (int)&((VM_thread*)0)->last_m2n_frame; - Imm_Opnd imm1(last_m2n_frame_offset); + Imm_Opnd imm1(size_32,last_m2n_frame_offset); buf = alu(buf, add_opc, eax_opnd, imm1); Imm_Opnd imm2((unsigned)method); Index: vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp =================================================================== --- vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp (revision 654458) +++ vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp (working copy) @@ -180,8 +180,8 @@ char* patch_offset = ((char *)ss) - 1; // Store location for jump patch *ss++ = (char)0x9C; // PUSHFD M_Base_Opnd m4(esp_reg, 0); - ss = alu(ss, and_opc, m4, Imm_Opnd(FLG_CLEAR_MASK)); - ss = alu(ss, and_opc, ecx_opnd, Imm_Opnd(FLG_SET_MASK)); + ss = alu(ss, and_opc, m4, Imm_Opnd(size_32,FLG_CLEAR_MASK)); + ss = alu(ss, and_opc, ecx_opnd, Imm_Opnd(size_32,FLG_SET_MASK)); ss = alu(ss, or_opc, m4, ecx_opnd); *ss++ = (char)0x9D; // POPFD // Patch conditional jump Index: vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp =================================================================== --- vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp (revision 654458) +++ vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp (working copy) @@ -124,7 +124,7 @@ #ifdef LOCK_RESERVATION ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8); // mov al, byte[ecx+1] - ss = test(ss, eax_opnd, Imm_Opnd(size_8, 0x4), size_8); // test al,0x4 + ss = test(ss, eax_opnd, Imm_Opnd(size_8, 0x4, false), size_8); // test al,0x4 ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); // jnz finish char *finish = ((char *)ss) - 1; Index: vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h (revision 654458) +++ 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_Any), 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_Any), 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_Any) + :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,12 @@ /** returns the mask field of the constraint */ uint32 getMask()const{ return mask; } + /** returns the ext field of the constraint */ + OpndExt getExt()const {return (OpndExt)ext; } + + /** sets the ext field of the constraint */ + void setExt(uint32 e){ext=e; } + /** sets the mask field of the constraint */ void setMask(uint32 m){ mask=m; } @@ -217,7 +233,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/Ia32IRManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (working copy) @@ -96,7 +96,7 @@ //_____________________________________________________________________________________________ Opnd * IRManager::newOpnd(Type * type, Constraint c) { - c.intersectWith(Constraint(OpndKind_Any, getTypeSize(type))); + c.intersectWith(Constraint(OpndKind_Any, getTypeSize(type), extByType(type->tag))); assert(!c.isNull()); Opnd * opnd=new(memoryManager) Opnd(opndId++, type, c); addOpnd(opnd); @@ -234,7 +234,7 @@ //_____________________________________________________________________________________________ Opnd * IRManager::newRegOpnd(Type * type, RegName reg) { - Opnd * opnd = newOpnd(type, Constraint(getRegKind(reg))); + Opnd * opnd = newOpnd(type, Constraint(getRegKind(reg), OpndSize_Any, extByType(type->tag))); opnd->assignRegName(reg); return opnd; } @@ -297,14 +297,16 @@ //_____________________________________________________________________________________________ Constraint IRManager::createInitialConstraint(Type::Tag t)const { - OpndSize sz=getTypeSize(t); + OpndSize sz = getTypeSize(t); + OpndExt ext = extByType(t); + if (t==Type::Single||t==Type::Double||t==Type::Float) - return Constraint(OpndKind_XMMReg, sz)|Constraint(OpndKind_Mem, sz); + return Constraint(OpndKind_XMMReg, sz, ext)|Constraint(OpndKind_Mem, sz, ext); if (sz<=Constraint::getDefaultSize(OpndKind_GPReg)) - return Constraint(OpndKind_GPReg, sz)|Constraint(OpndKind_Mem, sz)|Constraint(OpndKind_Imm, sz); + return Constraint(OpndKind_GPReg, sz, ext)|Constraint(OpndKind_Mem, sz, ext)|Constraint(OpndKind_Imm, sz, ext); if (sz==OpndSize_64) - return Constraint(OpndKind_Mem, sz)|Constraint(OpndKind_Imm, sz); // imm before lowering - return Constraint(OpndKind_Memory, sz); + return Constraint(OpndKind_Mem, sz, ext)|Constraint(OpndKind_Imm, sz, ext); // imm before lowering + return Constraint(OpndKind_Memory, sz, ext); } //_____________________________________________________________________________________________ @@ -1017,10 +1019,25 @@ assert(tmpRegName!=RegName_Null); Opnd * tmp=getRegOpnd(tmpRegName); + + if(sourceOpnd->getSize() != targetOpnd->getSize()) { + assert(sourceOpnd->getSize() > targetOpnd->getSize()); + tmpRegName = getAliasReg(tmpRegName,targetOpnd->getSize()); + assert(tmpRegName!=RegName_Null); + Opnd* shortSrc = newMemOpnd(targetOpnd->getType(), + sourceOpnd->getMemOpndKind(), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Base), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Index), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Scale), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Displacement), + sourceOpnd->getSegReg()); + appendToInstList(instList, newCopyPseudoInst(Mnemonic_MOV, shortSrc, sourceOpnd)); + sourceOpnd = shortSrc; + } + Opnd * tmpAdjusted=newRegOpnd(targetOpnd->getType(), tmpRegName); Opnd * tmpRegStackOpnd = newMemOpnd(tmp->getType(), MemOpndKind_StackAutoLayout, getRegOpnd(STACK_REG), 0); - if (unusedTmpRegName==RegName_Null) appendToInstList(instList, newInst(Mnemonic_MOV, tmpRegStackOpnd, tmp)); @@ -1050,21 +1067,23 @@ } OpndSize sourceSize=sourceConstraint.getSize(); + OpndSize targetSize=targetConstraint.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 +1124,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,47 +1155,80 @@ 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 assert(sourceByteSize<=4); #endif - return newInst(Mnemonic_MOV, targetOpnd, sourceOpnd); // must satisfy constraints + if (sourceSize != targetSize) { + if (sourceOpnd->isPlacedIn(OpndKind_Imm)) { + sourceOpnd = newImmOpnd(targetOpnd->getType(),sourceOpnd->getImmValue()); + } else if (sourceOpnd->isPlacedIn(OpndKind_Reg)) { + if (sourceSize == OpndSize_32 && sourceOpnd->getType()->isInteger()) { + RegName regName = getAliasReg(sourceOpnd->getRegName(), targetSize); + assert(regName != RegName_Null); + Opnd* reg = newOpnd(typeManager.getSignedIntegerType(getByteSize(targetSize)), Constraint(regName)); + reg->assignRegName(regName); + Inst * instList=NULL; + appendToInstList(instList, newCopyPseudoInst(Mnemonic_MOV, reg, sourceOpnd)); + appendToInstList(instList, newInst(Mnemonic_MOV, targetOpnd, reg)); + return instList; + } else { + assert(0); + return NULL; + } + } else if (sourceOpnd->isPlacedIn(OpndKind_Mem)) { + assert(sourceOpnd->getType()->isInteger() && targetOpnd->getType()->isInteger()); + assert(targetOpnd->isPlacedIn(OpndKind_GPReg)); + Opnd* shortSrc = newMemOpnd(targetOpnd->getType(), + sourceOpnd->getMemOpndKind(), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Base), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Index), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Scale), + sourceOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Displacement), + sourceOpnd->getSegReg()); + Inst * instList=NULL; + appendToInstList(instList, newCopyPseudoInst(Mnemonic_MOV, shortSrc, sourceOpnd)); + appendToInstList(instList, newInst(Mnemonic_MOV, targetOpnd, shortSrc)); + return instList; + } + } + assert(targetOpnd->getSize() == sourceOpnd->getSize()); + 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){ return newInst(Mnemonic_MOVSS,targetOpnd, sourceOpnd); }else if (sourceByteSize==8){ - bool regsOnly = targetKind==OpndKind_XMMReg && sourceKind==OpndKind_XMMReg; + bool regsOnly = targetOpnd->isPlacedIn(OpndKind_XMMReg) && sourceOpnd->isPlacedIn(OpndKind_XMMReg); if (regsOnly && CPUID::isSSE2Supported()) { return newInst(Mnemonic_MOVAPD, targetOpnd, sourceOpnd); } else { 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_XMMReg && (sourceKind==OpndKind_Mem || sourceKind==OpndKind_GPReg)){ - if (sourceKind==OpndKind_Mem) + }else if (targetOpnd->isPlacedIn(OpndKind_XMMReg) && sourceOpnd->isPlacedIn(OpndKind_GPReg_Mem)){ + if (sourceOpnd->isPlacedIn(OpndKind_Mem)) sourceOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); return newInst(Mnemonic_MOVD, targetOpnd, sourceOpnd); - }else if ((targetKind==OpndKind_Mem || targetKind==OpndKind_GPReg) && sourceKind==OpndKind_XMMReg){ - if (targetKind==OpndKind_Mem) + }else if (targetOpnd->isPlacedIn(OpndKind_GPReg_Mem) && sourceOpnd->isPlacedIn(OpndKind_XMMReg)){ + if (targetOpnd->isPlacedIn(OpndKind_Mem)) targetOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16); return newInst(Mnemonic_MOVD, 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); @@ -1195,35 +1247,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{ @@ -1254,11 +1305,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{ @@ -1361,6 +1412,7 @@ case Type::Int64: case Type::UInt8: case Type::UInt16: + case Type::Char: case Type::UInt32: case Type::UInt64: case Type::Single: @@ -1372,13 +1424,22 @@ } //_____________________________________________________________________________________________ +OpndSize IRManager::getTypeSizeInMem(Type::Tag tag) +{ + if(tag == Type::Boolean) { + return OpndSize_8; + } else { + return getTypeSize(tag); + } +} + +//_____________________________________________________________________________________________ OpndSize IRManager::getTypeSize(Type::Tag tag) { OpndSize size; switch (tag) { case Type::Int8: case Type::UInt8: - case Type::Boolean: size = OpndSize_8; break; case Type::Int16: @@ -1392,6 +1453,7 @@ #endif case Type::Int32: case Type::UInt32: + case Type::Boolean: // see 3.3.4 of VM Spec size = OpndSize_32; break; #ifdef _EM64T_ @@ -1906,9 +1968,9 @@ Node* dispatchNode= dispatchEdge->getTargetNode(); if ((dispatchNode!=fg->getUnwindNode()) ||(checkOpnds[opnd] == (POINTER_SIZE_INT)-1 #ifdef _EM64T_ - ||!Type::isCompressedReference(opnd->getType()->tag) + ||!Type::isCompressedReference(opnd->getType()->tag) #endif - )){ + )){ Node* throwBasicBlock = fg->createBlockNode(); ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); assert(lastInst->getBCOffset()!=ILLEGAL_BC_MAPPING_VALUE); Index: vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp (revision 654458) +++ 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) { @@ -177,11 +169,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[i]; if (!isOpndAllowed(og, i, co, fi.isExtended, any)) return false; } @@ -189,6 +177,29 @@ } //_________________________________________________________________________________________________ +bool Encoder::matches(Constraint co, Constraint ci) +{ + Constraint cc = ci&co; + return co.isNull() || ( !cc.isNull() && EncoderBase::extAllowed(co.getExt(),ci.getExt()) ); +} + +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 +208,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; } //_________________________________________________________________________________________________ @@ -219,11 +242,12 @@ const Opnd * p = opnds[idx]; Constraint c = p->getConstraint(Opnd::ConstraintKind_Location); + OpndExt ext = p->getConstraint(Opnd::ConstraintKind_Calculated).getExt(); OpndSize sz = inst->opcodeGroup->opndConstraints[args.count()].getSize(); switch( c.getKind() ) { case OpndKind_Imm: - args.add(EncoderBase::Operand(sz, p->getImmValue())); + args.add(EncoderBase::Operand(sz, p->getImmValue(), ext)); break; case OpndKind_Mem: { @@ -262,7 +286,8 @@ baseReg, indexReg, NULL == pscale ? 0 : (unsigned char)pscale->getImmValue(), - disp); + disp, + ext); args.add( o ); // Emit prefix here - so it relates to the real instruction // emitted alter, rather that to the hidden MOV inserted above @@ -280,7 +305,7 @@ // with different size RegName reg = Constraint::getAliasRegName(opndReg, sz); assert(reg != RegName_Null); - args.add(EncoderBase::Operand(reg)); + args.add(EncoderBase::Operand(reg,ext)); } break; } @@ -329,8 +354,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 +444,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/Ia32I8Lowerer.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp (working copy) @@ -1122,6 +1122,7 @@ Opnd* temp_hi = irManager->newOpnd(int32type); Opnd* zero = irManager->newImmOpnd(int32type, 0); Opnd* one = irManager->newImmOpnd(int32type, 1); + Opnd* one8 = irManager->newImmOpnd(tm.getInt8Type(), 1); // newSubGFG(); @@ -1282,10 +1283,10 @@ // ^^^divisor now in edi:ebx and ecx:esi // shift both divisor and dividend right on 1 bit - /* shr edx, 1 */ newInst(Mnemonic_SHR, edx, one); - /* rcr eax, 1 */ newInst(Mnemonic_RCR, eax, one); - /* ror edi, 1 */ newInst(Mnemonic_ROR, edi, one); - /* rcr ebx, 1 */ newInst(Mnemonic_RCR, ebx, one); + /* shr edx, 1 */ newInst(Mnemonic_SHR, edx, one8); + /* rcr eax, 1 */ newInst(Mnemonic_RCR, eax, one8); + /* ror edi, 1 */ newInst(Mnemonic_ROR, edi, one8); + /* rcr ebx, 1 */ newInst(Mnemonic_RCR, ebx, one8); // // FIXME: workarounding WebMaker problem, which does not like @@ -1313,14 +1314,18 @@ /* shrd eax, edx, CL*/ newInst(Mnemonic_SHRD, eax, edx, ecx); /* shr edx, CL */ newInst(Mnemonic_SHR, edx, ecx); #else - Opnd* trueECX = irManager->getRegOpnd(RegName_ECX); +// Opnd* trueECX = irManager->getRegOpnd(RegName_ECX); + Opnd* trueECX = irManager->newOpnd(tm.getInt32Type()/*, Constraint(RegName_ECX)*/); newInst(Mnemonic_MOV, trueECX, ecx); +// Opnd* ecxCL = irManager->getRegOpnd(RegName_CL); + Opnd* ecxCL = irManager->newOpnd(tm.getInt8Type(), Constraint(RegName_CL)); + newInst(Mnemonic_MOV, ecxCL, trueECX); //~FIXME - /* shrd ebx, edi, CL*/ newInst(Mnemonic_SHRD, ebx, edi, trueECX); - /* shrd eax, edx, CL*/ newInst(Mnemonic_SHRD, eax, edx, trueECX); - /* shr edx, CL */ newInst(Mnemonic_SHR, edx, trueECX); + /* shrd ebx, edi, CL*/ newInst(Mnemonic_SHRD, ebx, edi, ecxCL); + /* shrd eax, edx, CL*/ newInst(Mnemonic_SHRD, eax, edx, ecxCL); + /* shr edx, CL */ newInst(Mnemonic_SHR, edx, ecxCL); #endif - /* rol edi, 1 */ newInst(Mnemonic_ROL, edi, one); + /* rol edi, 1 */ newInst(Mnemonic_ROL, edi, one8); // get quotient /* div ebx */ newInst(Mnemonic_DIV, 2, edx, eax, edx, eax, ebx, NULL); /* mov ebx, temp_lo*/ newInst(Mnemonic_MOV, ebx, temp_lo); Index: vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp (revision 654458) +++ 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); } //_________________________________________________________________________________________________ @@ -181,7 +182,7 @@ RegName Constraint::getAliasRegName(RegName regName, uint32 offset)const { RegName rn=getAliasRegName(regName, (OpndSize)size, offset); - return contains(rn)?rn:RegName_Null; + return contains(Constraint(rn,(OpndExt)ext))?rn:RegName_Null; } Index: vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (revision 654458) +++ 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/Ia32PeepHole.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp (working copy) @@ -279,8 +279,7 @@ // 2. Assigned to FPU - convert to FPU operations, to // avoid long FPU->mem->XMM chain // 3. Assigned to XMM - see #1 - const bool xmm_way = - !(src->hasAssignedPhysicalLocation() && src->isPlacedIn(OpndKind_FPReg)); + const bool xmm_way = src->canBePlacedIn(OpndKind_XMMReg); if (!xmm_way) { //TODO: will add FPU later if measurements show it worths trying @@ -509,8 +508,9 @@ nextmovopnd2 = next->getOpnd(nextmovuses.begin()); } if (movopnd1->getId() == nextmovopnd2->getId() && - !isMem(movopnd2) && !isMem(nextmovopnd1) && - !isMem(movopnd1) + !isMem(movopnd2) && !isMem(nextmovopnd1) && !isMem(movopnd1) && + movopnd1->getSize() == movopnd2->getSize() && + nextmovopnd1->getSize() == nextmovopnd2->getSize() ) { BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount()); @@ -667,8 +667,9 @@ if (minBit == maxBit) { assert(minBit>=2); if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 2^"<getTypeManager().getUInt32Type(); - irManager->newInstEx(Mnemonic_SHL, 1, dst, src1, irManager->newImmOpnd(int32Type, minBit))->insertAfter(inst); + Type* immType = irManager->getTypeManager().getUInt8Type(); + irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src1)->insertBefore(inst); + irManager->newInst(Mnemonic_SHL, dst, irManager->newImmOpnd(immType, minBit))->insertBefore(inst); inst->unlink(); return Changed_Inst; } Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (working copy) @@ -344,6 +344,15 @@ } } + static OpndExt extByType(Type::Tag t) { + if( t == Type::Char || t == Type::Boolean || Type::isUnsignedInteger(t) ) { + return OpndExt_Zero; + } else if( Type::isSignedInteger(t) ) { + return OpndExt_Signed; + } + return OpndExt_Any; + } + //----------------------------------------------------------------------------------------------- bool isOnlyPrologSuccessor(Node * bb) ; @@ -457,7 +466,13 @@ /** returns the size of location occupied by an operand of type type */ static OpndSize getTypeSize(Type::Tag tag); static OpndSize getTypeSize(Type * type){ return getTypeSize(type->tag); } + /** returns the size of memory location occupied by an operand of type type. + * There is an issue with Boolean. It must be 1 byte in memory and 4 bytes on reg. + */ + static OpndSize getTypeSizeInMem(Type::Tag tag); + static OpndSize getTypeSizeInMem(Type * type){ return getTypeSizeInMem(type->tag); } + /** checks loop info, returns FALSE if loop info is not valid, should be used in debug assert checks*/ bool ensureLivenessInfoIsValid(); Index: vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp (working copy) @@ -951,6 +951,10 @@ if (!tryRepair(opline, c)) {// Cannot assign operand, so let it remains in the original form DBGOUT("Cannot assign " << opline.opnd << " @ " << *opline.instx->inst << endl;) +if (Log::isEnabled()) { +asm("int3"); + Log::out() << "Cannot assign " << "opline.opnd" << " @ " << "*opline.instx->inst" << std::endl; +} ++fails; if (simplify(opline.instx->inst, opline.opnd)) @@ -1015,7 +1019,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 +1124,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 +1172,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/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32EarlyPropagation.cpp (working copy) @@ -153,8 +153,17 @@ uint32 defOpndId = defOpnd->getId(); OpndInfo * opndInfo = opndInfos + defOpndId; bool instHandled=false; - bool typeConvOk = isTypeConversionAllowed(srcOpnd, defOpnd); - if (typeConvOk && opndInfo->defCount == 1 && ! srcOpnd->isPlacedIn(OpndKind_Reg)){ + bool typeConvOk = srcOpnd->getSize() == defOpnd->getSize() && isTypeConversionAllowed(srcOpnd, defOpnd); + bool kindsAreOk = true; + // this is caused by the fact that FPReg and XMMReg can not be merged in the same Constraint + // there might be a problem with replacing operads of different reg kinds + // if src and def has different reg kinds the inst must be skipped + if(srcOpnd->canBePlacedIn(OpndKind_FPReg) || defOpnd->canBePlacedIn(OpndKind_FPReg)) { + Constraint srcConstr = srcOpnd->getConstraint(Opnd::ConstraintKind_Calculated); + Constraint defConstr = defOpnd->getConstraint(Opnd::ConstraintKind_Calculated); + kindsAreOk = ! (srcConstr&defConstr).isNull(); + } + if (typeConvOk && kindsAreOk && opndInfo->defCount == 1 && ! srcOpnd->isPlacedIn(OpndKind_Reg)){ if (!defOpnd->hasAssignedPhysicalLocation()){ opndInfo->sourceInst = inst; opndInfo->sourceOpndId = srcOpnd->getId(); Index: vm/jitrino/src/codegenerator/ia32/Ia32Encoder.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Encoder.h (revision 654458) +++ 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/Ia32CopyExpansion.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32CopyExpansion.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32CopyExpansion.cpp (working copy) @@ -399,7 +399,13 @@ cmpxchg->setPrefix(inst->getPrefix()); } cmpxchg->insertAfter(inst); - } else if (inst->hasKind(Inst::Kind_CopyPseudoInst)){ +/* } else if ( inst->getMnemonic() == Mnemonic_MOVZX ) { // it's an optimization + Opnd * toOpnd=inst->getOpnd(0); + Opnd * fromOpnd=inst->getOpnd(1); + if (toOpnd->isPlacedIn(OpndKind_Reg) && fromOpnd->isPlacedIn(OpndKind_Reg) && equals(toOpnd->getRegName(),fromOpnd->getRegName()) ) { + continue; + } +*/ } else if (inst->hasKind(Inst::Kind_CopyPseudoInst)){ Mnemonic mn=inst->getMnemonic(); Inst *copySequence = NULL; if (mn==Mnemonic_MOV){ @@ -409,7 +415,7 @@ if (toOpnd == fromOpnd){ continue; } else if (toOpnd->isPlacedIn(OpndKind_Reg) && fromOpnd->isPlacedIn(OpndKind_Reg)){ - if (toOpnd->getRegName()==fromOpnd->getRegName()) + if ( equals(toOpnd->getRegName(),fromOpnd->getRegName()) ) continue; }else{ #ifdef _EM64T_ Index: vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (working copy) @@ -336,7 +336,14 @@ OpndSize srcSize=irManager.getTypeSize(srcType); OpndSize dstSize=irManager.getTypeSize(dstType); - + + if (dstSize!=srcSize && srcOpnd->isPlacedIn(OpndKind_Imm) && dstOpnd == NULL) { + int64 immValue = srcOpnd->getImmValue(); + if (dstSize > srcSize || Type::constFits(immValue, dstType->tag)) { + return irManager.newImmOpnd(dstType, immValue); + } + } + if (dstSize==srcSize){ // trivial conversion if (dstOpnd==NULL && dstType == srcType) { dstOpnd=srcOpnd; @@ -354,10 +361,10 @@ if (dstOpnd==NULL) dstOpnd=irManager.newOpnd(dstType); #ifdef _EM64T_ - appendInsts(irManager.newInstEx(srcType->isSignedInteger() & !isZeroExtend ? Mnemonic_MOVSX:Mnemonic_MOVZX, 1, dstOpnd, srcOpnd)); + appendInsts(irManager.newInstEx(srcType->isSignedInteger() & !isZeroExtend ? Mnemonic_MOVSX:Mnemonic_MOVZX, 1, dstOpnd, srcOpnd)); #else if (dstSizeisSignedInteger() && !isZeroExtend ? Mnemonic_MOVSX:Mnemonic_MOVZX, 1, dstOpnd, srcOpnd)); + appendInsts(irManager.newInst(srcType->isSignedInteger() && !isZeroExtend ? Mnemonic_MOVSX:Mnemonic_MOVZX, dstOpnd, srcOpnd)); }else{ appendInsts(irManager.newI8PseudoInst(srcType->isSignedInteger()?Mnemonic_MOVSX:Mnemonic_MOVZX, 1, dstOpnd, srcOpnd)); } @@ -405,7 +412,8 @@ #endif //load float value to FP0 - Opnd* fpResOpnd = irManager.newOpnd(irManager.getTypeManager().getDoubleType()); + Type* dType = irManager.getTypeManager().getDoubleType(); + Opnd* fpResOpnd = irManager.newRegOpnd(dType, RegName_FP0); Inst* convInst = irManager.newInst(Mnemonic_FILD, fpResOpnd, int64Opnd); appendInsts(convInst); @@ -545,6 +553,10 @@ Opnd * srcOpnd=(Opnd*)oph; Type * srcType=srcOpnd->getType(); + if (dstOpnd==NULL && dstType == srcType) { + dstOpnd=srcOpnd; + return dstOpnd; + } bool converted=false; if (isIntegerType(srcType)){ if (isIntegerType(dstType)){ @@ -983,8 +995,9 @@ case NegOp::F: { Type * dstType=irManager.getTypeFromTag(Type::Double); - dst = irManager.newOpnd(dstType); - appendInsts(irManager.newInstEx(Mnemonic_FCHS,1,dst,(Opnd*)src)); + dst = irManager.newOpnd(dstType, Constraint(OpndKind_FPReg, ((Opnd*)src)->getSize(), OpndExt_None)); + copyOpnd(dst,(Opnd*)src); + appendInsts(irManager.newInst(Mnemonic_FCHS,dst)); break; } case NegOp::S: @@ -1188,9 +1201,9 @@ dstType=irManager.getTypeFromTag(Type::Int64); dst=irManager.newOpnd(dstType); #ifndef _EM64T_ - appendInsts(irManager.newI8PseudoInst(mn,1,dst,(Opnd*)convert(value, dstType),(Opnd*)convert(shiftAmount, typeManager.getInt32Type()))); + appendInsts(irManager.newI8PseudoInst(mn,1,dst,(Opnd*)convert(value, dstType),(Opnd*)convert(shiftAmount, typeManager.getInt8Type()))); #else - appendInsts(irManager.newInstEx(mn,1,dst,(Opnd*)convert(value, dstType),(Opnd*)convert(shiftAmount, typeManager.getInt32Type()))); + appendInsts(irManager.newInstEx(mn,1,dst,(Opnd*)convert(value, dstType),(Opnd*)convert(shiftAmount, typeManager.getInt8Type()))); #endif return dst; default: @@ -1268,13 +1281,15 @@ CG_OpndHandle* src1, CG_OpndHandle* src2, int ifNaNResult) { + Opnd * dst8=irManager.newOpnd(typeManager.getUInt8Type()); Opnd * dst=irManager.newOpnd(typeManager.getInt32Type()); bool swapped=cmpToEflags(cmpOp, opType, (Opnd*)src1, (Opnd*)src2); ConditionMnemonic cm=getConditionMnemonicFromCompareOperator(cmpOp, opType); if (swapped) cm=swapConditionMnemonic(cm); - appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt32Type(), 0))); - appendInsts(irManager.newInstEx(getMnemonic(Mnemonic_SETcc, cm), 1, dst,dst)); + appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst8, irManager.newImmOpnd(typeManager.getUInt8Type(), 0))); + appendInsts(irManager.newInstEx(getMnemonic(Mnemonic_SETcc, cm), 1, dst8,dst8)); + appendInsts(irManager.newInstEx(Mnemonic_MOVZX, 1, dst, dst8)); if (ifNaNResult == 1 || (ifNaNResult ==0 && ((opType==CompareOp::F) ||(opType==CompareOp::S) ||(opType==CompareOp::D)) && ((cmpOp == CompareOp::Geu) || (cmpOp == CompareOp::Gtu) || (cmpOp == CompareOp::Ne) || (cmpOp == CompareOp::Eq)))) { appendInsts(irManager.newInstEx(Mnemonic_CMOVP,1,dst,dst,irManager.newImmOpnd(typeManager.getInt32Type(), ifNaNResult))); } @@ -1992,7 +2007,7 @@ && !elemType->isCompressedReference()) { elemSize = 4; } else { - elemSize = getByteSize(irManager.getTypeSize(elemType)); + elemSize = getByteSize(irManager.getTypeSizeInMem(elemType)); } Opnd * elemSizeOpnd = irManager.newImmOpnd(indexType, elemSize); @@ -2032,7 +2047,7 @@ PtrType * ptrType=type->asPtrType(); Type * elemType = ptrType->getPointedToType(); - uint32 elemSize=getByteSize(irManager.getTypeSize(elemType)); + uint32 elemSize=getByteSize(irManager.getTypeSizeInMem(elemType)); Type * indexType = #ifdef _EM64T_ Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (working copy) @@ -38,7 +38,7 @@ assert(r!=RegName_Null); memOpndKind=MemOpndKind_Null; regName=r; - constraints[ConstraintKind_Location]=Constraint(r); + constraints[ConstraintKind_Location]=Constraint(r,constraints[ConstraintKind_Calculated].getExt()); checkConstraints(); } @@ -49,7 +49,9 @@ if (constraints[ConstraintKind_Location].getKind() != OpndKind_Imm) runtimeInfo=NULL; immValue=v; - constraints[ConstraintKind_Location]=Constraint(OpndKind_Imm, constraints[ConstraintKind_Initial].getSize()); + constraints[ConstraintKind_Location]=Constraint(OpndKind_Imm, + constraints[ConstraintKind_Initial].getSize(), + constraints[ConstraintKind_Initial].getExt()); checkConstraints(); } @@ -59,7 +61,9 @@ assert(_base||_index||_displacement); assert(!_scale||_index); - constraints[ConstraintKind_Location]=Constraint(OpndKind_Mem, constraints[ConstraintKind_Initial].getSize()); + constraints[ConstraintKind_Location]=Constraint(OpndKind_Mem, + constraints[ConstraintKind_Initial].getSize(), + constraints[ConstraintKind_Initial].getExt()); memOpndKind=k; checkConstraints(); @@ -291,7 +295,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/Ia32CodeEmitter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (revision 654458) +++ vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (working copy) @@ -490,7 +490,9 @@ inst->setCodeOffset( (uint32)(instStartIp-blockStartIp) ); continue; } - +if(inst->getId() == 24 && inst->getMnemonic() == Mnemonic_MOVSS) { +asm("int3"); +} if (inst->hasKind(Inst::Kind_ControlTransferInst) && ((ControlTransferInst*)inst)->isDirect() && inst->getMnemonic() == Mnemonic_CALL) Index: vm/jitrino/src/codegenerator/ia32/Ia32RegAlloc2.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32RegAlloc2.cpp (revision 654458) +++ 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/jet/jdefs.h =================================================================== --- vm/jitrino/src/jet/jdefs.h (revision 654458) +++ vm/jitrino/src/jet/jdefs.h (working copy) @@ -583,6 +583,14 @@ extern JTypeDesc jtypes[num_jtypes]; /** + *@brief Tests whether specified #jtype represents signed integer value. + */ +inline bool is_signed_int( jtype jt ) +{ + return jt==i8 || jt==i16 || jt==i32 || jt==i64; +} + +/** *@brief Tests whether specified #jtype represents floating point value. */ inline bool is_f( jtype jt ) Index: vm/jitrino/src/jet/enc_ia32.cpp =================================================================== --- vm/jitrino/src/jet/enc_ia32.cpp (revision 654458) +++ vm/jitrino/src/jet/enc_ia32.cpp (working copy) @@ -114,38 +114,46 @@ assert(!op0.is_imm()); } +static OpndExt default_arg_ext(jtype t) { + if (is_signed_int(t)) return OpndExt_Signed; + else if ( t == u16) return OpndExt_Zero; + else return OpndExt_None; +} + static void add_arg(EncoderBase::Operands& args, const Opnd& op, bool can_shrink = false) { OpndSize sz = to_size(op.jt()); + OpndExt ext = default_arg_ext(op.jt()); if (op.is_reg()) { RegName reg = devirt(op.reg(), op.jt()); //::OpndKind kind = is_f(op.reg()) ? OpndKind_XMMReg : OpndKind_GPReg; - //args.add(EncoderBase::Operand(sz, kind, reg)); - args.add(EncoderBase::Operand(reg)); + //args.add(EncoderBase::Operand(sz, kind, reg, ext)); + args.add(EncoderBase::Operand(reg, ext)); } else if (op.is_mem()) { RegName base = op.base() != ar_x ? devirt(op.base()) : RegName_Null; RegName idx = op.index() == ar_x ? RegName_Null : devirt(op.index()); - EncoderBase::Operand mem(sz, base, idx, op.scale(), op.disp()); + EncoderBase::Operand mem(sz, base, idx, op.scale(), op.disp(), ext); args.add(mem); } else { assert(!is_f(op.jt())); if (op.jt() == i64) { - EncoderBase::Operand imm(sz, op.lval()); + EncoderBase::Operand imm(sz, op.lval(), ext); args.add(imm); } else if (op.jt() == jobj) { - EncoderBase::Operand imm(sz, (int_ptr)(void*)op.lval()); + EncoderBase::Operand imm(sz, (int_ptr)(void*)op.lval(), ext); args.add(imm); } else { assert(op.jt()<=i32); if (can_shrink && fits_i8(op.ival())) { sz = OpndSize_8; + ext = OpndExt_Any; } - EncoderBase::Operand imm(sz, op.ival()); + EncoderBase::Operand imm(sz, op.ival(), ext); args.add(imm); } } Index: vm/jitrino/src/optimizer/IRBuilder.h =================================================================== --- vm/jitrino/src/optimizer/IRBuilder.h (revision 654458) +++ vm/jitrino/src/optimizer/IRBuilder.h (working copy) @@ -403,7 +403,6 @@ // Opnd* propagateCopy(Opnd*); Inst* appendInst(Inst*); - Type* getOpndTypeFromLdType(Type* ldType); Opnd* createOpnd(Type*); PiOpnd* createPiOpnd(Opnd *org); Opnd* createTypeOpnd(ObjectType* type); Index: vm/jitrino/src/shared/Type.cpp =================================================================== --- vm/jitrino/src/shared/Type.cpp (revision 654458) +++ vm/jitrino/src/shared/Type.cpp (working copy) @@ -1321,5 +1321,17 @@ return type_tag_names[t].name; } +bool Type::constFits(int64 val, Tag tag) { + if (tag == Int8 || tag == UInt8) { + return (val & (int64)0x00000000000000FF) == val; + } else if (tag == Int16 || tag == UInt16 || tag == Char) { + return (val & (int64)0x000000000000FFFF) == val; + } else if (isIntegerOf4Bytes(tag)) { + return (val & (int64)0x00000000FFFFFFFF) == val; + } else { + assert(0); // implement if you need it + } + return false; +} } //namespace Jitrino Index: vm/jitrino/src/shared/Type.h =================================================================== --- vm/jitrino/src/shared/Type.h (revision 654458) +++ vm/jitrino/src/shared/Type.h (working copy) @@ -59,15 +59,15 @@ // (1) Value types // -------------------- // (1.1) Built-in value types - Tau, // essentially a void type, used for + Tau, // essentially a void type, used for Void, Boolean, - Char, - IntPtr, // ptr-sized integer + Char, // unsigned 2-byte integer + IntPtr, // ptr-sized integer Int8, Int16, - Int32, // 4-byte integer - Int64, // 8-byte integer + Int32, // 4-byte integer + Int64, // 8-byte integer UIntPtr, // unsigned ptr-sized integer UInt8, UInt16, @@ -383,8 +383,10 @@ #endif static bool isIntegerOf4Bytes(Tag tag) { return isIntegerOf4Signed(tag) || isIntegerOf4Unsigned(tag); } static bool isIntegerOf8Bytes(Tag tag) { return isIntegerOf8Signed(tag) || isIntegerOf8Unsigned(tag); } - + // checks if a constant fits into type + static bool constFits(int64 val, Tag tag); + protected: virtual bool _isFinalClass() {return false;} @@ -791,6 +793,18 @@ void setLazyResolutionMode(bool flag) {lazyResolutionMode = flag;} bool isLazyResolutionMode() const {return lazyResolutionMode;} + Type* getIntegerType(int size, bool isSigned) { + switch (size) { + case 1: return isSigned ? int8Type : uint8Type; + case 2: return isSigned ? int16Type : uint16Type; + case 4: return isSigned ? int32Type : uint32Type; + case 8: return isSigned ? int64Type : uint64Type; + default: assert(0); return int32Type; + } + } + Type* getSignedIntegerType(int size) { return getIntegerType(size, true); } + Type* getUnsignedIntegerType(int size) { return getIntegerType(size, false);} + private: MemoryManager& memManager; // singletons for the built-in types