示例#1
0
TranslationTable::MachineInstructionVector
	TranslationTable::translateInstruction(
	const ir::Instruction* instruction) const
{
	auto translation = getTranslation(instruction->opcodeString());
	
	if(translation == nullptr)
	{
		// Fail the translation by returning nothing
		return MachineInstructionVector();
	}

	return translation->translateInstruction(instruction);
}
示例#2
0
文件: asm_engine.c 项目: lyudmil/acse
/* Function that translates every code and data segment.
* This function returns ASM_OK if everything went good */
int translateCode(t_translation_infos *infos, FILE *fp)
{
   int instruction_counter;
   t_list *current_instruction;
   void *instruction_or_data;
   int errorcode;
   
   /* unchecked preconditions: pf and infos are different from NULL */
   
   if (infos->code == NULL)
      return ASM_CODE_NOT_PRESENT;
   
   /* initialize the instruction_counter */
   instruction_counter = 0;
   current_instruction = infos->code;
   errorcode = ASM_OK;
   
   /* translate the instruction segment */
   while (instruction_counter < infos->codesize)
   {
      instruction_or_data = LDATA(current_instruction);
      assert(instruction_or_data != NULL);
      
      /* translate every single instruction */
      errorcode = translateInstruction
            (infos, (t_asm_instruction *) instruction_or_data, fp);

      /* verify the errorcode */
      if (errorcode != ASM_OK)
         return errorcode;
      
      /* update the instruction counter and the current instruction data */
      instruction_counter++;
      current_instruction = LNEXT(current_instruction);
   }

#ifndef NDEBUG
   fprintf(stderr, "\n");
#endif
   
   /* translate the data segment */
   while (current_instruction != NULL)
   {
      instruction_or_data = LDATA(current_instruction);
      assert(instruction_or_data != NULL);
      
      /* translate every single element of data */
#ifndef NDEBUG
      fprintf(stderr, "Adding data into the data segment [datatype == %s \t; "
            , dataType_toString(((t_asm_data *)instruction_or_data)->dataType) );
      fprintf(stderr, "value == 0x%08x] \n"
            , ((t_asm_data *)instruction_or_data)->value);
#endif
      
      errorcode = translateData(infos, (t_asm_data *) instruction_or_data, fp);
      
      /* verify the errorcode */
      if (errorcode != ASM_OK)
         return errorcode;
      
      current_instruction = LNEXT(current_instruction);
   }
   
#ifndef NDEBUG
   fprintf(stderr, "\n");
#endif

   return ASM_OK;
}
void Translator::generateCode()
{
    sourceOutput <<
        "void SMBEngine::code(int mode)\n" <<
        "{\n" <<
        TAB << "switch (mode)\n" <<
        TAB << "{\n" <<
        TAB << "case 0:\n" <<
        TAB << TAB << "loadConstantData();\n" <<
        TAB << TAB << "goto Start;\n" <<
        TAB << "case 1:\n" <<
        TAB << TAB << "goto NonMaskableInterrupt;\n" <<
        TAB << "}\n\n";
    
    // Search through the root node, and grab all code label nodes
    //
    for (std::list<AstNode*>::iterator it = root->children.begin();
         it != root->children.end(); ++it)
    {
        AstNode* node = (*it);

        if (node->type != AST_LABEL)
        {
            continue;
        }

        LabelNode* label = static_cast<LabelNode*>(node);
        if (label->labelType != LABEL_CODE)
        {
            continue;
        }

        // Output a C++ label for the label
        //
        sourceOutput << "\n";
        sourceOutput << label->value.s;

        // Output a comment, if the label has one
        //
        if (label->lineNumber != 0)
        {
            const char* comment = lookupComment(label->lineNumber);
            if (comment)
            {
                // Skip the first character of the ASM comment (;)
                //
                sourceOutput << " // " << (comment + 1);
            }
        }

        sourceOutput << "\n";

        // Translate each piece of code under the label...
        //
        ListNode* listElement = static_cast<ListNode*>(label->child);
        while (listElement != NULL)
        {
            AstNode* instruction = listElement->value.node;
            if (instruction->type == AST_INSTRUCTION)
            {
                sourceOutput << TAB << translateInstruction(static_cast<InstructionNode*>(instruction));

                if (instruction->lineNumber != 0)
                {
                    const char* comment = lookupComment(instruction->lineNumber);
                    if (comment)
                    {
                        // Skip the first character of the ASM comment (;)
                        //
                        sourceOutput << " // " << (comment + 1);
                    }
                }

                // Add a nice line separator after return statements
                //
                if (static_cast<InstructionNode*>(instruction)->code == RTS)
                {
                    sourceOutput << "\n\n";
                    sourceOutput << LINE_SEPARATOR_COMMENT;
                }
                else
                {
                    // Or just a newline for all other instructions
                    //
                    sourceOutput << "\n";
                }
                
                if (skipNextInstruction)
                {
                    // If we had a .db $2c instruction immediately before this one,
                    // we need to add a label to be able to skip this instruction
                    //
                    char indexStr[8];
                    sprintf(indexStr, "%d", skipNextInstructionIndex++);
                    sourceOutput << "Skip_" << indexStr << ":\n";

                    skipNextInstruction = false;
                }
            }
            else if (instruction->type == AST_DATA8 &&
                    strcmp(instruction->value.node->value.node->value.s, "$2c") == 0)
            {
                // Special case: .db $2c
                // We need to goto the next instruction
                //
                skipNextInstruction = true;
                char indexStr[8];
                sprintf(indexStr, "%d", skipNextInstructionIndex);
                sourceOutput << TAB << "goto Skip_" << indexStr << ";\n";
            }

            listElement = static_cast<ListNode*>(listElement->next);
        }
    }

    // Generate a return jump table at the end of the code
    //
    sourceOutput << 
        "// Return handler\n" <<
        "// This emulates the RTS instruction using a generated jump table\n" <<
        "//\n" <<
        "Return:\n" <<
        TAB << "switch (popReturnIndex())\n" <<
        TAB << "{\n";
    
    for (int i = 0; i < returnLabelIndex; i++)
    {
        char indexStr[8];
        sprintf(indexStr, "%d", i);
        sourceOutput <<
            TAB << "case " << indexStr << ":\n" <<
            TAB << TAB << "goto Return_" << indexStr << ";\n";
    }
    
    sourceOutput <<
        TAB << "}\n";
    
    // Final closing block for the code() function
    //
    sourceOutput << "}\n";
}