int main()
{
	const char *p = "add [ebp-02h], 20";
	ASM_DATA *asms = CreateAsmData();

	GetOpcode(&p);
	GetRegister(&p, &(asms->registers[0]));
}
void WorldPackets::Channel::ChannelPlayerCommand::Read()
{
    switch (GetOpcode())
    {
        case CMSG_CHAT_CHANNEL_BAN:
        case CMSG_CHAT_CHANNEL_INVITE:
        case CMSG_CHAT_CHANNEL_KICK:
        case CMSG_CHAT_CHANNEL_MODERATOR:
        case CMSG_CHAT_CHANNEL_MUTE:
        case CMSG_CHAT_CHANNEL_SET_OWNER:
        case CMSG_CHAT_CHANNEL_SILENCE_ALL:
        case CMSG_CHAT_CHANNEL_SILENCE_VOICE:
        case CMSG_CHAT_CHANNEL_UNBAN:
        case CMSG_CHAT_CHANNEL_UNMODERATOR:
        case CMSG_CHAT_CHANNEL_UNMUTE:
        case CMSG_CHAT_CHANNEL_UNSILENCE_ALL:
        case CMSG_CHAT_CHANNEL_UNSILENCE_VOICE:
        {
            uint32 channelNameLength = _worldPacket.ReadBits(7);
            uint32 nameLength = _worldPacket.ReadBits(9);
            ChannelName = _worldPacket.ReadString(channelNameLength);
            Name = _worldPacket.ReadString(nameLength);
            break;
        }
        case CMSG_CHAT_CHANNEL_ANNOUNCEMENTS:
        case CMSG_CHAT_CHANNEL_DECLINE_INVITE:
        case CMSG_CHAT_CHANNEL_DISPLAY_LIST:
        case CMSG_CHAT_CHANNEL_LIST:
        case CMSG_CHAT_CHANNEL_MODERATE:
        case CMSG_CHAT_CHANNEL_OWNER:
        case CMSG_CHAT_CHANNEL_VOICE_OFF:
        case CMSG_CHAT_CHANNEL_VOICE_ON:
        {
            ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7));
            break;
        }
        case CMSG_CHAT_CHANNEL_PASSWORD:
        {
            uint32 channelNameLength = _worldPacket.ReadBits(7);
            uint32 nameLength = _worldPacket.ReadBits(7);
            ChannelName = _worldPacket.ReadString(channelNameLength);
            Name = _worldPacket.ReadString(nameLength);
            break;
        }
        default:
            break;
    }
}
WorldPackets::Channel::ChannelPlayerCommand::ChannelPlayerCommand(WorldPacket&& packet) : ClientPacket(std::move(packet))
{
    switch (GetOpcode())
    {
        case CMSG_CHAT_CHANNEL_BAN:
        case CMSG_CHAT_CHANNEL_INVITE:
        case CMSG_CHAT_CHANNEL_KICK:
        case CMSG_CHAT_CHANNEL_MODERATOR:
        case CMSG_CHAT_CHANNEL_SET_OWNER:
        case CMSG_CHAT_CHANNEL_SILENCE_ALL:
        case CMSG_CHAT_CHANNEL_UNBAN:
        case CMSG_CHAT_CHANNEL_UNMODERATOR:
        case CMSG_CHAT_CHANNEL_UNSILENCE_ALL:
            break;
        default:
            ABORT();
            break;
    }
}
std::string Thumb::LoadStoreMultipleInstruction::ToString() const
{
    std::stringstream stream;
    stream << Thumb::ToString(GetOpcode()) << " R" << GetRegister() << "!, {" ;

    std::bitset<8> registersBits(GetRegisterList());
    while (registersBits.count() > 0)
    {
        uint8_t bitIndex = 0;
        for (; bitIndex < 8 && !registersBits.test(bitIndex); ++bitIndex);

        stream << "R" << +bitIndex;
        registersBits[bitIndex] = false;
        if (registersBits.count() != 0)
            stream << ", ";
    }
    stream << "}";
    return stream.str();
}
Exemple #5
0
void WorldPacket::compress(uint32 opcode)
{
    if (opcode == OPCODE_NOT_FOUND)  // this just doesn't look right, atm not using that define opcode way.
        return;

    uint32 uncompressedOpcode = GetOpcode();
    uint32 size = wpos();
    uint32 destsize = compressBound(size);

    std::vector<uint8> storage(destsize);

    _compress(static_cast<void*>(&storage[0]), &destsize, static_cast<const void*>(contents()), size);
    if (destsize == 0)
        return;

    clear();
    reserve(destsize + sizeof(uint32));
    *this << uint32(size);
    append(&storage[0], destsize);
    SetOpcode(opcode);

    sLog->outStaticDebug("Successfully compressed opcode %u (len %u) to %u (len %u)",
        uncompressedOpcode, size, opcode, destsize);
}
Exemple #6
0
void WorldPacket::compress(Opcodes opcode)
{
    if (opcode == UNKNOWN_OPCODE)
        return;

    Opcodes uncompressedOpcode = GetOpcode();
    uint32 size = wpos();
    uint32 destsize = compressBound(size);

    std::vector<uint8> storage(destsize);

    _compress(static_cast<void*>(&storage[0]), &destsize, static_cast<const void*>(contents()), size);
    if (destsize == 0)
        return;

    clear();
    reserve(destsize + sizeof(uint32));
    *this << uint32(size);
    append(&storage[0], destsize);
    SetOpcode(opcode);

    sLog->outStaticDebug("Successfully compressed opcode %u (len %u) to %u (len %u)",
        uncompressedOpcode, size, opcode, destsize);
}
void ParseScript()
{
	char str[512];
	
	while(!feof(infile))
	{	
		memset(str,'\0',512);
		fgets(str,512,infile);
		
		switch(GetType(str))
		{
			case 1:
			{
				int opcode = GetID(str);
				
				if(opcode!=-1)
				{
					Push(&bytestack,opcode,1);
					PushArgs(&bytestack,str,opcode,4);
				}
			}
			break;
			
			case 2:
			{
				char *name = GetFuncName(str);
				int opcode = GetOpcode(name);
				
				Push(&bytestack,opcode,1);
				PushArgs(&bytestack,str,opcode,strlen(name));
				
				free(name);
			}
			break;
			
			case 3:
			{
				int id = GetID(str);
				
				if(id!=-1)
				{
					PushInt(&labelstack,bytestack.size,id);
					scrhead.labels.size++;
				}
				else
				{
					printf("Problem parsing label: %s",str);
					exit(1);
				}
			}
			break;
				
			case 4:
			{
				int id = GetID(str);
				
				if(id!=-1)
				{
					//Push(&markerstack,id,4);
					markerstack[id] = bytestack.size;
					scrhead.markers.size = 100;
				}
				else
				{
					printf("Problem parsing marker: %s",str);
					exit(1);
				}
			}
			break;
				
			case 5:
			{
				FILE *textfile = NULL;
				
				while(str[strlen(str)-1]=='\r' || str[strlen(str)-1]=='\n')
					str[strlen(str)-1] = '\0';
					
				textfile = fopen(str+9,"rb");
				
				if(!textfile)
				{
					printf("Could not open %s\n",str+9);
					exit(1);
				}
				
				ParseText(textfile);
				fclose(textfile);
			}
			break;
			
			case 6:
			{
				int t = 0;
				sscanf(str+1,"%x",&t);
				
				if(scrhead.unk12.size==0)
					unk12stack = (int*)calloc(1,sizeof(int));
				else
					unk12stack = (int*)realloc(unk12stack,(scrhead.unk12.size+1)*sizeof(int));
				
				unk12stack[scrhead.unk12.size++] = t;
			}
			break;
			
			case 7:
			{
				int t = 0;
				sscanf(str+1,"%x",&t);
				
				if(scrhead.unk13.size==0)
					unk13stack = (int*)calloc(1,sizeof(int));
				else
					unk13stack = (int*)realloc(unk13stack,(scrhead.unk13.size+1)*sizeof(int));
					
				unk13stack[scrhead.unk13.size++] = t;
			}
			break;
		
			default:
				break;
		}
	}
}
#include "catch/catch.hpp"
#include "Common/Instructions/ARM/DataProcessingInstructions.hpp"
#include "Common/MathHelper.hpp"

TEST_CASE("Data Processing Instructions", "Checks that the data processing instruction structures are working")
{
    auto and = new ARM::DataProcessingInstruction(0xE2004020);

    REQUIRE(and->GetOpcode() == ARM::ARMOpcodes::AND);
    REQUIRE(and->GetFirstOperand() == 0);
    REQUIRE(and->IsImmediate() == true);
    REQUIRE(and->GetDestinationRegister() == 4);
    REQUIRE(and->GetShiftedSecondOperandImmediate() == 32);
    delete and;

    auto mov = new ARM::DataProcessingInstruction(0xE1A00005);
    REQUIRE(mov->GetOpcode() == ARM::ARMOpcodes::MOV);
    REQUIRE(mov->GetFirstOperand() == 0);
    REQUIRE(mov->IsImmediate() == false);
    REQUIRE(mov->GetSecondOperand() == 5);
    delete mov;
}
WorldPackets::Character::EnumCharacters::EnumCharacters(WorldPacket&& packet) : ClientPacket(std::move(packet))
{
    ASSERT(GetOpcode() == CMSG_ENUM_CHARACTERS || GetOpcode() == CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT);
}
Exemple #10
0
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(PacketFilter& updater)
{
    std::lock_guard<std::mutex> guard(m_recvQueueLock);

    ///- Retrieve packets from the receive queue and call the appropriate handlers
    /// not process packets if socket already closed
    while (m_Socket && !m_Socket->IsClosed() && !m_recvQueue.empty())
    {
        auto const packet = std::move(m_recvQueue.front());
        m_recvQueue.pop_front();

        /*#if 1
        sLog.outError( "MOEP: %s (0x%.4X)",
                        packet->GetOpcodeName(),
                        packet->GetOpcode());
        #endif*/

        OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
        try
        {
            switch (opHandle.status)
            {
                case STATUS_LOGGEDIN:
                    if (!_player)
                    {
                        // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
                        if (!m_playerRecentlyLogout)
                            LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    }
                    else if (_player->IsInWorld())
                        ExecuteOpcode(opHandle, *packet);

                    // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
                    break;
                case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
                    if (!_player && !m_playerRecentlyLogout)
                    {
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet and not recently logout");
                    }
                    else
                        // not expected _player or must checked in packet hanlder
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_TRANSFER:
                    if (!_player)
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    else if (_player->IsInWorld())
                        LogUnexpectedOpcode(*packet, "the player is still in world");
                    else
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_AUTHED:
                    // prevent cheating with skip queue wait
                    if (m_inQueue)
                    {
                        LogUnexpectedOpcode(*packet, "the player not pass queue yet");
                        break;
                    }

                    // single from authed time opcodes send in to after logout time
                    // and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
                    if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
                        m_playerRecentlyLogout = false;

                    ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_NEVER:
                    sLog.outError("SESSION: received not allowed opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
                case STATUS_UNHANDLED:
                    DEBUG_LOG("SESSION: received not handled opcode %s (0x%.4X)",
                              packet->GetOpcodeName(),
                              packet->GetOpcode());
                    break;
                default:
                    sLog.outError("SESSION: received wrong-status-req opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
            }
        }
        catch (ByteBufferException&)
        {
            sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i.",
                          packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
            if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
            {
                DEBUG_LOG("Dumping error causing packet:");
                packet->hexlike();
            }

            if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
            {
                DETAIL_LOG("Disconnecting session [account id %u / address %s] for badly formatted packet.",
                           GetAccountId(), GetRemoteAddress().c_str());

                KickPlayer();
            }
        }
    }

    // check if we are safe to proceed with logout
    // logout procedure should happen only in World::UpdateSessions() method!!!
    if (updater.ProcessLogout())
    {
        ///- If necessary, log the player out
        const time_t currTime = time(nullptr);

        if (m_Socket->IsClosed() || (ShouldLogOut(currTime) && !m_playerLoading))
            LogoutPlayer(true);

        // finalize the session if disconnected.
        if (m_Socket->IsClosed())
            return false;
    }

    return true;
}
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(PacketFilter& updater)
{
    std::lock_guard<std::mutex> guard(m_recvQueueLock);

    ///- Retrieve packets from the receive queue and call the appropriate handlers
    /// not process packets if socket already closed
    while (m_Socket && !m_Socket->IsClosed() && !m_recvQueue.empty())
    {
        auto const packet = std::move(m_recvQueue.front());
        m_recvQueue.pop_front();

        /*#if 1
        sLog.outError( "MOEP: %s (0x%.4X)",
                        packet->GetOpcodeName(),
                        packet->GetOpcode());
        #endif*/

        OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
        try
        {
            switch (opHandle.status)
            {
                case STATUS_LOGGEDIN:
                    if (!_player)
                    {
                        // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
                        if (!m_playerRecentlyLogout)
                            LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    }
                    else if (_player->IsInWorld())
                        ExecuteOpcode(opHandle, *packet);

                    // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer

#ifdef BUILD_PLAYERBOT
                    if (_player && _player->GetPlayerbotMgr())
                        _player->GetPlayerbotMgr()->HandleMasterIncomingPacket(*packet);
#endif
                    break;
                case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
                    if (!_player && !m_playerRecentlyLogout)
                    {
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet and not recently logout");
                    }
                    else
                        // not expected _player or must checked in packet hanlder
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_TRANSFER:
                    if (!_player)
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    else if (_player->IsInWorld())
                        LogUnexpectedOpcode(*packet, "the player is still in world");
                    else
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_AUTHED:
                    // prevent cheating with skip queue wait
                    if (m_inQueue)
                    {
                        LogUnexpectedOpcode(*packet, "the player not pass queue yet");
                        break;
                    }

                    // single from authed time opcodes send in to after logout time
                    // and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
                    if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
                        m_playerRecentlyLogout = false;

                    ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_NEVER:
                    sLog.outError("SESSION: received not allowed opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
                case STATUS_UNHANDLED:
                    DEBUG_LOG("SESSION: received not handled opcode %s (0x%.4X)",
                              packet->GetOpcodeName(),
                              packet->GetOpcode());
                    break;
                default:
                    sLog.outError("SESSION: received wrong-status-req opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
            }
        }
        catch (ByteBufferException&)
        {
            sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i.",
                          packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
            if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
            {
                DEBUG_LOG("Dumping error causing packet:");
                packet->hexlike();
            }

            if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
            {
                DETAIL_LOG("Disconnecting session [account id %u / address %s] for badly formatted packet.",
                           GetAccountId(), GetRemoteAddress().c_str());

                KickPlayer();
            }
        }
    }

#ifdef BUILD_PLAYERBOT
    // Process player bot packets
    // The PlayerbotAI class adds to the packet queue to simulate a real player
    // since Playerbots are known to the World obj only by its master's WorldSession object
    // we need to process all master's bot's packets.
    if (GetPlayer() && GetPlayer()->GetPlayerbotMgr())
    {
        for (PlayerBotMap::const_iterator itr = GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsBegin();
                itr != GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsEnd(); ++itr)
        {
            Player* const botPlayer = itr->second;
            WorldSession* const pBotWorldSession = botPlayer->GetSession();
            if (botPlayer->IsBeingTeleported())
                botPlayer->GetPlayerbotAI()->HandleTeleportAck();
            else if (botPlayer->IsInWorld())
            {
                while (!pBotWorldSession->m_recvQueue.empty())
                {
                    auto const botpacket = std::move(pBotWorldSession->m_recvQueue.front());
                    pBotWorldSession->m_recvQueue.pop_front();

                    OpcodeHandler const& opHandle = opcodeTable[botpacket->GetOpcode()];
                    pBotWorldSession->ExecuteOpcode(opHandle, *botpacket);
                };
                pBotWorldSession->m_recvQueue.clear();
            }
        }
    }
#endif

    // check if we are safe to proceed with logout
    // logout procedure should happen only in World::UpdateSessions() method!!!
    if (updater.ProcessLogout())
    {
        switch (m_sessionState)
        {
            case WORLD_SESSION_STATE_CREATED:
            {
                if (m_requestSocket)
                {
                    if (!IsOffline())
                        SetOffline();

                    m_Socket = m_requestSocket;
                    m_requestSocket = nullptr;
                    sLog.outString("New Session key %s", m_Socket->GetSessionKey().AsHexStr());
                    SendAuthOk();
                }
                else
                {
                    if (m_inQueue)
                        SendAuthQueued();
                    else
                        SendAuthOk();
                }
                m_sessionState = WORLD_SESSION_STATE_CHAR_SELECTION;
                return true;
            }

            case WORLD_SESSION_STATE_CHAR_SELECTION:

                // waiting to go online
                // TODO:: Maybe check if have to send queue update?
                if (!m_Socket || (m_Socket && m_Socket->IsClosed()))
                {
                    // directly remove this session
                    return false;
                }

                if (ShouldLogOut(time(nullptr)) && !m_playerLoading)   // check if delayed logout is fired
                    LogoutPlayer(true);

                return true;

            case WORLD_SESSION_STATE_READY:
            {
                if (m_Socket && m_Socket->IsClosed())
                {
                    if (!_player)
                        return false;

                    // give the opportunity for this player to reconnect within 20 sec
                    SetOffline();
                }
                else if (ShouldLogOut(time(nullptr)) && !m_playerLoading)   // check if delayed logout is fired
                    LogoutPlayer(true);

                return true;
            }

            case WORLD_SESSION_STATE_OFFLINE:
            {
                if (ShouldDisconnect(time(nullptr)))   // check if delayed logout is fired
                {
                    LogoutPlayer(true);
                    if (!m_requestSocket && (!m_Socket || m_Socket->IsClosed()))
                        return false;
                }

                return true;
            }
            default:
                break;
        }
    }

    return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operand* ConstantFolder::LoadFromAddress(Operand* op, const Type* loadType, 
                                         __int64 offset) {
	// If the operand has a defining instruction then we try to compute
	// the offset from which we should load. If it's a variable reference
	// we try to load from the offset that was already computed.
	if(op->HasDefiningInstruction() == false) {
		return LoadFromGlobal(op, loadType, offset);
	}

	auto instr = op->DefiningInstruction();

	switch(instr->GetOpcode()) {
		case Instr_Index: {
			// If the index operand is not a constant give up.
			auto indexInstr = instr->As<IndexInstr>();
			auto indexConst = indexInstr->IndexOp()->As<IntConstant>();
			
            if(indexConst == nullptr) {
                return nullptr;
            }

			// The type of the base is 'pointer-to-array', so we need to strip the pointer.
			auto elementType = indexInstr->GetElementType();
			__int64 index = indexConst->Value();
			__int64 elemSize = TypeInfo::GetSize(elementType, target_);

			// The offset is incremented by the index multiplied with the element size.
			__int64 newOffset = offset + (index * elemSize);
			return LoadFromAddress(indexInstr->BaseOp(), loadType, newOffset);
		}
		case Instr_Element: {
			auto elemInstr = instr->As<ElementInstr>();
			__int64 index = elemInstr->GetFieldIndex();

			// The type of the base is 'pointer-to-record', 
            // so we need to strip the pointer.
			auto recordType = elemInstr->GetRecordType();

			// Obtain the offset of the selected field.
			// The new offset is the old one added with the field offset.
			__int64 fieldOffset = recordType->Fields()[index].FieldOffset;
			__int64 newOffset = offset + fieldOffset;
			return LoadFromAddress(elemInstr->BaseOp(), loadType, newOffset);
		}
		case Instr_Address: {
			// If the index operand is not a constant give up.
			auto addrInstr = instr->As<AddressInstr>();
			auto indexConst = addrInstr->IndexOp()->As<IntConstant>();

			if(indexConst == nullptr) {
                return nullptr;
            }

			// The type of the base is 'pointer-to-object',
            // so we need to strip the pointer.
			auto objectType = addrInstr->GetPointeeType();
			__int64 index = indexConst->Value();
			__int64 elemSize = TypeInfo::GetSize(objectType, target_);

			// The offset is incremented by the index multiplied with the object size.
			__int64 newOffset = offset + (index * elemSize);
			return LoadFromAddress(addrInstr->BaseOp(), loadType, newOffset);
		}
		case Instr_Ptop: {
			// This instruction is ignored (the previous recursion step
			// has already taken care about its effects).
			auto ptopInstr = instr->As<PtopInstr>();
			auto targetInstr = ptopInstr->TargetOp()->DefiningInstruction();
			return LoadFromAddress(ptopInstr->TargetOp(), loadType, offset);
		}
		case Instr_Load: {
			// This happens when the variable is a pointer.
			auto loadInstr = instr->As<LoadInstr>();
			return LoadFromAddress(loadInstr->SourceOp(), loadType, offset);
		}
		default: {
			// All other cases don't lead to a constant operand.
			return nullptr;
		}
	}
}
Exemple #13
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OperandInfo::EstimateZeroBitsImpl(Operand* op, Mask& bits, int depth) {
    DebugValidator::IsNotNull(op);
    DebugValidator::IsLargerOrEqual(depth, 0);

	// Don't recourse too many times, in most cases it won't improve the results.
	if(depth == 0) return;

    auto intType = op->GetType()->As<IntegerType>();
    bool isPositive = false;
	bits = 0; // We start knowing nothing.

	// First test for constants and references.
    IntConstant* intConst = op->As<IntConstant>();

    if(intConst == nullptr) {
        isPositive = IsOperandPositive(op, intConst);
    }

	if(intConst) {
		// We know all the bits that are not set for constants.
        __int64 mask = IA::GetMinusOneMask(intType);
        bits = ~intConst->Value() & mask;
        return;
	}
	else if(op->IsNullConstant() && target_) {
		// All bits are zero.
		auto ptrIntType = IntegerType::GetHavingSize(target_->GetPointerSize());
		bits = IA::GetMinusOneMask(ptrIntType);
        return;
	}
	else if(auto variableRef = op->As<VariableReference>()) {
		// For global variables we can consider the alignment.
        if(target_) {
            int alignment = GetVariableAlignment(variableRef, target_);
		    bits = IA::ValueFromBitCount(alignment);
        }
        return;
	}
    else if(isPositive) {
        bits = IA::GetSignBitMask(intType);
    }

	// Now check for instructions for which we can determine some of the zero bits.
	auto definingInstr = op->DefiningInstruction();
	
    if(definingInstr == nullptr) {
        return;
    }

	// What we know about the left and right operands of binary instructions.
	Mask bitsLeft = 0;
	Mask bitsRight = 0;

	switch(definingInstr->GetOpcode()) {
		case Instr_And: {
			// A bit is zero if it's zero in the left operand 
			// or if it's zero in the right operand.
			EstimateZeroBits(definingInstr->GetSourceOp(0), bitsLeft, depth - 1);
			EstimateZeroBits(definingInstr->GetSourceOp(1), bitsRight, depth - 1);
			bits = bitsLeft | bitsRight;
			break;
		}
		case Instr_Or: {
			// A bit is zero if it's zero in both left and right operands.
			EstimateZeroBits(definingInstr->GetSourceOp(0), bitsLeft, depth - 1);
			EstimateZeroBits(definingInstr->GetSourceOp(1), bitsRight, depth - 1);
			bits = bitsLeft & bitsRight;
			break;
		}
		case Instr_Xor: {
			// A bit is zero if it has the same value in both operands.
			EstimateZeroBits(definingInstr->GetSourceOp(0), bitsLeft, depth - 1);
			EstimateZeroBits(definingInstr->GetSourceOp(1), bitsRight, depth - 1);

            Mask oneBitsLeft;
            Mask oneBitsRight;
            EstimateOneBits(definingInstr->GetSourceOp(0), oneBitsLeft, depth - 1);
			EstimateOneBits(definingInstr->GetSourceOp(1), oneBitsRight, depth - 1);

			bits = (bitsLeft & bitsRight) |
                   (oneBitsLeft & oneBitsRight);
			break;
		}
		case Instr_Shl:  { EstimateZeroBitsShl(definingInstr, bits, depth);  break; }
		case Instr_Ushr: { EstimateZeroBitsUshr(definingInstr, bits, depth); break; }
		case Instr_Shr:  { EstimateZeroBitsShr(definingInstr, bits, depth);  break; }
		case Instr_Add:
        case Instr_Sub:  { EstimateZeroBitsAddSub(definingInstr, bits, depth); break; }
		case Instr_Mul:  { EstimateZeroBitsAddSub(definingInstr, bits, depth); break; }
		case Instr_Mod:  { EstimateZeroBitsMod(definingInstr, bits, depth);    break; }
		case Instr_Umod: { EstimateZeroBitsUmod(definingInstr, bits, depth);   break; }
		case Instr_Udiv: { EstimateZeroBitsUdiv(definingInstr, bits, depth);   break; }
		case Instr_Trunc:
		case Instr_Zext: { EstimateZeroBitsZextTrunc(definingInstr, bits, depth); break; }
		case Instr_Sext: { EstimateZeroBitsSext(definingInstr, bits, depth);      break; }
		case Instr_Ptoi: { EstimateZeroBitsPtoi(definingInstr, bits, depth);      break; }
		case Instr_Itop: { EstimateZeroBitsItop(definingInstr, bits, depth);      break; }
        case Instr_Phi:  { EstimateZeroBitsPhi(definingInstr, bits, depth);       break; }
        case Instr_Call: { EstimateZeroBitsCall(definingInstr, bits, depth);      break; }
        case Instr_Question: { EstimateZeroBitsQuest(definingInstr, bits, depth); break; }
	}
}
void Instr::Encode
    (
    )
{
    mEncoding = GetOpcode() << 27;
}
Exemple #15
0
void CArp::Show( ulong ulParams )
{
	cout << "ARP " << GetIpSrc() << " > " << GetIpDest() << " " << GetOpcode() << endl;
}