Beispiel #1
0
int get_arg_count(const char *name, Function *op)
{
    uint8_t args_present[MAX_ARGS];
    int nb_args, i, n;
    const char *p;

    for(i = 0;i < MAX_ARGS; i++)
        args_present[i] = 0;

    // compute the number of arguments by looking at
    // the uses of the op parameters
    for (Function::arg_iterator i = op->arg_begin(), e = op->arg_end(); i != e; ++i) {
      const char *tmpArgName = i->getName().c_str();
      char *argName = (char *) malloc(strlen(tmpArgName + 1));
      strcpy(argName, tmpArgName);

      if (strstart(argName, "__op_param", &p)) {
	if (i->hasNUsesOrMore(1)) {
	  n = strtoul(p, NULL, 10);
	  if (n > MAX_ARGS)
	    error("too many arguments in %s", name);
	  args_present[n - 1] = 1;
	}
      }
    }

    for (i = 1; i <= MAX_ARGS; i++) {
      char *funcName = (char *) malloc(20);
      sprintf(funcName, "__op_gen_label%d", i);
      Function *f = ops->getFunction(std::string(funcName));
      if (f != NULL) {
	  for (Function::use_iterator j = f->use_begin(), e = f->use_end(); j != e; ++j) {
	      if (Instruction *inst = dyn_cast<Instruction>(*j)) {
		if (inst->getParent()->getParent() == op) {
		  args_present[i - 1] = 1;
		}
	      }
	  }
      } else {
	  std::cout << "symbol not found\n";
      }
    }

    nb_args = 0;
    while (nb_args < MAX_ARGS && args_present[nb_args])
        nb_args++;

    for(i = nb_args; i < MAX_ARGS; i++) {
        if (args_present[i])
            error("inconsistent argument numbering in %s", name);
    }

    return nb_args;
}
Beispiel #2
0
// generate code for ops which return a void value
void gen_code_void_op(const char *name,
              FILE *outfile, Function *op)
{
    uint8_t args_present[MAX_ARGS];
    int nb_args, i, n;
    const char *p;

    for(i = 0;i < MAX_ARGS; i++)
        args_present[i] = 0;

    // compute the number of arguments by looking at
    // the uses of the op parameters
    for (Function::arg_iterator i = op->arg_begin(), e = op->arg_end(); i != e; ++i) {
      const char *tmpArgName = i->getName().c_str();
      char *argName = (char *) malloc(strlen(tmpArgName + 1));
      strcpy(argName, tmpArgName);

      if (strstart(argName, "__op_param", &p)) {
	if (i->hasNUsesOrMore(1)) {
	  n = strtoul(p, NULL, 10);
	  if (n > MAX_ARGS)
	    error("too many arguments in %s", name);
	  args_present[n - 1] = 1;
	}
      }
    }

    nb_args = 0;
    while (nb_args < MAX_ARGS && args_present[nb_args])
        nb_args++;

    for(i = nb_args; i < MAX_ARGS; i++) {
        if (args_present[i])
            error("inconsistent argument numbering in %s", name);
    }

    // add local variables for op parameters
    if (nb_args > 0) {
        fprintf(outfile, "    long ");
        for(i = 0; i < nb_args; i++) {
	    if (i != 0)
	        fprintf(outfile, ", ");
	    fprintf(outfile, "param%d", i + 1);
        }
        fprintf(outfile, ";\n");
    }

    // load parameters in variables
    for(i = 0; i < nb_args; i++) {
        fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
    }

    // load op parameters into the arguments of the call
//     fprintf(outfile, "Value * args[MAX_ARGS];\n");
//     for (i = 0; i < nb_args; i++) {
//       fprintf(outfile, "args[%d] = ConstantInt::get(Type::Int32Ty, param%d);\n", i, i + 1);
//     }
//     for (i = nb_args; i < MAX_ARGS; i++) {
//       fprintf(outfile, "args[%d] = zero;\n", i);
//     }
    // add call to micro op
    //fprintf(outfile, "    currCall = new CallInst(M->getFunction(\"%s\"), (Value **)&args, %d, \"\", currInst);\n", name, MAX_ARGS);

    // load op parameters into the arguments of the call
    fprintf(outfile, "std::vector<Value *> args;\n");
    for (i = 0; i < nb_args; i++) {
        fprintf(outfile, "args.push_back(ConstantInt::get(Type::Int32Ty, param%d));\n", i + 1);
    }
    for (i = nb_args; i < MAX_ARGS; i++) {
      fprintf(outfile, "args.push_back(zero);\n");
    }
    // add call to micro op
    fprintf(outfile, "    currCall = new CallInst(M->getFunction(\"%s\"), args.begin(), args.end(), \"\", currInst);\n", name);

    if (strcmp(name, "op_exit_tb") == 0) {
      fprintf(outfile,
	      "     currBB = new BasicBlock(\"\", tb);\n"
	      "     currInst = new ReturnInst(fallThrough, currBB);\n"
	      );
      
    } else if (strcmp(name, "op_goto_tb0")) {
//         fprintf(outfile,
// 	      "     currBB = new BasicBlock(\"\", tb);\n"
// 	      "     currInst = new ReturnInst(tb0, currBB);\n"
// 	      );
    } else if (strcmp(name, "op_goto_tb1")) {
//         fprintf(outfile,
// 	      "     currBB = new BasicBlock(\"\", tb);\n"
// 	      "     currInst = new ReturnInst(tb1, currBB);\n"
// 	      );
    }
    fprintf(outfile, "    InlineFunction(currCall);");
	    // inlining can change the basic block the return instruction belongs to
	    fprintf(outfile, "    currBB = currInst->getParent();");
}
Beispiel #3
0
// generate code for ops which return a void value
void gen_code_void_op(const char *name,
              FILE *outfile, Function *op)
{
    uint8_t args_present[MAX_ARGS];
    int nb_args, i, n;
    const char *p;

    for(i = 0;i < MAX_ARGS; i++)
        args_present[i] = 0;

    // compute the number of arguments by looking at
    // the uses of the op parameters
    for (Function::arg_iterator i = op->arg_begin(), e = op->arg_end(); i != e; ++i) {
      const char *tmpArgName = i->getName().c_str();
      char *argName = (char *) malloc(strlen(tmpArgName + 1));
      strcpy(argName, tmpArgName);

      if (strstart(argName, "__op_param", &p)) {
	if (i->hasNUsesOrMore(1)) {
	  n = strtoul(p, NULL, 10);
	  if (n > MAX_ARGS)
	    error("too many arguments in %s", name);
	  args_present[n - 1] = 1;
	}
      }
    }

    nb_args = 0;
    while (nb_args < MAX_ARGS && args_present[nb_args])
        nb_args++;

    for(i = nb_args; i < MAX_ARGS; i++) {
        if (args_present[i])
            error("inconsistent argument numbering in %s", name);
    }

    // add local variables for op parameters
    if (nb_args > 0) {
        fprintf(outfile, "    long ");
        for(i = 0; i < nb_args; i++) {
	    if (i != 0)
	        fprintf(outfile, ", ");
	    fprintf(outfile, "param%d", i + 1);
        }
        fprintf(outfile, ";\n");
    }

    // load parameres in variables
    for(i = 0; i < nb_args; i++) {
        fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
    }

    // load op parameters into the arguments of the call
    fprintf(outfile, "Value * args[MAX_ARGS];\n");
    for (i = 0; i < nb_args; i++) {
      fprintf(outfile, "args[%d] = ConstantInt::get(Type::Int32Ty, param%d);\n", i, i + 1);
    }
    for (i = nb_args; i < MAX_ARGS; i++) {
      fprintf(outfile, "args[%d] = zero;\n", i);
    }
    // add call to micro op
    fprintf(outfile, "    currCall = new CallInst(M->getFunction(\"%s\"), (Value **)&args, %d, \"\", currBB);\n", name, MAX_ARGS);
    fprintf(outfile, "     InlineFunction(currCall);");
}