/*
* instructionlist.cpp
*
* This file contains static helper functions
*
* Copyright 2010 Tobias Wirtl, HBM <tobias.wirtl@hbm.com>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/

#include "instructionlist.h"
#include "helpers.h"
#include <fstream>
#include <exception>
#include <iostream>


using namespace std;


InstructionList::InstructionList(const string &filename)
{
    ifstream inFile;
    string bufInst;
    string bufBitcode;
    string bufOption;
    try
    {
        inFile.open(filename.c_str());
        if (inFile.good())
        {
            do
            {
                inFile>>bufInst;
                Helpers::strToLower(bufInst);
                inFile>>bufBitcode;
                inFile>>bufOption;
                this->instructions.push_back(new Instruction(bufInst,bufBitcode,bufOption));
            } while(!inFile.eof());
        }
        else
            cout<<"Can't read instruction list from file: "<<filename;
    }
    catch(const exception &e)
    {
        cout<<"Error reading instruction list: "<<e.what();
    }
}


unsigned int InstructionList::size()
{
    return this->instructions.size();
}

Instruction* InstructionList::getInstruction(int i)
{
    return this->instructions.at(i);
}


// get instruction object of a program row (null if not found)
Instruction* InstructionList::getInstructionOfInstructionStr(const string &instructionStr)
{
    unsigned int i;
    string tmp;
    Instruction* result = 0;

    for (i = 0; i < instructionStr.size(); i++)
    {
        if (instructionStr[i] != ' ')
            tmp += instructionStr[i];
        else
            break;
    }
    for (i = 0; i < instructions.size(); i++)
    {
        if (instructions[i]->getInstructionStr() == tmp)
            result = instructions[i];
    }
    return result;
}

//get instruction object of a bitcode (null if not found)
Instruction* InstructionList::getInstructionOfBitcodeStr(const string &bitcodeStr)
{
    Instruction* result = 0;
    unsigned int i1,i2;
    string bitMask;
    bool equal;

    //string* fordebug = new string(bitcodeStr);

    for(i1 = 0; i1 < this->instructions.size();i1++)
    {
        equal = true;
        bitMask = instructions[i1]->getBitMask();
        for (i2 = 0; i2 < 16; i2++)
        {
            if (bitcodeStr[i2] != bitMask[i2] && (bitMask[i2] == '1' || bitMask[i2] == '0'))
            {
                equal = false;
                break;
            }
        }
        if (equal)
        {
            result = instructions[i1];
            break;
        }
    }
    return result;
}
