Пример #1
0
void
parseExp(std::map<identifier,Expression> &values, std::string input)
{
  const std::regex inputRegex(std::string("(((NOT)|((\\d+|[a-z]{1,2}) (AND|OR|LSHIFT|RSHIFT))) |(\\d+)|([a-z]{1,2}))(\\d*|[a-z]{1,2}) -> ([a-z]{1,2})"));
  std::smatch inputMatch;
  if(std::regex_match(input, inputMatch, inputRegex)){
    Expression::Operation op = Expression::Operation::EQ;
    /**/ if (inputMatch[3].matched)        op = Expression::Operation::NOT;
    else if(inputMatch[6].str()==   "AND") op = Expression::Operation::AND;
    else if(inputMatch[6].str()==    "OR") op = Expression::Operation::OR;
    else if(inputMatch[6].str()=="LSHIFT") op = Expression::Operation::LSHIFT;
    else if(inputMatch[6].str()=="RSHIFT") op = Expression::Operation::RSHIFT;
    identifier id = inputMatch[10].str();

    if(op==Expression::Operation::NOT){
      values[id] = {op,parseOperand(inputMatch[9].str())};
    }else if(op==Expression::Operation::EQ){
      if(inputMatch[8].matched)
        values[id] = {op,parseOperand(inputMatch[8].str())};
      else
        values[id] = {op,parseOperand(inputMatch[7].str())};
    }else{
      values[id] = {op,parseOperand(inputMatch[5].str()),parseOperand(inputMatch[9].str())};
    }
    std::cout << id << "<-" << values[id] << std::endl;
  }
}
Пример #2
0
/**
 * Parses instructions with a SOPP encoding
 * 
 * MAGIC (9) | OP (7) | SIMM (16)
 */
isa_op_code* parseSOPP(isa_instr instr, int argc, char **args)
{
	char *simm_str;

	isa_operand *simm_op;	// ISA operand structs
	isa_op_code *op_code;	// Generated opcode struct

	op_code = (isa_op_code *) malloc(sizeof(isa_op_code));
	
	if (argc < 1)
		ERROR("number of passed operands is too low");

	// Setup arguments
	simm_str	= args[0];

	// Parse operands
	op_code->code = instr.op_code;
	op_code->literal_set = 0;

	// SIMM
	simm_op = parseOperand(simm_str, 16);

	if (simm_op->op_type.type != LITERAL)
		ERROR("non-literal value supplied for SIMM operand");

	// We use a 16 bit inline literal here
	op_code->code |= (uint16_t) simm_op->value;

	free(simm_op);

	return op_code;
}
Пример #3
0
/**
 * Parses instructions with a VOPC encoding
 * 
 * MAGIC (7) | OP (8) | VSRC1 (8) | SSRC0 (9) | [LITERAL (32)]
 */
isa_op_code* parseVOPC(isa_instr instr, int argc, char **args)
{
	char *vsrc1_str, *src0_str;
	int has_vcc;

	isa_operand *vsrc1_op, *src0_op;	// ISA operand structs
	isa_op_code *op_code;				// Generated opcode struct

	op_code = (isa_op_code *) malloc(sizeof(isa_op_code));

	if (argc < 2)
		ERROR("number of passed operands is too low");

	has_vcc = argc == 3;

	// Setup arguments
	src0_str	= args[0 + has_vcc];
	vsrc1_str	= args[1 + has_vcc];

	// Parse operands
	op_code->code = instr.op_code;
	op_code->literal = 0;
	op_code->literal_set = 0;

	// SRC0
	src0_op = parseOperand(src0_str);

	if (src0_op->op_type.type == LITERAL)
		setLiteralOperand(op_code, src0_op);
	else if (src0_op->op_type.type == VGPR)
		src0_op->op_code += 256;

	op_code->code |= src0_op->op_code;	

	// VSRC1
	vsrc1_op = parseOperand(vsrc1_str);

	if (vsrc1_op->op_type.type != VGPR)
		ERROR("VSRC1 must be of VGPR type");

	op_code->code |= vsrc1_op->op_code << 9;

	free(vsrc1_op);
	free(src0_op);

	return op_code;
}
Пример #4
0
tOperand parseLabelOperand(char *operand_name, tDatabase label_values)
{
    tOperand operand;
    tAddress value = getLabelValue(operand_name, label_values);
    if (value == -1)
    {
        operand = parseOperand(operand_name);
    }
    else
    {
        operand.type = 0;
        operand.value = value;
    }
    return operand;
}
Пример #5
0
/**
 * Parses instructions with a MUBUF encoding
 * 
 * MAGIC (6) | r | OP (7) | r | LDS | ADDR64 | GLC 
 * | IDXEN | OFFEN | OFFSET (12) | SOFFSET(8) | TFE
 * | SLC | r | SRSRC (5) | VDATA (8) | VADDR (8)
 */
isa_op_code* parseMUBUF(isa_instr instr, int argc, char **args)
{
	char *vdata_str, *vaddr_str, *srsrc_str, *soffset_str;
	int i, j;

	isa_operand *vdata_op, *vaddr_op, 	// ISA operand structs
		*srsrc_op, *soffset_op;	
	isa_op_code *op_code;				// Generated opcode struct

	
	op_code = (isa_op_code *) malloc(sizeof(isa_op_code));
	
	if (argc < 4)
		ERROR("number of passed operands is too low");

	// Setup arguments
	vdata_str	= args[0];
	vaddr_str	= args[1];
	srsrc_str	= args[2];
	soffset_str	= args[3];

	// Parse operands
	op_code->code = instr.op_code;
	op_code->literal = 0;
	op_code->literal_set = 1;

	// VDATA
	vdata_op = parseOperand(vdata_str);

	if (vdata_op->op_type.type != VGPR)
		ERROR("VDATA operand must be a VGPR");

	op_code->literal |= vdata_op->op_code << 8;

	// VADDR
	vaddr_op = parseOperand(vaddr_str);

	if (vaddr_op->op_type.type != VGPR)
		ERROR("VADDR operand must be a VGPR");

	op_code->literal |= vaddr_op->op_code;

	// SRSRC
	srsrc_op = parseOperand(srsrc_str);

	// This field is missing 2 bits from LSB
	srsrc_op->op_code >>= 2;

	if (srsrc_op->op_type.type != SGPR)
		ERROR("SRSRC operand must be an SGPR");

	op_code->literal |= srsrc_op->op_code << 16;

	// SOFFSET
	soffset_op = parseOperand(soffset_str);

	if (soffset_op->op_type.type != SGPR
			&& soffset_op->op_type.type != M0
			&& soffset_op->op_type.type != ZERO
			&& soffset_op->op_type.type != INL_POS
			&& soffset_op->op_type.type != INL_NEG)
		ERROR("SOFFSET operand must be an SGPR, M0 or inline constant");

	op_code->literal |= soffset_op->op_code << 24;

	// Parse optional parameters
	for (i = 4; i < argc; ++i)
	{
		// Convert to upper case
		for (j = 0; args[i][j]; ++j)
			args[i][j] = (char) toupper(args[i][j]);

		if (strcmp(args[i], "OFFEN") == 0)
			op_code->code |= (1 << 12);
		else if (strcmp(args[i], "IDXEN") == 0)
			op_code->code |= (1 << 13);
		else if (strcmp(args[i], "GLC") == 0)
			op_code->code |= (1 << 14);
		else if (strcmp(args[i], "ADDR64") == 0)
			op_code->code |= (1 << 15);
		else if (strcmp(args[i], "LDS") == 0)
			op_code->code |= (1 << 16);
		else if (strcmp(args[i], "SLC") == 0)
			op_code->literal |= (1 << 22);
		else if (strcmp(args[i], "TFE") == 0)
			op_code->literal |= (1 << 23);
		else if (strncmp(args[i], "OFFSET:", strlen("OFFSET:")) == 0)
		{
			isa_operand *offset_op = parseOperand(args[i] 
				+ strlen("OFFSET:"));

			if (!isConstantOperand(offset_op))
				ERROR("non-literal value supplied for OFFSET operand");

			op_code->code |= offset_op->value;
			
			free(offset_op);
		}

	}

	free(vdata_op);
	free(vaddr_op);
	free(srsrc_op);
	free(soffset_op);

	return op_code;
}
Пример #6
0
void ArgState::run(int argc, const char** argv) {
	bool keepgoing = true;

	ukoct_ASSERT(stage == STAGE_PARSE, "Running must only happen at parsing stage.");


	// PARSING


	if (keepgoing) {
		std::vector<std::string> badOptions;
		std::vector<std::string> badArgs;
		parser.parse(argc, argv);

		if (!parser.gotRequired(badOptions)) {
			for(int i=0; i < badOptions.size(); ++i)
				err() << "Missing required option " << badOptions[i] << ".\n";
			err(false) << "Check `" << ukoct_NAME << " -h` for help." << std::endl;
			keepgoing = false;
		}

		if (keepgoing && !parser.gotExpected(badOptions)) {
			for(int i=0; i < badOptions.size(); ++i)
				err() << "Wrong arguments for option " << badOptions[i] << ".\n";
			err(false) << "Check `" << ukoct_NAME << " -h` for help." << std::endl;
			keepgoing = false;
		}

		if (keepgoing && !parser.gotValid(badOptions, badArgs)) {
			for(int i=0; i < badOptions.size(); ++i)
				err() << "Got invalid argument \"" << badArgs[i] << "\" for option " << badOptions[i] << "." << std::endl;
			err(false) << "Check `" << ukoct_NAME << " -h` for help." << std::endl;
			keepgoing = false;
		}
	}

	if (keepgoing) {
		keepgoing = callOptionGroups();
	}

	if (keepgoing) {
		// Input
		if (parser.firstArgs.size() > 1) {
			inputOperand.inputStream.fileName = *parser.firstArgs.back();
			dbg() << "Found input file \"" << inputOperand.inputStream.fileName << "\"." << std::endl;
		}

		for (auto& ezGroup : parser.groups) {
			const Option* option = NULL;

			for (auto& flag : ezGroup->flags) {
				auto it = options.find(*flag);
				if (it != options.end()) {
					option = it->second;
					break;
				}
			}

			ukoct_ASSERT(option != NULL, "Option Groups must register an option object.");

			std::vector<std::vector<std::string> > multiArgs;
			ezGroup->getMultiStrings(multiArgs);

			// If the option takes any arguments, or if giving an
			// argument is optional and was not given, ez will return
			// a non-empty multi-argument array[i][j] where each [i] is
			// the specific occurrence (that coincides in index with
			// the parseIndex vector in the OptionGroup), and [j] is
			// the split option (if any). array[i] should not be empty.
			if (!multiArgs.empty()) {
				for (size_t i = 0; i < multiArgs.size(); ++i) {
					Operand multiOperand;
					multiOperand.option = option;
					multiOperand.parseIndex = ezGroup->parseIndex.size() == multiArgs.size() ? ezGroup->parseIndex[i] : 0; // Because of the defaults
					multiOperand.ezGroup = ezGroup;
					multiOperand.args = multiArgs[i];
					multiOperand.stage = STAGE_PARSE;
					keepgoing = callOptionGroups(multiOperand);

					if (keepgoing) {
						operands.push_back(multiOperand);
					} else {
						break;
					}
				}

			} else {
				// In case the option doesn't take any arguments,
				// just insert each parseIndex to the operands list.
				// Those will be further sorted and then
				for (auto& parseIndex : ezGroup->parseIndex) {
					Operand operandOccurrence;
					operandOccurrence.option = option;
					operandOccurrence.parseIndex = parseIndex;
					operandOccurrence.ezGroup = ezGroup;
					operandOccurrence.stage = STAGE_PARSE;
					keepgoing = callOptionGroups(operandOccurrence);

					if (keepgoing) {
						operands.push_back(operandOccurrence);
					} else {
						break;
					}
				}
			}

			if (!keepgoing) {
				break;
			}
		}
	}

	if (keepgoing && totalActions == 0) {
		keepgoing = false;
		err() << "Please specify at least one action." << std::endl;
		err(false) << "Check `" << ukoct_NAME << " -h` for help." << std::endl;
		exitCode = RETEARG;
		keepgoing = false;
	}

	// Open files/streams

	if (keepgoing) {
		keepgoing = parseInputOperand(inputOperand) && parseOutputOperand(outputOperand);
	}

	if (keepgoing) {
		for (auto& operand : operands) {
			keepgoing = parseOperand(operand);
			if (!keepgoing) break;
		}
	}


	// INIT


	if (keepgoing) {
		stage = STAGE_INIT;
		std::sort(operands.begin(), operands.end());
		keepgoing = callOptionGroups();
	}

	if (keepgoing) {
		for (auto& operand : operands) {
			operand.stage = STAGE_INIT;
			keepgoing = callOptionGroups(operand);
			if (!keepgoing) {
				break;
			}
		}
	}


	// RUN


	if (keepgoing) {
		stage = STAGE_EXEC;
		keepgoing = callOptionGroups();
	}

	if (keepgoing) {
		unsigned int actionIdx = 1;

		for (auto& operand : operands) {
			operand.stage = STAGE_EXEC;
			operand.actionIdx = actionIdx;
			keepgoing = callOptionGroups(operand);

			if (!keepgoing) {
				break;
			} else {
				++actionIdx;
			}
		}
	}


	// PRINT RESULTS


	if (keepgoing && printTimings) {
		// TODO Print results
	}
}
Пример #7
0
/**
 * Parses instructions with a SMRD encoding
 * 
 * MAGIC (5) | OP (5) | SDST (7) | SBASE (6) | IMM (1) | OFFSET (8) | 
 * [LITERAL (32)]
 */
isa_op_code* parseSMRD(isa_instr instr, int argc, char **args)
{
	char *sdst_str, *sbase_str, *offset_str;

	isa_operand *sdst_op, *sbase_op, *offset_op;	// ISA operand structs
	isa_op_code *op_code;							// Generated opcode struct
	
	if (argc < 3)
		ERROR("number of passed operands is too low");

	// Setup arguments
	sdst_str	= args[0];
	sbase_str	= args[1];
	offset_str	= args[2];

	op_code = (isa_op_code *) malloc(sizeof(isa_op_code));

	// Parse operands
	op_code->code = instr.op_code;
	op_code->literal_set = 0;

	// SDST
	sdst_op = parseOperand(sdst_str, SDST);

	if (sdst_op->op_type.type != SGPR 
			&& sdst_op->op_type.type != VCC_LO 
			&& sdst_op->op_type.type != VCC_HI)
		ERROR("wrong type of operand for SDST in the SMRD format");

	op_code->code |= sdst_op->op_code << 15;

	// SBASE
	sbase_op = parseOperand(sbase_str, SBASE);

	if (sbase_op->op_type.type != SGPR)
		ERROR("wrong type of operand for SBASE in the SMRD format");

	// This field is missing the LSB
	// It can only be a multiple of two
	sbase_op->op_code >>= 1;

	op_code->code |= sbase_op->op_code << 9;

	// OFFSET
	offset_op = parseOperand(offset_str, OFFSET);

	if (offset_op->op_type.type != SGPR)
	{
		// If it's not an SGPR then it is a literal byte value
		// It is easier to simply reparse, because inline constant literals
		// are only supported up to 64

		char *end;

		if (strncmp(offset_str, "0x", 2) == 0)
		{
			offset_op->op_code = strtol((const char*) offset_str+2, &end, 16);
		}
		else
		{
			offset_op->op_code = strtol((const char*) offset_str, &end, 10);
		}

		// Also set the IMM bit
		op_code->code |= (1 << 8);
	}

	op_code->code |= offset_op->op_code;



	free(sdst_op);
	free(sbase_op);
	free(offset_op);

	return op_code;
}
Пример #8
0
/**
 * Parses instructions with a MIMG encoding
 * 
 * MAGIC (6) | S | OP (7) | L | T | R | D | G | U | DMASK
 * | r | r | SSAMP (5) | SRSRC(5) | VDATA(8) | VADDR(8)
 */
isa_op_code* parseMIMG(isa_instr instr, int argc, char **args)
{
	char *vdata_str, *vaddr_str, *ssamp_str, *srsrc_str;
	int i, j;

	isa_operand *vdata_op, *vaddr_op, 	// ISA operand structs
		*ssamp_op, *srsrc_op;	
	isa_op_code *op_code;				// Generated opcode struct

	
	op_code = (isa_op_code *) malloc(sizeof(isa_op_code));
	
	if (argc < 4)
		ERROR("number of passed operands is too low");

	// Setup arguments
	vdata_str	= args[0];
	vaddr_str	= args[1];
	srsrc_str	= args[2];
	ssamp_str	= args[3];

	// Parse operands
	op_code->code = instr.op_code;
	op_code->literal = 0;
	op_code->literal_set = 1;

	// VDATA
	vdata_op = parseOperand(vdata_str);

	if (vdata_op->op_type.type != VGPR)
		ERROR("VDATA operand must be a VGPR");

	op_code->literal |= vdata_op->op_code << 8;

	// VADDR
	vaddr_op = parseOperand(vaddr_str);

	if (vaddr_op->op_type.type != VGPR)
		ERROR("VADDR operand must be a VGPR");

	op_code->literal |= vaddr_op->op_code;

	// SRSRC
	srsrc_op = parseOperand(srsrc_str);

	// This field is missing 2 bits from LSB
	srsrc_op->op_code >>= 2;

	if (srsrc_op->op_type.type != SGPR)
		ERROR("SRSRC operand must be an SGPR");

	op_code->literal |= srsrc_op->op_code << 16;

	// SSAMP
	ssamp_op = parseOperand(ssamp_str);

	if (ssamp_op->op_type.type != SGPR)
		ERROR("SSAMP operand must be an SGPR");

	// This field is also missing 2 bits from the LSB
	ssamp_op->op_code >>= 2;

	op_code->literal |= ssamp_op->op_code << 21;

	// Parse optional parameters
	for (i = 4; i < argc; ++i)
	{
		// Convert to upper case
		for (j = 0; args[i][j]; ++j)
			args[i][j] = (char) toupper(args[i][j]);

		if (strcmp(args[i], "SLC") == 0)
			op_code->code |= (1 << 25);
		else if (strcmp(args[i], "LWE") == 0)
			op_code->code |= (1 << 17);
		else if (strcmp(args[i], "TFE") == 0)
			op_code->code |= (1 << 16);
		else if (strcmp(args[i], "R128") == 0)
			op_code->code |= (1 << 15);
		else if (strcmp(args[i], "DA") == 0)
			op_code->code |= (1 << 14);
		else if (strcmp(args[i], "GLC") == 0)
			op_code->code |= (1 << 13);
		else if (strcmp(args[i], "UNORM") == 0)
			op_code->code |= (1 << 12);
		else if (strncmp(args[i], "DMASK:", strlen("DMASK:")) == 0)
		{
			isa_operand *dmask_op = parseOperand(args[i] + strlen("DMASK:"));

			if (!isConstantOperand(dmask_op))
				ERROR("non-literal value supplied for DMASK operand");

			// Only 4 bits are needed
			dmask_op->value &= 0xF;

			op_code->code |= (dmask_op->value) << 8;
			
			free(dmask_op);
		}

	}

	free(vdata_op);
	free(vaddr_op);
	free(srsrc_op);
	free(ssamp_op);

	return op_code;
}