Download | Plain Text | No Line Numbers


  1. /**
  2.  * @module cinstruction
  3.  * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
  4.  * @brief Abstract class for instructions
  5.  * @date 26.05.2009
  6.  */
  7.  
  8. #ifndef CINSTRUCTION_H
  9. #define CINSTRUCTION_H 1
  10.  
  11. #include <iostream>
  12. #include <list>
  13. #include <sstream>
  14. #include <boost/lexical_cast.hpp>
  15. #include <assert.h>
  16. #include <stdexcept>
  17.  
  18. /**
  19.  * @class CInstructionError
  20.  *
  21.  * Exception thrown by implemententations of CInstruction
  22.  */
  23. class CInstructionError
  24. : public std::invalid_argument
  25. {
  26. public:
  27. /**
  28.   * @method CInstructionError
  29.   * @brief Default exception ctor
  30.   * @param what message to pass along
  31.   * @return -
  32.   * @globalvars none
  33.   * @exception none
  34.   * @pre none
  35.   * @post none
  36.   */
  37. CInstructionError(const std::string& what)
  38. : std::invalid_argument(what)
  39. {}
  40. };
  41.  
  42. #include "ccpu.h"
  43.  
  44. /* forward declare CCPU */
  45. template <class T>
  46. class CCPU;
  47.  
  48. /**
  49.  * @class CInstruction
  50.  *
  51.  * Abstract class for instructions
  52.  */
  53. template <class T>
  54. class CInstruction
  55. {
  56. public:
  57. /**
  58.   * @method CInstruction
  59.   * @brief Default ctor
  60.   * @param name name of instruction
  61.   * @return -
  62.   * @globalvars none
  63.   * @exception none
  64.   * @pre none
  65.   * @post none
  66.   */
  67. CInstruction(std::string name)
  68. : m_name(name)
  69. {}
  70.  
  71. /**
  72.   * @method ~CInstruction
  73.   * @brief Default dtor
  74.   * @param -
  75.   * @return -
  76.   * @globalvars none
  77.   * @exception none
  78.   * @pre none
  79.   * @post none
  80.   */
  81. virtual ~CInstruction()
  82. {}
  83.  
  84. /**
  85.   * @method operator==
  86.   * @brief implementation of operator ==
  87.   * @param name reference to std::string
  88.   * @return true if instructionname is name
  89.   * @globalvars none
  90.   * @exception none
  91.   * @pre none
  92.   * @post none
  93.   */
  94. virtual bool operator==(std::string& name)
  95. {
  96. return name == m_name;
  97. }
  98.  
  99. /**
  100.   * @method operator()
  101.   * @brief implementation of operator (CCPU)
  102.   * @param cpu pointer to cpu
  103.   * @return -
  104.   * @globalvars none
  105.   * @exception CInstructionError
  106.   * @pre none
  107.   * @post none
  108.   */
  109. virtual CInstruction& operator()(CCPU<T> *cpu)
  110. {
  111. execute(cpu);
  112. return *this;
  113. }
  114.  
  115. /**
  116.   * @method getName
  117.   * @brief returns instruction name
  118.   * @param -
  119.   * @return name of instruction
  120.   * @globalvars none
  121.   * @exception none
  122.   * @pre none
  123.   * @post none
  124.   */
  125. virtual const std::string& getName()
  126. {
  127. return m_name;
  128. }
  129.  
  130. /**
  131.   * @method dump
  132.   * @brief dumps information about instruction to outputstream
  133.   * @param stream outputstream
  134.   * @return reference to outputstream
  135.   * @globalvars none
  136.   * @exception none
  137.   * @pre none
  138.   * @post none
  139.   */
  140. virtual std::ostream& dump(std::ostream& stream)
  141. {
  142. stream << m_name;
  143. return stream;
  144. }
  145.  
  146. /**
  147.   * @method operator<<
  148.   * @brief Shift/output operator for outputstream
  149.   * @param stream reference to outputstream
  150.   * @param instr object which will be printed to stream
  151.   * @return reference to outputstream
  152.   * @globalvars none
  153.   * @exception none
  154.   * @pre none
  155.   * @post none
  156.   */
  157. friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr)
  158. {
  159. return instr.dump(stream);
  160. }
  161.  
  162. /**
  163.   * @method parseRegister
  164.   * @brief parses register syntax Rx (e.g. "R1")
  165.   * @param str register in assembler syntax
  166.   * @return registernumber
  167.   * @globalvars none
  168.   * @exception CInstructionError
  169.   * @pre str != NULL
  170.   * @post none
  171.   */
  172. virtual const unsigned parseRegister(const std::string& str);
  173.  
  174. /**
  175.   * @method checkRegister
  176.   * @brief performs a register boundary check
  177.   * does the register exist in cpu?
  178.   * @param cpu pointer to cpu
  179.   * @param regidx registernumber
  180.   * @return -
  181.   * @globalvars none
  182.   * @exception CInstructionError
  183.   * @pre none
  184.   * @post none
  185.   */
  186. virtual void checkRegister(CCPU<T> *cpu, const unsigned regidx);
  187.  
  188. /**
  189.   * @method factory
  190.   * @brief creates a new instance of this instruction
  191.   * @param -
  192.   * @return new instruction instance
  193.   * @globalvars none
  194.   * @exception none
  195.   * @pre none
  196.   * @post none
  197.   */
  198. virtual CInstruction *factory() = 0;
  199.  
  200. /**
  201.   * @method compile
  202.   * @brief parses instruction parameters and prepares the
  203.   * instruction for executing
  204.   * @param params list of parameters of this instruction
  205.   * @return -
  206.   * @globalvars none
  207.   * @exception CInstructionError
  208.   * @pre none
  209.   * @post none
  210.   */
  211. virtual void compile(std::list<std::string>& params) = 0;
  212.  
  213. /**
  214.   * @method execute
  215.   * @brief executes the instruction
  216.   * @param cpu pointer to cpu
  217.   * @return -
  218.   * @globalvars none
  219.   * @exception CInstructionError
  220.   * @pre cpu valid (memory, program, registers valid)
  221.   * @post none
  222.   */
  223. virtual void execute(CCPU<T> *cpu) = 0;
  224.  
  225. protected:
  226. /* members */
  227. /** name of instruction */
  228. std::string m_name;
  229. };
  230.  
  231. /*----------------------------------------------------------------------------*/
  232.  
  233. template<class T>
  234. const unsigned CInstruction<T>::parseRegister(const std::string& str)
  235. {
  236. unsigned reg;
  237. if (str.length() < 2 || str[0] != 'r')
  238. throw CInstructionError("Invalid syntax of register");
  239.  
  240. try
  241. {
  242. reg = boost::lexical_cast<unsigned>(str.substr(1));
  243. }
  244. catch(boost::bad_lexical_cast& ex)
  245. {
  246. throw CInstructionError("Invalid syntax of register");
  247. }
  248.  
  249. return reg;
  250. }
  251.  
  252. /*----------------------------------------------------------------------------*/
  253.  
  254. template<class T>
  255. inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx)
  256. {
  257. assert(cpu != NULL);
  258. if (regidx >= cpu->getRegisterCount())
  259. {
  260. std::stringstream sstr;
  261. sstr << "Register R" << regidx << " doesn't exist (out of bound)";
  262. throw CInstructionError(sstr.str());
  263. }
  264. }
  265.  
  266. #endif
  267.  
  268. /* vim: set et sw=2 ts=2: */
  269.