OpenASIP 2.2
Loading...
Searching...
No Matches
TestOsal.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file TestOsal.cc
26 *
27 * Implementation of test_osal.
28 *
29 * @author Jussi Nykänen 2004 (nykanen-no.spam-cs.tut.fi)
30 * @author Pekka Jääskeläinen 2005 (pjaaskel-no.spam-cs.tut.fi)
31 * @note rating: red
32 */
33
34#include <iostream>
35
36#include "TestOsal.hh"
37#include "Operation.hh"
38#include "Conversion.hh"
39#include "SimValue.hh"
40#include "Application.hh"
41#include "LineReader.hh"
42#include "LineReaderFactory.hh"
43#include "CmdHelp.hh"
44#include "StringTools.hh"
45#include "InterpreterContext.hh"
46#include "OperationSimulator.hh"
47#include "IdealSRAM.hh"
48#include "BaseType.hh"
49#include "TCEString.hh"
50#include "tce_config.h"
51#include "OperationBehavior.hh"
52#include "OperationPool.hh"
53
54using std::string;
55using std::vector;
56using std::cout;
57using std::endl;
58using std::cerr;
59
60//////////////////////////////////////////////////////////////////////////////
61// CmdTrigger
62//////////////////////////////////////////////////////////////////////////////
63
64/**
65 * Constructor.
66 */
69
70/**
71 * Copy constructor.
72 */
75
76/**
77 * Destructor.
78 */
81
82/**
83 * Executes the trigger command of an operation.
84 *
85 * @param arguments The arguments for the command.
86 * @return True if the command is executed succesfully, otherwise false.
87 * @exception NumberFormatException If data object conversion fails.
88 */
89bool
90CmdTrigger::execute(const std::vector<DataObject>& arguments) {
91 ScriptInterpreter* scriptInterp = interpreter();
92 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
93 assert(interp != NULL);
94 DataObject* obj = new DataObject();
95
96 if (arguments.size() < 2) {
97 obj->setString("too few arguments");
98 interp->setResult(obj);
99 return false;
100 }
101
102 string opName = arguments[1].stringValue();
103
104 Operation* op = NULL;
105 try {
106 op = &interp->operation(opName);
107 } catch (const IllegalOperationBehavior& e) {
108 // Catch error due to undefined or missing operation behavior.
109 obj->setString(e.errorMessage());
110 interp->setResult(obj);
111 return false;
112 }
113
114 if (op == &NullOperation::instance()) {
115 obj->setString("unknown operation \"" + opName + "\"");
116 interp->setResult(obj);
117 return false;
118 }
119
120 // remove "trigger" and operation name.
121 vector<DataObject> inputs;
122 for (size_t i = 2; i < arguments.size(); i++) {
123 inputs.push_back(arguments[i]);
124 }
125
126 vector<SimValue*> args;
127 TesterContext& context = *dynamic_cast<TesterContext*>(&interp->context());
128 OperationContext& opContext = context.operationContext();
129
130 string result = "";
131
133 InstructionAddress oldPC = opContext.programCounter();
134
135 if (!simulator.simulateTrigger(*op, inputs, args, opContext, result)) {
136 for (unsigned int i = 0; i < args.size(); i++) {
137 delete args[i];
138 }
139 obj->setString(result);
140 interp->setResult(obj);
141 return false;
142 } else {
143
144 for (int i = 0; i < op->numberOfOutputs(); i++) {
145
146 SimValue* current = args[op->numberOfInputs() + i];
147 string output = context.toOutputFormat(current);
148 result += output;
149
150 // put blank everywhere else but after the last output
151 if (i < op->numberOfOutputs() - 1) {
152 result += " ";
153 }
154 }
155 }
156
157 for (unsigned int i = 0; i < args.size(); i++) {
158 delete args[i];
159 }
160
161 if (opContext.saveReturnAddress()) {
162 opContext.returnAddress() = oldPC;
163 }
164 obj->setString(result);
165 interp->setResult(obj);
166 return true;
167}
168
169/**
170 * Returns the help text of trigger command.
171 *
172 * @return The help text.
173 */
174string
176 return "trigger <operation> <operand>...";
177}
178
179//////////////////////////////////////////////////////////////////////////////
180// CmdReset
181//////////////////////////////////////////////////////////////////////////////
182
183/**
184 * Constructor.
185 */
188
189/**
190 * Copy constructor.
191 *
192 * @param cmd Command to be copied.
193 */
195}
196
197/**
198 * Destructor
199 */
202
203/**
204 * Executes the command.
205 *
206 * @param arguments Arguments for the command.
207 * @return True if the command is executed succesfully, otherwise false.
208 */
209bool
210CmdReset::execute(const std::vector<DataObject>& arguments) {
211 ScriptInterpreter* scriptInterp = interpreter();
212 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
213 assert(interp != NULL);
214
215 DataObject* result = new DataObject();
216 if (arguments.size() != 2) {
217 result->setString("wrong number of arguments");
218 interp->setResult(result);
219 return false;
220 }
221
222 string opName = arguments[1].stringValue();
223
224 Operation& op = interp->operation(opName);
225
226 if (&op == &NullOperation::instance()) {
227 result->setString("unknown operation \"" + opName + "\"");
228 interp->setResult(result);
229 return false;
230 }
231
232 TesterContext& context = *dynamic_cast<TesterContext*>(&interp->context());
233 OperationContext& opContext = context.operationContext();
234
235 OperationBehavior& behavior = op.behavior();
236 behavior.deleteState(opContext);
237 result->setString("");
238 interp->setResult(result);
239 return true;
240}
241
242/**
243 * Returns the help text of the command.
244 *
245 * @return The help text.
246 */
247string
249 return "Resets the state of the operation.\n\n"
250 "!reset <command name>";
251}
252
253//////////////////////////////////////////////////////////////////////////////
254// CmdOutput
255//////////////////////////////////////////////////////////////////////////////
256
257const string CmdOutput::OUTPUT_FORMAT_INT_SIGNED = "signed";
258const string CmdOutput::OUTPUT_FORMAT_INT_UNSIGNED = "unsigned";
259const string CmdOutput::OUTPUT_FORMAT_LONG_SIGNED = "long";
260const string CmdOutput::OUTPUT_FORMAT_LONG_UNSIGNED = "ulong";
261const string CmdOutput::OUTPUT_FORMAT_DOUBLE = "double";
262const string CmdOutput::OUTPUT_FORMAT_FLOAT = "float";
263const string CmdOutput::OUTPUT_FORMAT_HALF = "half";
264const string CmdOutput::OUTPUT_FORMAT_BIN = "bin";
265const string CmdOutput::OUTPUT_FORMAT_HEX = "hex";
266
267/**
268 * Constructor.
269 */
272
273/**
274 * Copy constructor.
275 *
276 * @param cmd Command to be copied.
277 */
280
281/**
282 * Destructor
283 */
286
287/**
288 * Executes the command.
289 *
290 * @param arguments Arguments for the command.
291 * @return True if the command is executed succesfully, otherwise false.
292 */
293bool
294CmdOutput::execute(const std::vector<DataObject>& arguments) {
295 ScriptInterpreter* scriptInterp = interpreter();
296 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
297 assert(interp != NULL);
298 DataObject* result = new DataObject();
299
300 if (arguments.size() != 2) {
301 result->setString("wrong number of arguments");
302 interp->setResult(result);
303 return false;
304 }
305
306 string outputFormat = arguments[1].stringValue();
307
308 if (outputFormat == OUTPUT_FORMAT_INT_SIGNED ||
309 outputFormat == OUTPUT_FORMAT_INT_UNSIGNED ||
310 outputFormat == OUTPUT_FORMAT_LONG_SIGNED ||
311 outputFormat == OUTPUT_FORMAT_LONG_UNSIGNED ||
312 outputFormat == OUTPUT_FORMAT_DOUBLE ||
313 outputFormat == OUTPUT_FORMAT_FLOAT ||
314 outputFormat == OUTPUT_FORMAT_HALF ||
315 outputFormat == OUTPUT_FORMAT_BIN ||
316 outputFormat == OUTPUT_FORMAT_HEX) {
317
319 *dynamic_cast<TesterContext*>(&interp->context());
320 context.setOutputFormat(outputFormat);
321 result->setString("");
322 interp->setResult(result);
323 } else {
324 result->setString("illegal output format \"" +
325 outputFormat +"\"");
326 interp->setResult(result);
327 return false;
328 }
329
330 return true;
331}
332
333/**
334 * Returns the help text of the command.
335 *
336 * @return The help text.
337 */
338string
340
341 ScriptInterpreter* scriptInterp = interpreter();
342 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
344 *dynamic_cast<TesterContext*>(&interp->context());
345
346 return
347 "Changes the format of the output between "
348 "int, double, float, bin and hex.\n"
349 "Currently \"" +
350 context.outputFormat() +
351 "\" is used.\n\n"
352 "!output {" +
356 OUTPUT_FORMAT_FLOAT + "|" +
357 OUTPUT_FORMAT_HALF + "|" +
358 OUTPUT_FORMAT_BIN + "|" +
359 OUTPUT_FORMAT_HEX + "}";
360}
361
362//////////////////////////////////////////////////////////////////////////////
363// OsalInterpreter
364//////////////////////////////////////////////////////////////////////////////
365
366/**
367 * Constructor.
368 */
373
374/**
375 * Destructor.
376 */
380
381/**
382 * Loads an operation and return a reference to it.
383 *
384 * @param name The name of the operation.
385 * @return The reference to operation.
386 */
388OsalInterpreter::operation(const std::string& name) {
389
391 operation_->name() != name) {
392 operation_ = &(pool_->operation(name.c_str()));
393 }
394
395 TesterContext& testCont = *dynamic_cast<TesterContext*>(&context());
396 OperationContext& opContext = testCont.operationContext();
399 beh.createState(opContext);
400 }
401
402 return *operation_;
403}
404
405//////////////////////////////////////////////////////////////////////////////
406// TesterContext
407//////////////////////////////////////////////////////////////////////////////
408
409/**
410 * Constructor.
411 */
413 InterpreterContext(), continue_(true), programCounterStorage_(0),
414 irfStartStorage_(0), branchDelayCycles_(3),
415 outputFormat_(CmdOutput::OUTPUT_FORMAT_INT_SIGNED),
416 opContext_(NULL, programCounterStorage_, returnAddressStorage_,
417 branchDelayCycles_) {
418
419}
420
421/**
422 * Destructor.
423 */
426
427/**
428 * Sets the continue_ flag off.
429 */
430void
432 continue_ = false;
433}
434
435/**
436 * Return true, if program can continue, false otherwise.
437 *
438 * @return True if program can continue, false otherwise.
439 */
440bool
442 return continue_;
443}
444
445/**
446 * Returns the operation context shared with all operations invoked in
447 * the application.
448 *
449 * @return The operations context shared with all operations invoked
450 * in the application.
451 */
456
457/**
458 * Returns the output format currently in use.
459 *
460 * @return The output format currently in use.
461 */
462string
466
467/**
468 * Sets the output format to be used in the future.
469 *
470 * @param The output format to be used in the future.
471 */
472void
476
477/**
478 * Converts given SimValue to output string.
479 *
480 * @param value Value to be converted.
481 * @return The value of SimValue as a string.
482 */
483string
485 string output = "";
486
487 // If output format is in hex or the value is wider than 64 bits
488 // convert the SimValue to hex using the full
489 // width of the value. This means that leading zeroes are included in
490 // the output result (e.g. 32 bit value 0x15 = 0x00000015).
492 value->width() > 64) {
493 output = value->hexValue();
496 output = Conversion::toString(value->sLongWordValue());
497
500 output = Conversion::toString(value->uLongWordValue());
501
503 DoubleWord doubleWord = value->doubleWordValue();
504 output = Conversion::toString(doubleWord);
505
507 FloatWord floatWord = value->floatWordValue();
508 output = Conversion::toString(floatWord);
509
511 HalfFloatWord halfFloatWord = value->halfFloatWordValue();
512 output = Conversion::toString(FloatWord(float(halfFloatWord)));
513
515 output = value->binaryValue();
516 output += 'b';
517 }
518 return output;
519}
520
521/**
522 * Returns the program counter as SimValue.
523 *
524 * @return Program counter as SimValue.
525 */
530
531/**
532 * Returns the return address as SimValue.
533 *
534 * @return Return address as SimValue.
535 */
540
541
542//////////////////////////////////////////////////////////////////////////////
543// CmdQuit
544//////////////////////////////////////////////////////////////////////////////
545
546/**
547 * Constructor.
548 */
551
552/**
553 * Copy constructor.
554 *
555 * @param cmd Command to be copied.
556 */
558}
559
560/**
561 * Destructor.
562 */
565
566/**
567 * Executes the command.
568 *
569 * The execution of the quit command will stop the program.
570 *
571 * @param arguments Arguments for the command.
572 * @exception NumberFormatException If DataObject conversion fails.
573 * @return True if execution is successful, false otherwise.
574 */
575bool
576CmdQuit::execute(const std::vector<DataObject>& arguments) {
577 ScriptInterpreter* scriptInterp = interpreter();
578 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
579 DataObject* result = new DataObject();
580 assert(interp != NULL);
581
582 if (arguments.size() != 1) {
583 result->setString("wrong number of arguments");
584 interp->setResult(result);
585 return false;
586 }
587
588 InterpreterContext& interpCont = interp->context();
589 TesterContext& testCont = *dynamic_cast<TesterContext*>(&interpCont);
590 testCont.stop();
591 result->setString("");
592 interp->setResult(result);
593 return true;
594}
595
596/**
597 * Returns the help text of the command.
598 *
599 * @return The help text.
600 */
601string
603 return "exits the program";
604}
605
606//////////////////////////////////////////////////////////////////////////////
607// CmdRegister
608//////////////////////////////////////////////////////////////////////////////
609
610const string CmdRegister::REGISTER_PROGRAM_COUNTER = "programcounter";
611const string CmdRegister::REGISTER_RETURN_ADDRESS = "returnaddress";
612
613/**
614 * Constructor.
615 */
618
619/**
620 * Copy constructor.
621 *
622 * @param cmd Command to be copied.
623 */
626
627/**
628 * Destructor.
629 */
632
633/**
634 * Executes the command.
635 *
636 * Output is the value of given register.
637 *
638 * @param arguments Arguments for the command.
639 * @return True if the execution is successful, false otherwise.
640 * @exception NumberFormatException If DataObject conversion fails.
641 */
642bool
643CmdRegister::execute(const std::vector<DataObject>& arguments) {
644 ScriptInterpreter* scriptInterp = interpreter();
645 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
646 assert(interp != NULL);
647 DataObject* result = new DataObject();
648
649 if (arguments.size() != 2) {
650 result->setString("wrong number of arguments");
651 interp->setResult(result);
652 return false;
653 }
654
655 string registerValue = arguments[1].stringValue();
656
658 *(dynamic_cast<TesterContext*>(&interp->context()));
659
660 string output = "";
661
662 if (registerValue == REGISTER_PROGRAM_COUNTER) {
663 InstructionAddress& addr = context.programCounter();
664 SimValue value(64);
665 value = addr;
666 output = context.toOutputFormat(&value);
667 } else if (registerValue == REGISTER_RETURN_ADDRESS) {
668 SimValue& addr = context.returnAddress();
669 SimValue value(64);
670 value = addr;
671 output = context.toOutputFormat(&value);
672 } else {
673 result->setString("illegal register name \"" +
674 registerValue + "\"");
675 interp->setResult(result);
676 return false;
677 }
678
679 result->setString(output);
680 interp->setResult(result);
681 return true;
682}
683
684/**
685 * Returns the help text of the command.
686 *
687 * @return The help text.
688 */
689string
691 return
692 "Prints the contents of the register. Register is one of the "
693 "following:\n{" +
696}
697
698//////////////////////////////////////////////////////////////////////////////
699// CmdRegister
700//////////////////////////////////////////////////////////////////////////////
701
702const string CmdMem::MEM_BYTE = "byte";
703const string CmdMem::MEM_HALF_WORD = "halfword";
704const string CmdMem::MEM_WORD = "word";
705const string CmdMem::MEM_DOUBLE_WORD = "double";
706
707/**
708 * Constructor.
709 */
712
713/**
714 * Copy constructor.
715 *
716 * @param cmd Command to be copied.
717 */
719}
720
721/**
722 * Destructor.
723 */
726
727/**
728 * Executes the command.
729 *
730 * @param arguments Arguments for the command.
731 * @return True if execution is successful, false otherwise.
732 * @exception NumberFormatException If DataObject conversion fails.
733 */
734bool
735CmdMem::execute(const std::vector<DataObject>& arguments) {
736 ScriptInterpreter* scriptInterp = interpreter();
737 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
738 assert(interp != NULL);
739
740 DataObject* result = new DataObject();
741
742 if (arguments.size() != 3) {
743 result->setString("wrong number of arguments");
744 interp->setResult(result);
745 return false;
746 }
747
748 string size = arguments[1].stringValue();
749
750 if (size != MEM_BYTE &&
751 size != MEM_HALF_WORD &&
752 size != MEM_WORD &&
753 size != MEM_DOUBLE_WORD) {
754
755 result->setString("invalid memory size: " + size);
756 interp->setResult(result);
757 return false;
758 }
759
761 *(dynamic_cast<TesterContext*>(&interp->context()));
762
763 Memory& memory = context.operationContext().memory();
764
765 Word address = 0;
766 string addressString = arguments[2].stringValue();
767
768 try {
769 address = Conversion::toInt(addressString);
770 } catch(const NumberFormatException& n) {
771 result->setString("illegal address: " + addressString);
772 interp->setResult(result);
773 return false;
774 }
775
776 SimValue resultValue(64);
777
778 try {
779 if (context.outputFormat() == CmdOutput::OUTPUT_FORMAT_LONG_UNSIGNED ||
781 resultValue.setBitWidth(64);
782 }
783 if (size == MEM_BYTE) {
784 resultValue.setBitWidth(8);
785 ULongWord resultInt = 0;
786 memory.read(address, 1, resultInt);
787 resultValue = resultInt;
788 } else if (size == MEM_HALF_WORD) {
789 resultValue.setBitWidth(16);
790 ULongWord resultInt = 0;
791 memory.read(address, 2, resultInt);
792 resultValue = resultInt;
793 } else if (size == MEM_WORD) {
794 resultValue.setBitWidth(32);
795 ULongWord resultInt = 0;
796 memory.read(address, 4, resultInt);
797 resultValue = resultInt;
798 } else if (size == MEM_DOUBLE_WORD) {
799 resultValue.setBitWidth(64);
800
801 DoubleWord result = 0.0;
802 // TODO: when to read in LE?
803 memory.readBE(address, result);
804 resultValue = result;
805 }
806 } catch (const OutOfRange& o) {
807 string addressString = Conversion::toString(address);
808 result->setString("address " + addressString + " out of memory bounds");
809 interp->setResult(result);
810 return false;
811 }
812 string output = context.toOutputFormat(&resultValue);
813 result->setString(output);
814 interp->setResult(result);
815 return true;
816}
817
818/**
819 * Returns the help text of the command.
820 *
821 * @return The help text.
822 */
823string
825 return
826 "Prints the contents of the memory.\n"
827 "!mem <size> <address>\n"
828 "size is one of the following:\n{" +
829 MEM_BYTE + "|" + MEM_HALF_WORD + "|" + MEM_WORD + "|" +
830 MEM_DOUBLE_WORD + "}";
831}
832
833//////////////////////////////////////////////////////////////////////////////
834// CmdAdvanceClock
835//////////////////////////////////////////////////////////////////////////////
836
837/**
838 * Constructor.
839 */
842
843/**
844 * Copy constructor.
845 *
846 * @param cmd Command to be copied.
847 */
851
852/**
853 * Destructor.
854 */
857
858/**
859 * Executes the command.
860 *
861 * @param arguments Arguments for the command.
862 * @return True if execution is successful.
863 * @exception NumberFormatException If DataObject conversion fails.
864 */
865bool
866CmdAdvanceClock::execute(const std::vector<DataObject>& arguments) {
867 ScriptInterpreter* scriptInterp = interpreter();
868 OsalInterpreter* interp = dynamic_cast<OsalInterpreter*>(scriptInterp);
869 assert(interp != NULL);
870
871 DataObject* result = new DataObject();
872
873 if (arguments.size() != 1) {
874 result->setString("wrong number of arguments");
875 interp->setResult(result);
876 return false;
877 }
878
880 *(dynamic_cast<TesterContext*>(&interp->context()));
881
882 Memory& memory = context.operationContext().memory();
883 memory.advanceClock();
884 context.operationContext().advanceClock();
885 result->setString("");
886 interp->setResult(result);
887 return true;
888}
889
890/**
891 * Returns the help text of the command.
892 *
893 * @return The help text.
894 */
895string
897 return "Advances clock per one cycle";
898}
899
900//////////////////////////////////////////////////////////////////////////////
901// OsalCmdLineOptions
902//////////////////////////////////////////////////////////////////////////////
903
904/**
905 * Constructor.
906 */
909
910/**
911 * Destructor.
912 */
915
916/**
917 * Prints the version of the program.
918 */
919void
921 cout << "test_osal - OSAL Tester "
923}
924
925/**
926 * Prints the help menu of the program.
927 */
928void
930 string helpText = "test_osal\n\tcommands:\n";
931 helpText += "\t<operation> param...: Executes operation with parameters.\n";
932 helpText += "\t!quit: Quits the execution of the program.\n";
933 cout << helpText << endl;
934}
935
936// function declaration
937void executeCommand(OsalInterpreter& interpreter, string command);
938
939/**
940 * Main program.
941 */
942int main(int argc, char* argv[]) {
943
945 try {
946 options.parse(argv, argc);
947 } catch (ParserStopRequest const&) {
948 return EXIT_SUCCESS;
949 } catch (const IllegalCommandLine& i) {
950 cerr << i.errorMessage() << endl;
951 return EXIT_FAILURE;
952 }
953
954 OsalInterpreter interpreter;
956 TesterContext context;
957 CmdTrigger* trigger = new CmdTrigger();
958 CmdHelp* help = new CmdHelp();
959 CmdReset* reset = new CmdReset();
960 CmdOutput* output = new CmdOutput();
961 CmdQuit* quit = new CmdQuit();
962 CmdRegister* reg = new CmdRegister();
963 CmdMem* mem = new CmdMem();
964 CmdAdvanceClock* clock = new CmdAdvanceClock();
965
966 interpreter.initialize(argc, argv, &context, reader);
967 interpreter.addCustomCommand(trigger);
968 interpreter.addCustomCommand(help);
969 interpreter.addCustomCommand(reset);
970 interpreter.addCustomCommand(output);
971 interpreter.addCustomCommand(quit);
972 interpreter.addCustomCommand(reg);
973 interpreter.addCustomCommand(mem);
974 interpreter.addCustomCommand(clock);
975 reader->initialize(">> ");
976
977 // memory is 64k bytes
978 // TODO: what endianess
979 IdealSRAM* memory = new IdealSRAM(0, 65535, 8, false);
980 context.operationContext().setMemory(memory);
981
982 if (options.numberOfArguments() > 0) {
983 // batch mode
984
985 string command = "trigger ";
986 for (int i = 1; i <= options.numberOfArguments(); i++) {
987 string token = options.argument(i);
988 if (token.substr(token.size() - 1) == ";") {
989 // an end of the command
990 command += token.substr(0, token.size() - 1);
991 executeCommand(interpreter, command);
992 command = "trigger ";
993 } else {
994 command += token + " ";
995 }
996 }
997 if (command != "") {
998 executeCommand(interpreter, command);
999 }
1000
1001 } else {
1002 // interactive mode
1003 string command = "";
1004 InterpreterContext& interpCont = interpreter.context();
1005 TesterContext& testCont = *dynamic_cast<TesterContext*>(&interpCont);
1006 while (testCont.cont()) {
1007 try {
1008 command = reader->readLine();
1009 } catch (const EndOfFile&) {
1010 interpreter.interpret("quit\n");
1011 break;
1012 }
1013 command = StringTools::trim(command);
1014 if (command == "") {
1015 continue;
1016 }
1017 if (command.find("!") == string::npos) {
1018 command = "trigger " + command;
1019 } else {
1020 command = command.substr(1, command.length());
1021 }
1022 executeCommand(interpreter, command);
1023 }
1024 }
1025 delete reader;
1026 delete memory;
1027 interpreter.finalize();
1028 return EXIT_SUCCESS;
1029}
1030
1031/**
1032 * Executes given command with interpreter.
1033 *
1034 * @param interpreter Interpreter which executes the command.
1035 * @param command The command to be executed.
1036 * @param print True, if result is printed.
1037 */
1038void
1039executeCommand(OsalInterpreter& interpreter, string command) {
1040 bool succeeded = interpreter.interpret(command);
1041 if (interpreter.result() != "") {
1042 if (!succeeded) {
1043 cout << "Error: ";
1044 }
1045 cout << interpreter.result() << endl;
1046 }
1047}
#define assert(condition)
unsigned long ULongWord
Definition BaseType.hh:51
UInt32 InstructionAddress
Definition BaseType.hh:175
float FloatWord
Definition BaseType.hh:160
double DoubleWord
Definition BaseType.hh:166
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
int main(int argc, char *argv[])
Definition TestOsal.cc:942
void executeCommand(OsalInterpreter &interpreter, string command)
Definition TestOsal.cc:1039
static std::string TCEVersionString()
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:866
virtual ~CmdAdvanceClock()
Definition TestOsal.cc:855
virtual std::string helpText() const
Definition TestOsal.cc:896
void parse(char *argv[], int argc)
virtual std::string argument(int index) const
virtual int numberOfArguments() const
static const std::string MEM_DOUBLE_WORD
Name for double word memory access.
Definition TestOsal.hh:178
virtual std::string helpText() const
Definition TestOsal.cc:824
static const std::string MEM_WORD
Name for word memory access.
Definition TestOsal.hh:176
virtual ~CmdMem()
Definition TestOsal.cc:724
static const std::string MEM_HALF_WORD
Name for half word memory access.
Definition TestOsal.hh:174
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:735
static const std::string MEM_BYTE
Name for byte memory access.
Definition TestOsal.hh:172
static const std::string OUTPUT_FORMAT_BIN
Definition TestOsal.hh:124
static const std::string OUTPUT_FORMAT_LONG_SIGNED
Definition TestOsal.hh:119
static const std::string OUTPUT_FORMAT_DOUBLE
Definition TestOsal.hh:121
virtual ~CmdOutput()
Definition TestOsal.cc:284
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:294
static const std::string OUTPUT_FORMAT_HALF
Definition TestOsal.hh:123
static const std::string OUTPUT_FORMAT_FLOAT
Definition TestOsal.hh:122
virtual std::string helpText() const
Definition TestOsal.cc:339
static const std::string OUTPUT_FORMAT_INT_SIGNED
Definition TestOsal.hh:117
static const std::string OUTPUT_FORMAT_LONG_UNSIGNED
Definition TestOsal.hh:120
static const std::string OUTPUT_FORMAT_HEX
Definition TestOsal.hh:125
static const std::string OUTPUT_FORMAT_INT_UNSIGNED
Definition TestOsal.hh:118
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:576
virtual std::string helpText() const
Definition TestOsal.cc:602
virtual ~CmdQuit()
Definition TestOsal.cc:563
static const std::string REGISTER_PROGRAM_COUNTER
Definition TestOsal.hh:148
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:643
virtual ~CmdRegister()
Definition TestOsal.cc:630
static const std::string REGISTER_RETURN_ADDRESS
Definition TestOsal.hh:149
virtual std::string helpText() const
Definition TestOsal.cc:690
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:210
virtual std::string helpText() const
Definition TestOsal.cc:248
virtual ~CmdReset()
Definition TestOsal.cc:200
virtual ~CmdTrigger()
Definition TestOsal.cc:79
virtual std::string helpText() const
Definition TestOsal.cc:175
virtual bool execute(const std::vector< DataObject > &arguments)
Definition TestOsal.cc:90
static std::string toString(const T &source)
static int toInt(const T &source)
InterpreterContext * context() const
ScriptInterpreter * interpreter() const
virtual void setString(std::string value)
std::string errorMessage() const
Definition Exception.cc:123
static LineReader * lineReader()
virtual void initialize(std::string defPrompt="", FILE *in=stdin, FILE *out=stdout, FILE *err=stderr)=0
virtual std::string readLine(std::string prompt="")=0
virtual void readBE(ULongWord address, int size, ULongWord &data)
Definition Memory.cc:640
virtual void advanceClock()
Definition Memory.cc:819
virtual Memory::MAU read(ULongWord address)=0
Definition Memory.cc:160
static NullOperation & instance()
virtual void createState(OperationContext &context) const
virtual void deleteState(OperationContext &context) const
void setMemory(Memory *memory)
SimValue & returnAddress()
InstructionAddress & programCounter()
Operation & operation(const char *name)
static OperationSimulator & instance()
bool simulateTrigger(Operation &op, std::vector< DataObject > inputs, std::vector< SimValue * > &outputs, OperationContext &context, std::string &result)
virtual TCEString name() const
Definition Operation.cc:93
virtual OperationBehavior & behavior() const
Definition Operation.cc:388
virtual int numberOfInputs() const
Definition Operation.cc:192
virtual int numberOfOutputs() const
Definition Operation.cc:202
virtual void printVersion() const
Definition TestOsal.cc:920
virtual void printHelp() const
Definition TestOsal.cc:929
virtual ~OsalCmdLineOptions()
Definition TestOsal.cc:913
virtual ~OsalInterpreter()
Definition TestOsal.cc:377
Operation * operation_
Last loaded operation.
Definition TestOsal.hh:260
Operation & operation(const std::string &name)
Definition TestOsal.cc:388
OperationPool * pool_
Used to load operations.
Definition TestOsal.hh:258
virtual void finalize()
virtual std::string result()
virtual void addCustomCommand(CustomCommand *command)
virtual void setResult(DataObject *result)
HalfFloatWord halfFloatWordValue() const
Definition SimValue.cc:1098
void setBitWidth(int width)
Definition SimValue.cc:113
ULongWord uLongWordValue() const
Definition SimValue.cc:1027
DoubleWord doubleWordValue() const
Definition SimValue.cc:1052
TCEString hexValue(bool noHexIdentifier=false) const
Definition SimValue.cc:1150
TCEString binaryValue() const
Definition SimValue.cc:1121
FloatWord floatWordValue() const
Definition SimValue.cc:1075
int width() const
Definition SimValue.cc:103
SLongWord sLongWordValue() const
Definition SimValue.cc:997
virtual void initialize(int argc, char *argv[], InterpreterContext *context, LineReader *reader)
virtual bool interpret(const std::string &commandLine)
virtual InterpreterContext & context() const
static std::string trim(const std::string &source)
std::string toOutputFormat(SimValue *value)
Definition TestOsal.cc:484
OperationContext & operationContext()
Definition TestOsal.cc:453
bool continue_
Flag indicating whether program can continue or not.
Definition TestOsal.hh:230
virtual ~TesterContext()
Definition TestOsal.cc:424
SimValue & returnAddress()
Definition TestOsal.cc:537
bool cont() const
Definition TestOsal.cc:441
void setOutputFormat(std::string outputFormat)
Definition TestOsal.cc:473
std::string outputFormat_
Indicates which output format is used currently.
Definition TestOsal.hh:236
InstructionAddress & programCounter()
Definition TestOsal.cc:527
OperationContext opContext_
The operation context shared with all operations invoked in the application.
Definition TestOsal.hh:239
std::string outputFormat() const
Definition TestOsal.cc:463