1 /* `Deep Thought', a softcore CPU implemented on a FPGA
3 Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "CInstrFactory.hpp"
28 * Purpose: loads a command from the given library file
30 * Parameter: std::string lib location of the library file
32 * Preconditions: lib references to a valid library
34 Iinstr* CInstrFactory::loadFromLib(string lib)
36 Iinstr* (*create_instruction)();
38 // load a Instruction from library
39 void* instruction = dlopen(lib.c_str(), RTLD_LAZY);
41 cerr << "Cannot load library: " << dlerror() << endl;
46 void* create = dlsym(instruction, "create_instruction");
47 void* destroy = dlsym(instruction, "destroy_instruction");
49 if (!create || !destroy) {
50 cerr << "Cannot load symbols: " << dlerror() << endl;
55 memcpy(&create_instruction, &create, sizeof(create));
57 Iinstr* instructionPointer = create_instruction();
59 m_libStore.insert(make_pair(instruction, instructionPointer));
61 return instructionPointer;
65 * Name: getNextInstruction
66 * Purpose: returns a pointer to a command
68 * Returns: Pointer to the loaded command
71 * Preconditions: a command is left to load
73 Iinstr* CInstrFactory::getNextInstr()
75 if(m_files.size() >= 1) {
77 instruction = loadFromLib(m_files[0]);
78 m_files.erase(m_files.begin());
82 throw string("No more instruction left!");
88 * Name: searchLibsInDir
89 * Purpose: finds librarys in the given directory
91 * Returns: number of found librarays
93 * Parameters: std::string dir Directory where the libraries are located
95 * Postconditions: all files with a trailing '.so' are ready to be used
97 size_t CInstrFactory::searchLibsInDir(string dir)
101 if((dp = opendir(dir.c_str())) == NULL) {
103 errmsg << "Error(" << errno << ") opening " << dir << endl;
107 while ((dirp = readdir(dp)) != NULL) {
108 string file = dirp->d_name;
109 if(file.size() >= 3) {
110 file = file.substr(file.size()-3);
111 std::transform(file.begin(), file.end(), file.begin(), ::tolower);
113 m_files.push_back(dir+"/"+string(dirp->d_name));
118 return m_files.size();
123 * Purpose: returns the number of librarys left
125 * Returns: size_t number of files left
127 size_t CInstrFactory::getNumFiles()
129 return m_files.size();
132 void CInstrFactory::loadLibsIntoMap(map<short, Iinstr*>& instr, string dir)
135 cout << "Loaded " << this->searchLibsInDir(dir) << " Libraryfiles" << endl;
137 this->searchLibsInDir(dir);
139 while(this->getNumFiles() >= 1) {
140 Iinstr* pinstr = this->getNextInstr();
141 instr.insert(make_pair(pinstr->getOpcode(),pinstr));
143 cout << "found: " << pinstr->getName() << " its opcode is : " << pinstr->getOpcode() << endl;
150 * Name: ~CInstrFactory
151 * Purpose: Destructor of the Object
153 CInstrFactory::~CInstrFactory()
155 void (*destroy_instruction)(Iinstr*);
157 while(!m_libStore.empty()) {
158 void* destroy = dlsym(m_libStore.begin()->first, "destroy_instruction");
159 memcpy(&destroy_instruction, &destroy, sizeof(destroy));
160 destroy_instruction(m_libStore.begin()->second);
161 dlclose(m_libStore.begin()->first);
162 m_libStore.erase(m_libStore.begin());