Beispiel #1
0
bool ArmParser::parseRegisterList(Parser& parser, int& dest, int validMask)
{
    ArmRegisterValue reg, reg2;

    dest = 0;
    while (true)
    {
        if (parseRegister(parser,reg) == false)
            return false;

        if (parser.peekToken().type == TokenType::Minus)
        {
            parser.eatToken();

            if (parseRegister(parser,reg2) == false || reg2.num < reg.num)
                return false;

            for (int i = reg.num; i <= reg2.num; i++)
            {
                dest |= (1 << i);
            }
        } else {
            dest |= (1 << reg.num);
        }

        if (parser.peekToken().type != TokenType::Comma)
            break;

        parser.eatToken();
    }

    return (validMask & dest) == dest;
}
Beispiel #2
0
bool ArmParser::parseImmediate(Parser& parser, Expression& dest)
{
    TokenizerPosition pos = parser.getTokenizer()->getPosition();

    // check if it really is an immediate
    ArmOpcodeVariables tempVars;
    if (parsePsrTransfer(parser,tempVars,false))
        return false;

    parser.getTokenizer()->setPosition(pos);
    if (parseRegister(parser,tempVars.rd))
        return false;

    parser.getTokenizer()->setPosition(pos);
    if (parseCopNumber(parser,tempVars.rd))
        return false;

    parser.getTokenizer()->setPosition(pos);
    if (parseCopRegister(parser,tempVars.rd))
        return false;

    parser.getTokenizer()->setPosition(pos);
    dest = parser.parseExpression();
    return dest.isLoaded();
}
void HWInformation::parseRegisterAssociation (const xmlpp::Node *node)
{
	//Recurse through child nodes:
	xmlpp::Node::NodeList list = node->get_children ();

	for (xmlpp::Node::NodeList::iterator iter = list.begin (); iter != list.end (); ++iter)
	{
		const xmlpp::Node *tmp = *iter;

		//Be paranoid
		assert (tmp != NULL);

		if (verifyCanGetName (tmp))
		{
			if (verifyNodeName (tmp, "register"))
			{
				parseRegister (tmp);
			}
			else
			{
				Logging::log (1, "HWInformation: Warning: Unsupported name '", extractNodeName (tmp).c_str (), "' in register_association node at: ", getLine (tmp).c_str (), NULL);
			}
		}
	}
}
Beispiel #4
0
bool ArmParser::parseThumbParameters(Parser& parser, const tThumbOpcode& opcode, ThumbOpcodeVariables& vars)
{
    const u8* encoding = (const u8*) opcode.mask;

    ArmRegisterValue tempRegister;
    int value;

    while (*encoding != 0)
    {
        bool optional = *encoding == '/';
        if (optional)
            encoding++;

        switch (*encoding++)
        {
        case 'd': // register
            CHECK(parseRegister(parser,vars.rd,7));
            break;
        case 's': // register
            CHECK(parseRegister(parser,vars.rs,7));
            break;
        case 'n': // register
            CHECK(parseRegister(parser,vars.rn,7));
            break;
        case 'o': // register
            CHECK(parseRegister(parser,vars.ro,7));
            break;
        case 'D': // register
            CHECK(parseRegister(parser,vars.rd,15));
            break;
        case 'S': // register
            CHECK(parseRegister(parser,vars.rs,15));
            break;
        case 'r': // forced register
            CHECK(parseRegister(parser,tempRegister,15));
            CHECK(*encoding++ == tempRegister.num);
            break;
        case 'R':	// register list
            value = encoding[0] | (encoding[1] << 8);
            CHECK(parseRegisterList(parser,vars.rlist,value));
            encoding += 2;
            break;
        case 'I':	// immediate
        case 'i':
            CHECK(parseImmediate(parser,vars.ImmediateExpression));
            vars.ImmediateBitLen = *encoding++;
            break;
        default:
            CHECK(matchSymbol(parser,*(encoding-1),optional));
            break;
        }
    }

    // the next token has to be an identifier, else the parameters aren't
    // completely parsed
    return parser.atEnd() || parser.peekToken().type == TokenType::Identifier;
}
Beispiel #5
0
bool ArmParser::parsePseudoShift(Parser& parser, ArmOpcodeVariables& vars, int type)
{
    vars.Shift.Type = type;

    if (parseRegister(parser,vars.Shift.reg) == true)
    {
        vars.Shift.ShiftByRegister = true;
    } else {
        if (parser.peekToken().type == TokenType::Hash)
            parser.eatToken();

        if (parseImmediate(parser,vars.Shift.ShiftExpression) == false)
            return false;

        vars.Shift.ShiftByRegister = false;
    }

    vars.Shift.UseShift = true;
    return true;
}
Beispiel #6
0
int getcmd(char line[], int *index, int *num, int *data_start, int *data_end)
{
  int len = 0;
  int cmd = AT_CMD_END;


  *num = 0;
  *data_start = 0;
  *data_end = 0;

  if (line == NULL)
    return AT_CMD_NONE;
  len = strlen(line);
  while (*index < len) {
    cmd = toupper(line[*index]);
    switch (cmd) {
    case ' ':
      break;
    case 0:
      return AT_CMD_END;
    case '%':
      (*index)++;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case ' ':
          break;
        case 0:
          return AT_CMD_ERR;
        default:
          return parseCommand(line, AT_CMD_FLAG_PRO_PCT, index, num, len);
        }
        (*index)++;
      }
      break;
    case '\\':
      (*index)++;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case ' ':
          break;
        case 0:
          return AT_CMD_ERR;
        default:
          return parseCommand(line, AT_CMD_FLAG_PRO_BACK, index, num, len);
        }
        (*index)++;
      }
      break;
    case ':':
      (*index)++;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case ' ':
          break;
        case 0:
          return AT_CMD_ERR;
        default:
          return parseCommand(line, AT_CMD_FLAG_PRO_COLON, index, num, len);
        }
        (*index)++;
      }
      break;
    case '-':
      (*index)++;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case ' ':
          break;
        case 0:
          return AT_CMD_ERR;
        default:
          return parseCommand(line, AT_CMD_FLAG_PRO_MINUS, index, num, len);
        }
        (*index)++;
      }
      break;
    case '&':
      (*index)++;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case ' ':
          break;
        case 0:
          return AT_CMD_ERR;
        case 'Z':
          return parseRegister(line, AT_CMD_FLAG_EXT, index, num, len, data_start, data_end,
                               TRUE);
        default:
          return parseCommand(line, AT_CMD_FLAG_EXT, index, num, len);
        }
        (*index)++;
      }
      break;
    case 'D':  // handle Dialing.
      (*index)++;
      *num = 0;
      while (*index < len) {
        switch (toupper(line[*index])) {
        case 0:
          return cmd;
        case 'T':
        case 'P':
        case 'L':
          *num = toupper(line[*index]);
          (*index)++;
        default:
          getData(line, index, len, data_start, data_end, TRUE);
          return cmd;
        }
        (*index)++;
      }
      return cmd;
    case 'S':
      return parseRegister(line, AT_CMD_FLAG_BAS, index, num, len, data_start, data_end, FALSE);
    default:
      return parseCommand(line, AT_CMD_FLAG_BAS, index, num, len);
    }
    (*index)++;
  }
  return cmd;

}
Beispiel #7
0
bool ArmParser::parseArmParameters(Parser& parser, const tArmOpcode& opcode, ArmOpcodeVariables& vars)
{
    const u8* encoding = (const u8*) opcode.mask;

    ArmRegisterValue tempRegister;

    vars.Shift.UseShift = false;
    vars.Shift.UseFinal = false;
    vars.psr = false;
    vars.writeback = false;
    vars.SignPlus = false;
    vars.Opcode.UseNewEncoding = false;
    vars.Opcode.UseNewType = false;

    while (*encoding != 0)
    {
        bool optional = *encoding == '/';
        if (optional)
            encoding++;

        switch (*encoding++)
        {
        case 'd': // register
            CHECK(parseRegister(parser,vars.rd,*encoding++ == '1' ? 14 : 15));
            break;
        case 's': // register
            CHECK(parseRegister(parser,vars.rs,*encoding++ == '1' ? 14 : 15));
            break;
        case 'n': // register
            CHECK(parseRegister(parser,vars.rn,*encoding++ == '1' ? 14 : 15));
            break;
        case 'm': // register
            CHECK(parseRegister(parser,vars.rm,*encoding++ == '1' ? 14 : 15));
            break;
        case 'D': // cop register
            CHECK(parseCopRegister(parser,vars.CopData.cd));
            break;
        case 'N': // cop register
            CHECK(parseCopRegister(parser,vars.CopData.cn));
            break;
        case 'M': // cop register
            CHECK(parseCopRegister(parser,vars.CopData.cm));
            break;
        case 'W':	// writeback
            parseWriteback(parser,vars.writeback);
            break;
        case 'p':	// psr
            parsePsr(parser,vars.psr);
            break;
        case 'P':	// msr/mrs psr data
            CHECK(parsePsrTransfer(parser,vars,*encoding++ == '1'));
            break;
        case 'R':	// register list
            CHECK(parseRegisterList(parser,vars.rlist,0xFFFF));
            break;
        case 'S':	// shift
            CHECK(parseShift(parser,vars,*encoding++ == '1'));
            break;
        case 'I':	// immediate
        case 'i':
            CHECK(parseImmediate(parser,vars.ImmediateExpression));
            vars.ImmediateBitLen = 32;
            break;
        case 'j':	// variable bit immediate
            CHECK(parseImmediate(parser,vars.ImmediateExpression));
            vars.ImmediateBitLen = *encoding++;
            break;
        case 'X': // cop number
            CHECK(parseCopNumber(parser,vars.CopData.pn));
            break;
        case 'Y':	// cop opcode number
            CHECK(parseImmediate(parser,vars.CopData.CpopExpression));
            vars.ImmediateBitLen = 4;
            break;
        case 'Z':	// cop info number
            CHECK(parseImmediate(parser,vars.CopData.CpinfExpression));
            vars.ImmediateBitLen = 3;
            break;
        case 'z':	// shift for pseudo opcodes
            CHECK(parsePseudoShift(parser,vars,*encoding++));
            break;
        case 'v':	// sign for register index parameter
            parseSign(parser,vars.SignPlus);
            break;
        default:
            CHECK(matchSymbol(parser,*(encoding-1),optional));
            break;
        }
    }

    // the next token has to be an identifier, else the parameters aren't
    // completely parsed
    return parser.atEnd() || parser.peekToken().type == TokenType::Identifier;
}
Beispiel #8
0
bool ArmParser::parseShift(Parser& parser, ArmOpcodeVariables& vars, bool immediateOnly)
{
    // no shift is also valid
    vars.Shift.UseShift = false;
    if (parser.peekToken().type != TokenType::Comma)
        return true;

    parser.eatToken();

    // load shift mode
    const Token& shiftMode = parser.nextToken();
    if (shiftMode.type != TokenType::Identifier)
        return false;

    std::wstring stringValue = shiftMode.getStringValue();

    bool hasNumber = isNumber(stringValue.back());
    u64 number;

    // handle modeXX syntax
    if (hasNumber)
    {
        number = 0;
        u64 multiplier = 1;
        while (isNumber(stringValue.back()))
        {
            number += multiplier*(stringValue.back() - '0');
            multiplier *= 10;
            stringValue.pop_back();
        }
    }

    if (stringValue == L"lsl")
        vars.Shift.Type = 0;
    else if (stringValue == L"lsr")
        vars.Shift.Type = 1;
    else if (stringValue == L"asr")
        vars.Shift.Type = 2;
    else if (stringValue == L"ror")
        vars.Shift.Type = 3;
    else if (stringValue == L"rrx")
        vars.Shift.Type = 4;
    else
        return false;

    if (hasNumber)
    {
        vars.Shift.ShiftExpression = createConstExpression(number);
        vars.Shift.ShiftByRegister = false;
    } else if (parseRegister(parser,vars.Shift.reg) == true)
    {
        if (immediateOnly)
            return false;

        vars.Shift.ShiftByRegister = true;
    } else {
        if (parser.peekToken().type == TokenType::Hash)
            parser.eatToken();

        if (parseImmediate(parser,vars.Shift.ShiftExpression) == false)
            return false;

        vars.Shift.ShiftByRegister = false;
    }

    vars.Shift.UseShift = true;
    return true;
}