├── VERSION ├── test ├── run-c2050623.sh ├── run-c2100120.sh ├── run-c2171031.sh ├── run-c2181031.sh ├── run-c2191030.sh ├── run-c2201103.sh ├── run-c2221028.sh ├── run-c2231030.sh ├── run-c2241029.sh ├── run-c2060705a.sh ├── run-c2060705b.sh ├── run-c2130204a.sh ├── run-c2130204b.sh ├── run-c2141107a.sh ├── run-c2141107b.sh ├── run-c2141107r.sh ├── run-c2191030w.sh ├── program-ex1 ├── ex2.cycles ├── ex3.cycles ├── c2181030.cycles ├── c2181031.cycles ├── c2060705b.cycles ├── c2130204b.cycles ├── c2060705a.cycles ├── c2130204a.cycles ├── ex1.cycles ├── c2241029.cycles ├── c2191030.cycles ├── c2191030w.cycles ├── c2201103.cycles ├── c2221028.cycles ├── c2251030.cycles ├── c2171031.cycles ├── c2231030.cycles ├── c2141107b.cycles ├── c2141107r.cycles ├── c2141107a.cycles ├── run-ex2.sh ├── run-ex3.sh ├── c2100120.cycles ├── c2050623.cycles ├── run-ss05.sh ├── run-ex1.sh ├── run-tom02a.sh ├── run-tom02b.sh ├── run-tom04a.sh ├── run-tom04b.sh ├── run-tom05a.sh ├── run-tom05b.sh ├── run-tom05r.sh ├── run-tom06.sh ├── run-c2251030.sh ├── run-tom07.sh ├── run-tom082.sh ├── run-tom08r.sh ├── run-tom08w.sh ├── run-tom09.sh ├── run-tom10.sh ├── run-tom11.sh ├── run-tom01.sh └── run-tom03.sh ├── freess.wasm ├── parameters.png ├── processor_diagram.png ├── lib ├── version.h ├── getopt1.h ├── queue.h ├── Makefile ├── getopt.h ├── getopt1.c ├── queue.c ├── sui.h ├── getopt.c └── sui.c ├── RELEASE ├── printout.sh ├── run-freess.js ├── superscalar.h ├── .gitignore ├── TODO ├── LICENSE ├── configure ├── extractcycles.sh ├── main.h ├── Makefile ├── makefile.in ├── docheck.sh ├── README.md ├── main.tbi ├── index.html ├── freessini └── main.c /VERSION: -------------------------------------------------------------------------------- 1 | freess 1.1 2 | -------------------------------------------------------------------------------- /test/run-c2050623.sh: -------------------------------------------------------------------------------- 1 | run-tom01.sh -------------------------------------------------------------------------------- /test/run-c2100120.sh: -------------------------------------------------------------------------------- 1 | run-tom03.sh -------------------------------------------------------------------------------- /test/run-c2171031.sh: -------------------------------------------------------------------------------- 1 | run-tom06.sh -------------------------------------------------------------------------------- /test/run-c2181031.sh: -------------------------------------------------------------------------------- 1 | run-ss05.sh -------------------------------------------------------------------------------- /test/run-c2191030.sh: -------------------------------------------------------------------------------- 1 | run-tom08r.sh -------------------------------------------------------------------------------- /test/run-c2201103.sh: -------------------------------------------------------------------------------- 1 | run-tom09.sh -------------------------------------------------------------------------------- /test/run-c2221028.sh: -------------------------------------------------------------------------------- 1 | run-tom10.sh -------------------------------------------------------------------------------- /test/run-c2231030.sh: -------------------------------------------------------------------------------- 1 | run-tom11.sh -------------------------------------------------------------------------------- /test/run-c2241029.sh: -------------------------------------------------------------------------------- 1 | run-tom07.sh -------------------------------------------------------------------------------- /test/run-c2060705a.sh: -------------------------------------------------------------------------------- 1 | run-tom02a.sh -------------------------------------------------------------------------------- /test/run-c2060705b.sh: -------------------------------------------------------------------------------- 1 | run-tom02b.sh -------------------------------------------------------------------------------- /test/run-c2130204a.sh: -------------------------------------------------------------------------------- 1 | ./run-tom04a.sh -------------------------------------------------------------------------------- /test/run-c2130204b.sh: -------------------------------------------------------------------------------- 1 | ./run-tom04b.sh -------------------------------------------------------------------------------- /test/run-c2141107a.sh: -------------------------------------------------------------------------------- 1 | run-tom05a.sh -------------------------------------------------------------------------------- /test/run-c2141107b.sh: -------------------------------------------------------------------------------- 1 | run-tom05b.sh -------------------------------------------------------------------------------- /test/run-c2141107r.sh: -------------------------------------------------------------------------------- 1 | run-tom05r.sh -------------------------------------------------------------------------------- /test/run-c2191030w.sh: -------------------------------------------------------------------------------- 1 | run-tom08w.sh -------------------------------------------------------------------------------- /freess.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robgiorgi/freess/HEAD/freess.wasm -------------------------------------------------------------------------------- /parameters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robgiorgi/freess/HEAD/parameters.png -------------------------------------------------------------------------------- /processor_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robgiorgi/freess/HEAD/processor_diagram.png -------------------------------------------------------------------------------- /lib/version.h: -------------------------------------------------------------------------------- 1 | #define VERSION "0.91" 2 | #define RELDATE "6-Nov-" 3 | #define MACHINE "i586" 4 | #define OSYSTEM "Linux 2.0.24" 5 | -------------------------------------------------------------------------------- /test/program-ex1: -------------------------------------------------------------------------------- 1 | #! 1 2 | #x 1 10 3 | #x 4 40 4 | #x 5 50 5 | #x 6 60 6 | 1 3 4 0 # LW 7 | 1 7 5 128 # LW 8 | 7 7 7 3 # MUL 9 | 6 1 1 -1 # ADDI 10 | 2 7 6 256 # SW 11 | 6 2 2 8 # ADDI 12 | 4 1 0 -7 # BNE 13 | -------------------------------------------------------------------------------- /test/ex2.cycles: -------------------------------------------------------------------------------- 1 | 2 3 4 5 6 2 | 2 5 5 6 7 3 | 2 4 7 7 8 4 | 2 3 3 4 8 5 | 3 6 6 6 8 6 | 4 5 6 7 8 7 | 4 7 7 8 9 8 | 4 6 9 9 10 9 | 4 5 5 6 10 10 | 5 8 8 8 10 11 | 6 7 8 9 10 12 | 6 9 9 10 11 13 | 6 8 10 10 11 14 | 7 8 8 9 11 15 | 8 10 10 10 11 16 | -------------------------------------------------------------------------------- /test/ex3.cycles: -------------------------------------------------------------------------------- 1 | 2 3 4 5 6 2 | 2 5 5 6 7 3 | 3 4 6 6 8 4 | 3 4 4 5 9 5 | 4 6 6 6 10 6 | 5 6 7 8 11 7 | 5 8 8 9 12 8 | 6 7 9 9 13 9 | 6 7 7 8 14 10 | 7 9 9 9 15 11 | 8 9 10 11 16 12 | 8 11 11 12 17 13 | 9 10 12 12 18 14 | 9 10 10 11 19 15 | 10 12 12 12 20 16 | -------------------------------------------------------------------------------- /test/c2181030.cycles: -------------------------------------------------------------------------------- 1 | 2 3 4 6 7 2 | 2 6 6 11 12 3 | 2 4 11 11 12 4 | 2 3 3 4 12 5 | 3 6 6 6 12 6 | 4 5 6 8 13 7 | 4 8 8 13 14 8 | 4 6 13 13 14 9 | 4 5 5 6 14 10 | 5 8 8 8 14 11 | 7 8 9 11 15 12 | 13 14 14 19 20 13 | 13 14 19 19 20 14 | 14 15 15 16 20 15 | 14 15 15 15 20 16 | -------------------------------------------------------------------------------- /test/c2181031.cycles: -------------------------------------------------------------------------------- 1 | 2 3 4 6 7 2 | 2 6 6 11 12 3 | 2 4 11 11 12 4 | 2 3 3 4 12 5 | 3 6 6 6 12 6 | 4 5 6 8 13 7 | 4 8 8 13 14 8 | 4 6 13 13 14 9 | 4 5 5 6 14 10 | 5 8 8 8 14 11 | 7 8 9 11 15 12 | 13 14 14 19 20 13 | 13 14 19 19 20 14 | 14 15 15 16 20 15 | 14 15 15 15 20 16 | -------------------------------------------------------------------------------- /test/c2060705b.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 2 5 5 6 7 3 | 3 4 7 7 8 4 | 4 6 6 7 9 5 | 5 7 7 7 10 6 | 6 8 9 10 11 7 | 7 11 11 12 13 8 | 8 9 13 13 14 9 | 9 10 10 11 15 10 | 10 13 13 13 16 11 | 11 12 14 15 17 12 | 12 16 16 17 18 13 | 13 14 18 18 19 14 | 14 15 15 16 20 15 | 15 18 18 18 21 16 | -------------------------------------------------------------------------------- /test/c2130204b.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 5 6 2 | 2 6 6 7 8 3 | 3 4 8 8 9 4 | 4 5 5 6 10 5 | 5 8 8 8 11 6 | 6 7 9 11 12 7 | 7 12 12 13 14 8 | 8 9 14 14 15 9 | 9 10 10 12 16 10 | 10 14 14 14 17 11 | 11 13 15 17 18 12 | 13 18 18 19 20 13 | 14 15 20 20 21 14 | 15 16 16 18 22 15 | 16 20 20 20 23 16 | -------------------------------------------------------------------------------- /test/c2060705a.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 2 5 5 6 7 3 | 3 4 7 7 8 4 | 4 6 6 7 9 5 | 5 7 7 7 10 6 | 8 9 10 11 12 7 | 9 12 12 13 14 8 | 10 11 14 14 15 9 | 11 13 13 14 16 10 | 12 14 14 14 17 11 | 15 16 17 18 19 12 | 16 19 19 20 21 13 | 17 18 21 21 22 14 | 18 20 20 21 23 15 | 19 21 21 21 24 16 | -------------------------------------------------------------------------------- /test/c2130204a.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 5 6 2 | 2 6 6 7 8 3 | 3 4 8 8 9 4 | 4 5 5 6 10 5 | 5 8 8 8 11 6 | 9 10 11 13 14 7 | 10 14 14 15 16 8 | 11 12 16 16 17 9 | 12 13 13 14 18 10 | 13 16 16 16 19 11 | 17 18 19 21 22 12 | 18 22 22 23 24 13 | 19 20 24 24 25 14 | 20 21 21 22 26 15 | 21 24 24 24 27 16 | -------------------------------------------------------------------------------- /test/ex1.cycles: -------------------------------------------------------------------------------- 1 | 2 3 4 6 7 2 | 2 4 5 7 8 3 | 2 7 7 12 13 4 | 2 3 3 4 13 5 | 3 5 12 12 13 6 | 3 4 4 5 13 7 | 3 4 4 4 14 8 | 4 6 7 9 14 9 | 4 7 8 10 14 10 | 4 10 10 15 16 11 | 4 5 5 6 16 12 | 5 8 15 15 16 13 | 5 6 6 7 16 14 | 5 6 6 6 17 15 | 6 9 10 12 17 16 | 6 10 11 13 17 17 | 6 13 13 18 19 18 | 6 7 7 8 19 19 | 7 11 18 18 19 20 | 7 8 8 9 19 21 | 7 8 8 8 20 22 | -------------------------------------------------------------------------------- /test/c2241029.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 5 6 2 | 1 6 6 8 9 3 | 2 3 10 10 11 4 | 2 4 4 6 12 5 | 3 9 9 9 13 6 | 4 7 8 10 14 7 | 4 11 11 13 15 8 | 5 8 15 15 16 9 | 5 10 10 11 17 10 | 6 14 14 14 18 11 | 7 12 13 15 19 12 | 7 16 16 18 20 13 | 8 13 20 20 21 14 | 8 15 15 16 22 15 | 9 19 19 19 23 16 | 12 17 18 20 24 17 | 12 21 21 23 25 18 | 13 18 24 24 26 19 | 13 20 20 21 27 20 | 14 24 24 24 28 21 | -------------------------------------------------------------------------------- /test/c2191030.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 13 14 3 | 1 3 23 23 24 4 | 2 4 4 5 25 5 | 2 14 14 14 26 6 | 3 6 8 14 27 7 | 3 15 15 19 28 8 | 3 7 24 24 29 9 | 4 8 8 9 30 10 | 4 20 20 20 31 11 | 6 10 13 18 32 12 | 9 19 19 23 33 13 | 9 11 25 25 34 14 | 9 12 12 15 35 15 | 14 24 24 24 36 16 | 15 16 18 24 37 17 | 15 25 25 29 38 18 | 15 26 30 30 39 19 | 16 17 17 20 40 20 | 20 30 30 30 41 21 | -------------------------------------------------------------------------------- /test/c2191030w.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 13 14 3 | 1 3 18 18 19 4 | 2 4 4 5 20 5 | 2 14 14 14 21 6 | 3 6 8 14 22 7 | 3 15 15 19 23 8 | 3 7 24 24 25 9 | 4 8 8 9 26 10 | 4 20 20 20 27 11 | 6 10 13 18 28 12 | 9 19 19 23 29 13 | 9 11 25 25 30 14 | 9 12 12 15 31 15 | 14 24 24 24 32 16 | 15 16 19 24 33 17 | 15 25 25 29 34 18 | 15 21 30 30 35 19 | 16 17 17 20 36 20 | 20 30 30 30 37 21 | -------------------------------------------------------------------------------- /test/c2201103.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 14 15 3 | 1 3 23 23 24 4 | 2 4 4 5 25 5 | 2 15 15 15 26 6 | 3 6 8 13 27 7 | 3 14 14 19 28 8 | 3 7 24 24 29 9 | 4 8 8 9 30 10 | 4 20 20 20 31 11 | 6 10 13 18 32 12 | 9 19 19 24 33 13 | 9 11 25 25 34 14 | 9 12 12 15 35 15 | 15 25 25 25 36 16 | 16 17 18 23 37 17 | 16 24 24 29 38 18 | 16 26 30 30 39 19 | 17 18 18 20 40 20 | 20 30 30 30 41 21 | -------------------------------------------------------------------------------- /test/c2221028.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 13 14 3 | 2 3 18 18 19 4 | 2 4 4 5 20 5 | 3 14 14 14 21 6 | 4 6 8 13 22 7 | 4 15 15 19 23 8 | 5 7 24 24 25 9 | 5 8 8 9 26 10 | 6 20 20 20 27 11 | 7 10 13 18 28 12 | 9 19 19 23 29 13 | 9 11 25 25 30 14 | 10 12 12 14 31 15 | 14 24 24 24 32 16 | 15 16 19 24 33 17 | 15 25 25 29 34 18 | 16 21 30 30 35 19 | 16 17 17 18 36 20 | 20 30 30 30 37 21 | -------------------------------------------------------------------------------- /test/c2251030.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 6 7 2 | 1 7 7 9 10 3 | 1 3 10 10 11 4 | 2 4 4 5 12 5 | 2 10 10 10 13 6 | 3 6 7 10 14 7 | 3 11 11 13 15 8 | 3 8 16 16 17 9 | 4 9 9 11 18 10 | 4 14 14 14 19 11 | 6 12 13 16 20 12 | 7 17 17 19 21 13 | 8 13 22 22 23 14 | 8 15 15 17 24 15 | 10 20 20 20 25 16 | 12 18 19 22 26 17 | 12 23 23 25 27 18 | 13 19 26 26 28 19 | 13 21 21 23 29 20 | 14 26 26 26 30 21 | -------------------------------------------------------------------------------- /test/c2171031.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 10 11 3 | 1 3 13 13 14 4 | 2 4 4 5 15 5 | 2 11 11 11 16 6 | 3 6 8 13 17 7 | 4 14 14 15 18 8 | 4 7 19 19 20 9 | 9 10 10 11 21 10 | 9 16 16 16 22 11 | 10 12 14 19 23 12 | 10 20 20 21 24 13 | 10 13 25 25 26 14 | 14 15 15 16 27 15 | 14 22 22 22 28 16 | 15 17 20 25 29 17 | 15 26 26 27 30 18 | 15 18 28 28 31 19 | 20 21 21 22 32 20 | 20 28 28 28 33 21 | -------------------------------------------------------------------------------- /test/c2231030.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 5 6 2 | 2 6 6 8 9 3 | 3 4 10 10 11 4 | 4 5 5 6 12 5 | 5 9 9 9 13 6 | 6 7 8 10 14 7 | 7 11 11 13 15 8 | 8 10 14 14 16 9 | 9 12 12 14 17 10 | 10 14 14 14 18 11 | 11 15 16 18 19 12 | 12 19 19 21 22 13 | 13 16 23 23 24 14 | 14 17 17 19 25 15 | 15 22 22 22 26 16 | 16 20 21 23 27 17 | 17 24 24 26 28 18 | 18 21 27 27 29 19 | 19 23 23 24 30 20 | 20 27 27 27 31 21 | -------------------------------------------------------------------------------- /test/c2141107b.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 10 11 3 | 1 3 13 13 14 4 | 1 4 4 5 15 5 | 2 11 11 11 16 6 | 3 6 8 13 17 7 | 4 14 14 15 18 8 | 4 7 19 19 20 9 | 9 10 10 11 21 10 | 9 16 16 16 22 11 | 10 12 14 19 23 12 | 10 20 20 21 24 13 | 10 15 25 25 26 14 | 14 17 17 18 27 15 | 14 22 22 22 28 16 | 15 19 20 25 29 17 | 17 26 26 27 30 18 | 17 21 28 28 31 19 | 20 23 23 24 32 20 | 20 28 28 28 33 21 | -------------------------------------------------------------------------------- /test/c2141107r.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 10 11 3 | 1 3 23 23 24 4 | 1 4 4 5 25 5 | 2 11 11 11 26 6 | 3 6 8 13 27 7 | 4 14 14 15 28 8 | 4 7 24 24 29 9 | 9 10 10 11 30 10 | 9 16 16 16 31 11 | 10 12 13 18 32 12 | 10 19 19 20 33 13 | 10 24 25 25 34 14 | 14 15 15 16 35 15 | 14 21 21 21 36 16 | 15 17 18 23 37 17 | 15 25 25 26 38 18 | 17 27 28 28 39 19 | 19 20 20 21 40 20 | 19 28 28 28 41 21 | -------------------------------------------------------------------------------- /test/c2141107a.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 8 9 2 | 1 9 9 10 11 3 | 1 3 11 11 12 4 | 1 4 4 5 13 5 | 2 11 11 11 14 6 | 12 13 14 19 20 7 | 12 20 20 21 22 8 | 12 14 22 22 23 9 | 12 15 15 16 24 10 | 13 22 22 22 25 11 | 23 24 25 30 31 12 | 23 31 31 32 33 13 | 23 25 33 33 34 14 | 23 26 26 27 35 15 | 24 33 33 33 36 16 | 34 35 36 41 42 17 | 34 42 42 43 44 18 | 34 36 44 44 45 19 | 34 37 37 38 46 20 | 35 44 44 44 47 21 | -------------------------------------------------------------------------------- /test/run-ex2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST DATE: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | 1 2 1 0 13 | 6 2 2 1 14 | 2 2 1 0 15 | 6 1 1 4 16 | 4 2 0 -5 17 | EOF 18 | 19 | ./freess -exe $testprog -wins 12 -pregs 12 -robs 12 -lqs 3 -sqs 3 -llat 1 $* 20 | -------------------------------------------------------------------------------- /test/run-ex3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST DATE: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | 1 2 1 0 13 | 6 2 2 1 14 | 2 2 1 0 15 | 6 1 1 4 16 | 4 2 0 -5 17 | EOF 18 | 19 | ./freess -exe $testprog -wins 12 -robs 12 -pregs 12 -cw 1 -pw 2 -dw 2 -iw 2 -fw 2 -lqs 2 -sqs 2 -llat 1 -slat 1 -afu 1 $* 20 | -------------------------------------------------------------------------------- /test/c2100120.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 1 5 5 13 14 3 | 2 3 4 5 15 4 | 2 14 14 29 30 5 | 5 6 30 30 31 6 | 5 6 6 7 32 7 | 6 8 8 9 33 8 | 6 10 10 10 34 9 | 7 8 9 10 35 10 | 7 13 13 21 36 11 | 8 9 10 11 37 12 | 8 29 29 44 45 13 | 11 12 45 45 46 14 | 11 12 12 14 47 15 | 12 15 15 16 48 16 | 12 17 17 17 49 17 | 13 15 16 17 50 18 | 13 21 21 30 51 19 | 14 16 17 18 52 20 | 30 44 44 59 60 21 | 30 31 60 60 61 22 | 31 32 32 33 62 23 | 31 34 34 35 63 24 | 32 36 36 36 64 25 | -------------------------------------------------------------------------------- /test/c2050623.cycles: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 2 5 5 13 14 3 | 3 4 5 6 15 4 | 4 14 14 29 30 5 | 5 6 30 30 31 6 | 6 7 7 8 32 7 | 7 9 9 10 33 8 | 8 11 11 11 34 9 | 9 10 11 12 35 10 | 10 13 13 21 36 11 | 11 12 13 14 37 12 | 12 29 29 44 45 13 | 13 15 45 45 46 14 | 14 16 16 17 47 15 | 15 18 18 19 48 16 | 16 20 20 20 49 17 | 17 19 20 22 50 18 | 18 23 23 31 51 19 | 19 21 22 23 52 20 | 30 44 44 59 60 21 | 31 32 60 60 61 22 | 32 33 33 34 62 23 | 33 35 35 36 63 24 | 34 37 37 37 64 25 | -------------------------------------------------------------------------------- /RELEASE: -------------------------------------------------------------------------------- 1 | 0.1 -- May 2009 -- Initial Release 2 | 0.2 -- Nov 2015 -- Clean up for GCC 5.1 3 | 0.4 -- Oct 2018 -- Fixed P-name in SQ, effective address in LQ/SQ, removed available time (CL) on immediate, ported on Ubuntu 18.04, added possibility to load registers values as specified in the program file 4 | 0.5 -- Oct 2018 -- Fixed LQ/SQ bug: eleminted redundant option lsq_size 5 | 0.6 -- Oct 2018 -- Restyling of the interface, added explanation of stalls (on screen and on stall.log) 6 | 1.0 -- May 2025 -- Using RISC-V-like syntax 7 | -------------------------------------------------------------------------------- /printout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" = "" ]; then 4 | echo "ERROR: you must specify a test date or exercise (e.g., 070628 or ex1)" 5 | exit -1 6 | fi 7 | if [ ! -s "./test/run-$1.sh" ]; then 8 | echo "ERROR: cannot find file ./test/run-$1.sh" 9 | exit -1 10 | fi 11 | 12 | ./test/run-$1.sh -int no > out-$1.txt 13 | #enscript -o out-$1.ps -r -f Courier6 out-$1.txt 14 | a2ps -R out-$1.txt --columns 1 -o out-$1.ps -f 6 15 | ps2pdf out-$1.ps 16 | rm -f out-$1.ps 17 | echo "--> OUTPUT IN FILE: out-$1.pdf" 18 | -------------------------------------------------------------------------------- /test/run-ss05.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 4 2 2 # MUL 18 | 2 4 1 0 # SW 19 | 6 1 1 4 # ADDI 20 | 4 2 0 -5 # BNE 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -wins 8 -pregs 8 -robs 10 -llat 2 -lqs 3 -sqs 3 $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-ex1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 3 4 0 # LW 17 | 1 7 5 128 # LW 18 | 7 7 7 3 # MUL 19 | 6 1 1 -1 # ADDI 20 | 2 7 6 256 # SW 21 | 6 2 2 8 # ADDI 22 | 4 1 0 -7 # BNE 23 | EOF 24 | 25 | 26 | cmd="./freess -exe $testprog -pw 4 -wins 16 -pregs 24 -robs 99 -lqs 3 -sqs 3 -llat 2 -afu 1 $*" 27 | echo "$cmd" 28 | $cmd 29 | -------------------------------------------------------------------------------- /run-freess.js: -------------------------------------------------------------------------------- 1 | const freessModule = require('./freess.js'); 2 | 3 | const args = process.argv.slice(2); // skip "node" and script name 4 | 5 | freessModule().then((Module) => { 6 | Module.onRuntimeInitialized = () => { 7 | try { 8 | // Set up virtual FS from local directory 9 | Module.FS.mkdir('/working'); 10 | Module.FS.mount(Module.FS.filesystems.NODEFS, { root: '.' }, '/working'); 11 | Module.FS.chdir('/working'); 12 | 13 | // Call main with command-line arguments 14 | Module.callMain(args); 15 | } catch (e) { 16 | console.error("Runtime error:", e); 17 | } 18 | }; 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /superscalar.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | FILE : SUPERSCALAR.H 3 | INFO : Header of superscalar 4 | DEVELOPEMENT: GCC 2.7.0 5 | CREATED BY : RG[14-May-2009] 6 | MODIFIED BY : XX[XX-XXX-XXXX] 7 | -----------------------------------------------------------------------------*/ 8 | #ifndef _SUPERSCALAR_H 9 | #define _SUPERSCALAR_H 10 | 11 | /*------------- GLOBAL DEFINITIONS ------------------------------------------*/ 12 | int Superscalar__Constr(void); 13 | void Superscalar__Destru(void); 14 | int Superscalar__Start(int argc, char **argv); 15 | 16 | #endif /* _SUPERSCALAR_H */ 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/run-tom02a.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 1 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -iw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec no -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -rsrel no $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom02b.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 1 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -iw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -rsrel no $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom04a.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 2 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -iw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec no -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -rsrel no $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom04b.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 2 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -iw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -rsrel no $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom05a.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 2 -sqs 2 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -fw 4 -wblat 1 -cw 1 -ww 1 -dw 4 -pw 4 -iw 1 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec no -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -iter 4 -rsrel yes $*" 24 | echo "$cmd" 25 | $cmd 26 | -------------------------------------------------------------------------------- /test/run-tom05b.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 2 -sqs 2 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -fw 4 -wblat 1 -cw 1 -ww 1 -dw 4 -pw 4 -iw 1 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -iter 4 -rsrel yes $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom05r.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 2 -sqs 2 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -fw 4 -wblat 1 -cw 1 -ww 1 -dw 4 -pw 4 -iw 1 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-tom06.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 6 2 2 3 # ADDI 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 4 -mpipe yes -stck -1 -wblat 1 -cw 1 -ww 1 -fw 3 -dw 3 -pw 3 -iw 1 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 2 -brs 2 -lsrs 2 -mrs 2 -drs 2 -loadpri no -iter 4 -rsrel yes $*" 25 | echo "$cmd" 26 | $cmd 27 | -------------------------------------------------------------------------------- /test/run-c2251030.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 3 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 2 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 3 -fw 3 -pw 3 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom07.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 2 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 2 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 2 -fw 2 -pw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom082.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 4 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 3 -fw 3 -pw 3 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom08r.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 4 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 3 -fw 3 -pw 3 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom08w.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 4 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 3 -fw 3 -pw 3 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri no -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom09.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 5 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 3 -fw 3 -pw 3 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 5 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 4 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 2 -dw 2 -fw 2 -pw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri no -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /test/run-tom11.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 2 2 2 # MUL 18 | 2 2 1 400 # SW 19 | 6 1 1 4 # ADDI 20 | 3 2 0 -5 # BEQ 21 | EOF 22 | 23 | 24 | 25 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 3 -sqs 3 -llat 2 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 2 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 1 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 2 -mrs 2 -drs 2 -loadpri yes -iter 4 -rsrel yes $*" 26 | echo "$cmd" 27 | $cmd 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # Custom 55 | Debug 56 | Release 57 | freess 58 | *.ps 59 | *.pdf 60 | *.txt 61 | *.log 62 | program* 63 | out* 64 | makefile-tbi 65 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | ### TODO 2 | 3 | - model the LSU QUEUE: it is necessary to maintain the precedence between load and store! 4 | -- the coordination of the memory dataflow is still missing (see chap. 8 of Johnson91) 5 | -- the store data must be buffered and written to memory only at the time of complete ?? 6 | 7 | - model the update of the register values (partial for now) 8 | 9 | - model the exception handling with the consequent rollback 10 | 11 | - model the branch prediction 12 | (it may not be necessary because with few instructions it is difficult to train the predictor !!) 13 | 14 | - model the safe recovery 15 | 16 | - it seems that the issue is not done for n instructions but for n-1 ?? 17 | 18 | - generic stage buffers could be eliminated (they do not exist in reality) 19 | only D,P really need them at their input 20 | 21 | -------------------------------------------------------------------------------- /test/run-tom01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 4 2 5 # MUL 18 | 1 6 1 400 # LW 19 | 8 6 4 6 # DIV 20 | 2 6 1 400 # SW 21 | 6 1 1 8 # ADDI 22 | 9 3 1 800 # SGTI 23 | 3 3 0 -8 # BEQ 24 | EOF 25 | 26 | 27 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 1 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 1 -fw 1 -pw 1 -iw 4 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -swaits yes -tom yes -ars 3 -brs 2 -lsrs 2 -mrs 3 -drs 2 -loadpri no -rsrel no $*" 28 | echo "$cmd" 29 | $cmd 30 | -------------------------------------------------------------------------------- /test/run-tom03.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo $0 4 | testdate1="${0##*run-}" 5 | testdate2="${testdate1%.sh}" 6 | echo "TEST: $testdate2" 7 | 8 | testprog="program-$testdate2" 9 | 10 | cat <$testprog 11 | #! 1 12 | #x 1 10 13 | #x 4 40 14 | #x 5 50 15 | #x 6 60 16 | 1 2 1 0 # LW 17 | 7 4 2 5 # MUL 18 | 1 6 1 400 # LW 19 | 8 6 4 6 # DIV 20 | 2 6 1 400 # SW 21 | 6 1 1 8 # ADDI 22 | 9 3 1 800 # SGTI 23 | 3 3 0 -8 # BEQ 24 | EOF 25 | 26 | 27 | cmd="./freess -exe $testprog -pw 8 -wins 10 -pregs 8 -robs 20 -lqs 5 -sqs 5 -llat 1 -afu 1 -dlat 15 -dpipe no -dfu 1 -mfu 1 -mlat 8 -mpipe no -stck -1 -wblat 1 -cw 1 -ww 1 -dw 2 -fw 2 -pw 2 -ioi no -ioc no -slat 1 -wins 30 -preg 30 -spec yes -iw 10 -swaits yes -tom yes -lsrs 2 -brs 2 -ars 3 -mrs 3 -drs 2 -loadpri no -tom yes -rsrel no $*" 28 | echo "$cmd" 29 | $cmd 30 | -------------------------------------------------------------------------------- /lib/getopt1.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | FILE : GETOPT1.H 3 | INFO : Interface to getopt 4 | DEVELOPEMENT: GCC 2.6.3 && Borland C++ 3.1, Model=Large, ANSI-Keywords 5 | CREATED BY : RG[28-Apr-1995] 6 | MODIFIED BY : XX[XX-XXX-XXXX] 7 | -----------------------------------------------------------------------------*/ 8 | #ifndef _GETOPT1_H 9 | #define _GETOPT1_H 10 | 11 | /*------------- GLOBAL DEFINITIONS ------------------------------------------*/ 12 | #include "getopt.h" 13 | 14 | int getopt_long (int argc, char *const *argv, const char *options, 15 | const struct option *long_options, int *opt_index); 16 | 17 | int getopt_long_only (int argc, char *const *argv, const char *options, 18 | const struct option *long_options, int *opt_index); 19 | 20 | 21 | #endif /* _GETOPT1_H */ 22 | -------------------------------------------------------------------------------- /lib/queue.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | FILE : QUEUE.H 3 | INFO : Header of queue class implementation 4 | DEVELOPEMENT: GCC 2.6.3 && Borland C++ 3.1, Model=Large, ANSI-Keywords 5 | CREATED BY : RG[28-Apr-1995] 6 | MODIFIED BY : XX[XX-XXX-XXXX] 7 | -----------------------------------------------------------------------------*/ 8 | #ifndef _QUEUE_H 9 | #define _QUEUE_H 10 | 11 | /*------------- GLOBAL DEFINITIONS ------------------------------------------*/ 12 | #define MAX_QUEUE 10 13 | 14 | 15 | int QueuePackage__Constr(void); 16 | void QueuePackage__Destru(void); 17 | int Queue__Constr(void); 18 | void Queue__Destru(int q); 19 | int Queue__Insert(char *i, int q); 20 | int Queue__HInsert(char *i, int q); 21 | char *Queue__Extract(int q); 22 | char *Queue__ExtractBC(char *i, int q); 23 | char *Queue__Pick(int i, int q); 24 | char *Queue__Read(int i, int q); 25 | int Queue__Count(int q); 26 | 27 | #endif /* _QUEUE_H */ 28 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/make -f 2 | # 3 | # Unified Makefile for native (gcc) and wasm (emcc) builds 4 | 5 | DEFIN = -DSTDC_HEADERS=1 -DHAVE_UNISTD_H=1 -DDIRENT=1 6 | OBJS = sui.o getopt.o getopt1.o queue.o 7 | ARFLAGS = r 8 | AR = ar 9 | LIBTGT = libsui.a 10 | 11 | # Native compiler 12 | CC_NATIVE = gcc 13 | CFLAGS_NATIVE = -O3 -D_Linux_ $(DEFIN) -I../lib -I./include 14 | 15 | # WebAssembly compiler 16 | CC_WASM = emcc 17 | CFLAGS_WASM = -O3 -D_Linux_ $(DEFIN) -I../lib -I./include 18 | 19 | .PHONY: all clean wasm 20 | 21 | all: clean native 22 | 23 | native: CC=$(CC_NATIVE) 24 | native: CFLAGS=$(CFLAGS_NATIVE) 25 | native: $(LIBTGT) 26 | 27 | wasm: CC=$(CC_WASM) 28 | wasm: CFLAGS=$(CFLAGS_WASM) 29 | wasm: $(LIBTGT) 30 | 31 | $(LIBTGT): $(OBJS) 32 | $(AR) $(ARFLAGS) $(LIBTGT) $(OBJS) 33 | 34 | .SUFFIXES: 35 | .SUFFIXES: .c .o 36 | 37 | .c.o: 38 | $(CC) $(CFLAGS) -c $< 39 | 40 | sui.o: sui.c sui.h 41 | getopt.o: getopt.c getopt.h 42 | getopt1.o: getopt1.c getopt1.h 43 | queue.o: queue.c sui.h 44 | 45 | clean: 46 | -rm -f *.o *.ln $(LIBTGT) 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Roberto Giorgi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tgt=$1 4 | 5 | recompile="1" 6 | if [ "$2" = "-n" ]; then 7 | recompile="0" 8 | fi 9 | ostype=`uname -s|tr '-' '_'` 10 | os=`echo $ostype|tr '[A-Z]' '[a-z]'` 11 | gcc --version 2> /dev/null 12 | if [ "$?" = "0" ]; then compil="gcc"; else compil="cc"; fi 13 | if [ "$compil" = "gcc" ]; then optimi="-O3"; else optimi="-O2"; fi 14 | if [ "$os" = "sunos" -o "$os" = "freebsd" ]; then 15 | ranlib="ranlib \$(LIBTGT)"; define="-I/usr/include"; 16 | else 17 | ranlib=""; define=""; 18 | fi 19 | if [ "$os" = "ultrix" ]; then 20 | ranlib='ar ts $(LIBTGT)' 21 | fi 22 | 23 | echo "ostype='$ostype'" 24 | echo "compil='$compil'" 25 | echo "optimi='$optimi'" 26 | echo "define='$define'" 27 | echo "ranlib='$ranlib'" 28 | 29 | for t in $tgt lib; do 30 | if [ -d ../$t ]; then 31 | (cd ../$t 32 | echo "Configuring '$t'..." 33 | sed -e "{ 34 | s:___COMPIL___:$compil: 35 | s:___OPTIMI___:$optimi: 36 | s:___OSTYPE___:$ostype: 37 | s:___DEFINE___:$define: 38 | s:___RANLIB___:$ranlib: 39 | }" makefile.in > ./mmm.tmp 40 | 41 | 'rm' -f makefile 42 | mv ./mmm.tmp makefile 43 | ) 44 | fi 45 | done 46 | 47 | if [ "$recompile" = "1" ]; then 48 | make clean 49 | 'rm' -f $tgt 2> /dev/null 50 | make release 51 | fi 52 | -------------------------------------------------------------------------------- /extractcycles.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # extract_F_to_C.sh — F..C columns (including negatives) for 000..last 3 | # Usage: ./extract_F_to_C.sh < input.txt OR ./extract_F_to_C.sh dump.txt 4 | set -o pipefail 5 | 6 | input="/dev/stdin" 7 | if [ $# -ge 1 ]; then 8 | if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then 9 | grep '^# ' "$0" | cut -c3- 10 | exit 0 11 | fi 12 | if [ ! -r "$1" ]; then 13 | echo "ERROR: cannot read input file: $1" >&2 14 | exit 1 15 | fi 16 | input="$1" 17 | fi 18 | 19 | awk ' 20 | BEGIN { OFS = "\t"; 21 | # print "INS","F","D","P","I","X","W","C" 22 | } 23 | 24 | /^[0-9][0-9][0-9]\]/ { 25 | ins = substr($1, 1, 3) 26 | count = 0 27 | delete nums 28 | 29 | for (i = 1; i <= NF; i++) { 30 | # accept optional leading minus to keep negatives intact 31 | if ($i ~ /^-?[0-9]+$/) { 32 | count++ 33 | nums[count] = $i 34 | if (count == 7) break 35 | } 36 | } 37 | 38 | if (count == 7) { 39 | # print ins, nums[1], nums[2], nums[3], nums[4], nums[5], nums[6], nums[7] 40 | print nums[3], nums[4], nums[5], nums[6], nums[7] 41 | seen = 1 42 | } 43 | } 44 | 45 | END { 46 | if (!seen) { 47 | print "WARNING: no instruction rows found in input." > "/dev/stderr" 48 | } 49 | } 50 | ' "$input" 51 | 52 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | FILE : MAIN.H 3 | INFO : Free Superscalar Simulator 4 | DEVELOPEMENT: GCC 2.7.0 5 | CREATED BY : RG[14-Oct-2025] 6 | MODIFIED BY : XX[XX-XXX-XXXX] 7 | -----------------------------------------------------------------------------*/ 8 | /* Automatically generated by Tool Builder Interface V1.0. */ 9 | /* File: main.h (Don't edit this file.) */ 10 | 11 | #ifndef __MAIN_H 12 | #define __MAIN_H 13 | 14 | #include "sui.h" 15 | #include "getopt1.h" 16 | 17 | /*------------- GLOBAL DEFINITIONS ------------------------------------------*/ 18 | extern int verbose; 19 | extern int debug; 20 | extern int Tracing; 21 | extern int ETracing; 22 | 23 | #define MAXISSUEWIDTH 64 24 | #define MAXWINDOWSIZE 1024 25 | #define MAXROBSIZE 2048 26 | #define MAXPHYSREGS 1024 27 | #define MAXINTFU 24 28 | #define MAXFPFU 24 29 | #define MAXLFU 24 30 | #define MAXSFU 24 31 | #define MAXBFU 24 32 | #define MAXLQSIZE 256 33 | #define MAXSQSIZE 256 34 | #define MAXLATENCY 10000 35 | #define MAXITERATIONS 10000 36 | #define MAXRSPERFU 100 37 | 38 | 39 | typedef struct GeneralTAG 40 | { 41 | char progname[MAXFILENAMELEN]; 42 | int silent; 43 | int interactive; 44 | int batch; 45 | int iterations; 46 | int start_ck; 47 | int tomasulo; 48 | } General; 49 | 50 | typedef struct ArchitectureTAG 51 | { 52 | int lregs; 53 | int pregs; 54 | char pipestruct[MAXFILENAMELEN]; 55 | int uni_lsu; 56 | int load_has_pri; 57 | int io_issue; 58 | int io_complete; 59 | int uni_di; 60 | int early_rs_rel; 61 | int mem_pipe; 62 | int f_width; 63 | int d_width; 64 | int p_width; 65 | int i_width; 66 | int w_width; 67 | int c_width; 68 | int win_size; 69 | int rob_size; 70 | int int_fu; 71 | int a_lat; 72 | int a_rs; 73 | int im_fu; 74 | int im_lat; 75 | int im_pipe; 76 | int im_rs; 77 | int id_fu; 78 | int id_lat; 79 | int id_pipe; 80 | int id_rs; 81 | int fp_fu; 82 | int fm_fu; 83 | int l_fu; 84 | int l_lat; 85 | int l_pipe; 86 | int s_fu; 87 | int s_lat; 88 | int s_pipe; 89 | int s_waits; 90 | int ls_rs; 91 | int b_fu; 92 | int b_lat; 93 | int b_rs; 94 | int lqsize; 95 | int sqsize; 96 | int speculation; 97 | int wblat; 98 | } Architecture; 99 | 100 | typedef struct Program_DefaultsTAG 101 | { 102 | char logfile[MAXFILENAMELEN]; 103 | } Program_Defaults; 104 | 105 | 106 | extern General G; 107 | extern Architecture AA; 108 | extern Program_Defaults Pro; 109 | 110 | #endif /* __MAIN_H */ 111 | 112 | 113 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/make -f 2 | 3 | # Common settings 4 | TGT = freess 5 | DEFIN = -DSHARING_STAT -DDGEN -DDXP 6 | DIR = $(TGT) 7 | OBJS = $(REL)/main.o $(REL)/superscalar.o ./lib/libsui.a 8 | CFLAGS1 = -D_Linux_ $(DEFIN) -I./lib -I./include 9 | CFLAGS2 = -lm 10 | ARFLAGS = r 11 | AR = ar 12 | 13 | # Native build settings (gcc) 14 | CC_NATIVE = gcc 15 | 16 | # WebAssembly build settings (emcc) 17 | CC_WASM = emcc 18 | WASM_FLAGS1 = -O3 $(CFLAGS1) -s USE_SDL=2 19 | # -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXIT_RUNTIME=1 20 | WASM_FLAGS2 = -s MODULARIZE=1 -s EXPORT_NAME="freessModule" -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ 21 | -s EXPORTED_RUNTIME_METHODS='["FS", "callMain"]' -s EXIT_RUNTIME=0 \ 22 | --embed-file test/program-ex1 23 | 24 | # Targets 25 | 26 | .PHONY: all release debug clean veryclean install test t0 t1 t2 t3 t4 t5 t6 new wasm 27 | 28 | all: clean release 29 | 30 | release: 31 | -@mkdir -p Release Debug 32 | @echo "" 33 | @echo "------------------- Building $(TGT) Release Version" 34 | @CCOO="-O3 "; REL=Release; export REL CCOO; $(MAKE) tool CC="$(CC_NATIVE)" 35 | 36 | debug: 37 | -@mkdir -p Release Debug 38 | @echo "" 39 | @echo "------------------- Building $(TGT) Debug Version" 40 | @CCOO="-g "; CCSS=d; REL=Debug; export REL CCOO CCSS; $(MAKE) tool CC="$(CC_NATIVE)" 41 | 42 | tool: $(OBJS) 43 | @echo "" 44 | @echo "------------------- Building TOOL BINARY" 45 | $(CC) $(OBJS) $(CFLAGS1) -o $(TGT)$(CCSS) $(CFLAGS2) 46 | 47 | wasm: clean 48 | -@mkdir -p Release Debug 49 | @echo "" 50 | @echo "------------------- Building LIBRARY for WebAssembly" 51 | @cd ./lib && $(MAKE) wasm 52 | @echo "" 53 | @echo "------------------- Building $(TGT) WebAssembly Version" 54 | @REL=Release; CCSS=.js; export REL CCSS; $(MAKE) tool CC="$(CC_WASM)" \ 55 | CFLAGS1="$(WASM_FLAGS1)" CFLAGS2="$(WASM_FLAGS2)" 56 | # @echo "" 57 | # @echo "------------------- Linking to WebAssembly module for Browser" 58 | # $(CC_WASM) $(OBJS) $(WASM_FLAGS) -o $(TGT).js 59 | 60 | ./lib/libsui.a: ./lib/sui.c ./lib/sui.h 61 | @echo "" 62 | @echo "------------------- Building LIBRARY" 63 | cd ./lib && $(MAKE) || exit 1 64 | 65 | $(REL)/main.o: main.c main.h ./lib/sui.h ./lib/libsui.a 66 | $(CC) $(CFLAGS1) -o $(REL)/main.o -c main.c 67 | 68 | $(REL)/superscalar.o: superscalar.c superscalar.h 69 | $(CC) $(CFLAGS1) -o $(REL)/superscalar.o -c superscalar.c 70 | 71 | clean: 72 | @echo "" 73 | @echo "------------------- Cleaning build files" 74 | -rm -rf Release Debug *.ln $(TGT) $(TGT)d $(TGT).exe $(TGT).cpe $(TGT).def \ 75 | $(TGT).c $(TGT).h $(TGT).tem 76 | -cd ./lib && $(MAKE) clean || exit 0 77 | -mkdir -p Release Debug 78 | 79 | veryclean: clean 80 | -rm -f $(TGT) $(TGT)d $(TGT).exe $(TGT).cpe $(TGT).def \ 81 | freess.js freess.wasm freess.data 82 | 83 | install: 84 | cd .. && $(MAKE) install && cd $(TGT) 85 | 86 | test: all 87 | @echo "--------------" 88 | @./docheck.sh 89 | 90 | t0: 91 | cd test0 && ($(MAKE) && $(MAKE) cmp) 92 | t1: 93 | cd test1 && ($(MAKE) && $(MAKE) cmp) 94 | t2: 95 | cd test2 && ($(MAKE) && $(MAKE) cmp) 96 | t3: 97 | cd test3 && ($(MAKE) && $(MAKE) cmp) 98 | t4: 99 | cd test4 && ($(MAKE) && $(MAKE) cmp) 100 | t5: 101 | cd test5 && ($(MAKE) && $(MAKE) cmp) 102 | t6: 103 | cd test6 && ($(MAKE) && $(MAKE) cmp) 104 | 105 | new: 106 | rm -f $(TGT) 107 | $(MAKE) 108 | -------------------------------------------------------------------------------- /makefile.in: -------------------------------------------------------------------------------- 1 | #!/bin/make -f 2 | # Automatically generated by Tool Builder Interface V1.0. 3 | # File: makefile.in (Don't edit this file.) 4 | 5 | # 6 | # AR: archive command 7 | # AS: assembler command 8 | # ASFLAGS: options to assembler 9 | # CC: compiler command 10 | # CFLAGS: options to C compiler 11 | # DIR: root directory of FREESS 12 | # 13 | # Roberto Giorgi 14 | # [14-Oct-2025] 15 | 16 | TGT = freess 17 | DEFIN = -DSHARING_STAT -DDGEN -DDXP 18 | DIR = $(TGT) 19 | #REL = Release 20 | #DEB = Debug 21 | OBJS = $(REL)/main.o $(REL)/superscalar.o ../lib/libsui.a 22 | CFLAGS1 = $(CCOO)-D____OSTYPE____ $(DEFIN) -I../lib -I./include ___DEFINE___ 23 | CFLAGS = ___OPTIMI___ $(CFLAGS1) 24 | ARFLAGS = r 25 | AR = ar 26 | CC = ___COMPIL___ 27 | 28 | release: 29 | -@mkdir Release 2> /dev/null 30 | -@mkdir Debug 2> /dev/null 31 | @echo "" 32 | @echo "------------------- Building $(TGT) Release Version" 33 | @(CCOO="___OPTIMI___ "; REL=Release; export REL CCOO; make tool) 34 | 35 | debug: 36 | -@mkdir Release 2> /dev/null 37 | -@mkdir Debug 2> /dev/null 38 | @echo "" 39 | @echo "------------------- Building $(TGT) Debug Version" 40 | @(CCOO="-g "; CCSS=d; REL=Debug; export REL CCOO CCSS; make tool) 41 | 42 | all: 43 | make clean 44 | make release 45 | 46 | tool: $(OBJS) 47 | -@(count="0"; \ 48 | for i in Objs/*; do \ 49 | if [ -s $$i ]; then count=`expr $$count + 1`; fi; \ 50 | done;\ 51 | if [ $$count -gt 0 ]; then \ 52 | echo "";\ 53 | echo "------------------- Copying PREBUILT OBJECT FILES";\ 54 | for i in Objs/*; do \ 55 | tt=`echo $$i |awk -F/ '{print $$2}'`;\ 56 | rm -f $(REL)/$$tt.o;\ 57 | cp Objs/$$tt $(REL)/$$tt.o;\ 58 | echo "cp Objs/$$tt $(REL)/$$tt.o";\ 59 | done;\ 60 | fi) 61 | @echo "" 62 | @echo "------------------- Building TOOL BINARY" 63 | $(CC) $(OBJS) $(CFLAGS1) -o $(TGT)$(CCSS) -lm 64 | 65 | ../lib/libsui.a: ../lib/makefile ../lib/sui.c ../lib/sui.h 66 | @echo "" 67 | @echo "------------------- Building LIBRARY" 68 | cd ../lib && make || exit 1 69 | @echo "" 70 | @echo "------------------- Building TOOL MODULES" 71 | 72 | $(REL)/main.o: main.c main.h ../lib/sui.h ../lib/libsui.a 73 | $(CC) $(CFLAGS1) -o $(REL)/main.o -c main.c 74 | $(REL)/superscalar.o: superscalar.c superscalar.h 75 | $(CC) $(CFLAGS1) -o $(REL)/superscalar.o -c superscalar.c 76 | 77 | 78 | clean: 79 | @echo "" 80 | @echo "------------------- Cleaning all .o files" 81 | -'rm' -f Release/*.o *.ln 82 | -'rm' -f ../lib/*.o ../lib/*.a 83 | -'rm' -rf Debug Release 84 | -@mkdir Release 2> /dev/null 85 | -@mkdir Debug 2> /dev/null 86 | 87 | veryclean: 88 | $(MAKE) clean 89 | -'rm' -f $(TGT) $(TGT)d $(TGT).exe $(TGT)ini $(TGT).cpe $(TGT).def \ 90 | $(TGT).c $(TGT).h makefile makefile.in $(TGT).tem main.c main.h 91 | exec tbi2 92 | 93 | install: 94 | cd .. && make install && cd $(TGT) 95 | 96 | test: 97 | make 98 | @for i in test*; do\ 99 | if [ -d $$i ]; then cd $$i; make test; cd ..; fi\ 100 | done 101 | 102 | t0: 103 | cd test0 && ( make && make cmp ) 104 | t1: 105 | cd test1 && ( make && make cmp ) 106 | t2: 107 | cd test2 && ( make && make cmp ) 108 | t3: 109 | cd test3 && ( make && make cmp ) 110 | t4: 111 | cd test4 && ( make && make cmp ) 112 | t5: 113 | cd test5 && ( make && make cmp ) 114 | t6: 115 | cd test6 && ( make && make cmp ) 116 | 117 | new: 118 | rm -f $(TGT) 119 | make 120 | 121 | -------------------------------------------------------------------------------- /docheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tests="ex1 ex2 ex3 c2050623 c2060705a c2060705b c2100120 c2130204a c2130204b c2141107a c2141107b c2141107r c2171031 c2191030 c2191030w c2201103 c2221028 c2231030 c2241029 c2251030 c2181031" 4 | exe="freess" 5 | 6 | # Dependency check 7 | if [ ! -s "./$exe" ]; then 8 | echo "cannot find './$exe'" 9 | exit 2 10 | fi 11 | 12 | 13 | ####################### ARGUMENT MANAGEMENT START 14 | addargs=() # array of -a arguments (preserves spaces/quoting) 15 | test_arg="" # optional single positional TEST 16 | 17 | usage() { 18 | echo "Usage: $0 [-a ARG]... [--] [TEST]" 19 | echo " -a ARG Add an additional argument (repeatable)." 20 | echo " TEST Optional single test name; otherwise uses the default list." 21 | } 22 | 23 | # Manual, permissive parser: options can appear anywhere 24 | while [ "$#" -gt 0 ]; do 25 | case "$1" in 26 | -a) 27 | # -a requires one argument (accept anything, even if it starts with '-') 28 | if [ -z "${2-}" ]; then 29 | echo "Error: -a requires an argument." >&2 30 | usage 31 | exit 2 32 | fi 33 | addargs+=("$2") 34 | shift 2 35 | ;; 36 | --) 37 | # end of options; remaining (if any) should be positional 38 | shift 39 | break 40 | ;; 41 | -h|--help) 42 | usage 43 | exit 0 44 | ;; 45 | -*) 46 | echo "Unknown option: $1" >&2 47 | usage 48 | exit 2 49 | ;; 50 | *) 51 | # positional TEST (allow only one) 52 | if [ -n "$test_arg" ]; then 53 | echo "Error: only one TEST may be specified." >&2 54 | usage 55 | exit 2 56 | fi 57 | test_arg="$1" 58 | shift 59 | ;; 60 | esac 61 | done 62 | 63 | # Anything left after '--' (or after parsing) counts toward TEST 64 | if [ "$#" -gt 0 ]; then 65 | if [ -n "$test_arg" ] || [ "$#" -gt 1 ]; then 66 | echo "Error: only one TEST may be specified." >&2 67 | usage 68 | exit 2 69 | fi 70 | test_arg="$1" 71 | shift 72 | fi 73 | 74 | # Apply TEST override if provided 75 | if [ -n "$test_arg" ]; then 76 | tests="$test_arg" 77 | fi 78 | 79 | # Flat string like your original ALLARGS, plus safe array form 80 | ALLARGS="${addargs[*]}" 81 | 82 | # --- Example use (safe quoting) --- 83 | echo "Tests: $tests" 84 | echo "Extra args (${#addargs[@]}): ${addargs[*]}" 85 | ####################### ARGUMENT MANAGEMENT END 86 | 87 | # Create a unique temp file, cleaned up automatically. 88 | tmpfile="$(mktemp "/tmp/myprog.XXXXXX")" || { 89 | printf "mktemp failed\n" >&2 90 | exit 1 91 | } 92 | # Clean up on exit or signals 93 | trap 'rm -f "$tmpfile" "program-$t"' EXIT INT TERM 94 | out2="$tmpfile" 95 | count1="0" 96 | countt="0" 97 | ec="0" 98 | 99 | # Loop on tests 100 | for t in $tests; do 101 | src="./test/run-$t.sh" 102 | if [ ! -s "$src" ]; then 103 | echo "File '$src' not found!" 104 | ec="1"; exit $ec 105 | else 106 | printf "* Testing %12s" $t 107 | countt=`expr $countt + 1` 108 | $src -s yes $* |./extractcycles.sh > $tmpfile 109 | if [ -s "$tmpfile" ]; then 110 | out1="./test/$t.cycles" 111 | outd=`diff $out1 $out2` 112 | if [ -z "$outd" ]; then 113 | echo " --> OK" 114 | count1=`expr $count1 + 1` 115 | else 116 | echo ": (diff OLD vs NEW)" 117 | echo "======================" 118 | echo "$outd" 119 | echo "======================" 120 | fi 121 | else 122 | echo 123 | echo " ERROR" 124 | fi 125 | fi 126 | done 127 | 128 | echo "-----------------------" 129 | echo "* Passed $count1/$countt tests." 130 | if [ "$ec" != "0" ]; then 131 | if [ "$count1" = "$countt" -a "$count1" != "0" ]; then 132 | echo "Goodbye." 133 | else 134 | echo "ERRORS" 135 | fi 136 | fi 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # freess 2 | RISC-V Superscalar Educational Simulator based on Tomasulo's Algorithm 3 | 4 | # Tutorial/Paper 5 | [This paper has been published at the Workshop on Computer Architecture Education 2025 (at ISCA-2025).](https://doi.org/10.48550/arXiv.2506.07665) 6 | Please cite this work via this reference: 7 | ``` 8 | @InProceedings{Giorgi25-wcae, 9 | author = {Giorgi, Roberto}, 10 | title = {{FREESS}: An Educational Simulator of a {RISC-V}-Inspired Superscalar Processor Based on Tomasulo’s Algorithm}, 11 | booktitle = "ACM Workshop on Computer Architecture Education (WCAE-25)", 12 | address = "Tokyo, Japan", 13 | pages = "1-8", 14 | month = "jun", 15 | year = "2025" 16 | } 17 | ``` 18 | 19 | ![FREESS Processor Architecture](processor_diagram.png "Block diagram of the processor") 20 | 21 | # pre-requisites (dependencies in Ubuntu) 22 | ``` 23 | sudo apt install build-essential git vim 24 | ``` 25 | # pre-requisites (dependencies in Fedora) 26 | ``` 27 | sudo dnf install @development-tools git vim 28 | ``` 29 | # to compile 30 | ``` 31 | make 32 | ``` 33 | # to check that it works 34 | ``` 35 | make test 36 | ``` 37 | It should print something like '* TEST1 PASSED ...' 38 | 39 | # to run the examples 40 | ``` 41 | ./run-ex1.sh 42 | ./run-ex2.sh 43 | ./run-ex3.sh 44 | ``` 45 | 46 | # to write your own RISC-V-like program 47 | To write a program, students simply replace each mnemonic with its corresponding opcode, specify the register indices, and provide any required immediate values. The handling of branch instructions is particularly instructive: instead of using labels as in assembly, students must enter the immediate value representing the number of instructions to jump—positive for forward branches, negative for backward ones, effectively replacing the role of labels in `BEQ` and `BNE` instructions. For those unfamiliar with machine code, this exercise also provides a valuable opportunity to understand how binary files encode programs at the instruction level. 48 | 49 | Table 1 reports the opcodes for the seven supported instructions. 50 | 51 | **Table 1: FREESS instructions** 52 | 53 | | Mnemonic | Operation Code (opcode) | 54 | |----------|-------------------------| 55 | | LW | 1 | 56 | | SW | 2 | 57 | | BEQ | 3 | 58 | | BNE | 4 | 59 | | ADD | 5 | 60 | | ADDI | 6 | 61 | | MUL | 7 | 62 | 63 | Assuming the code: 64 | ``` 65 | loop: x3 <- mem(0+x4) # load b(i) 66 | x7 <- mem(128+x5) # load c(i) 67 | x7 <- x7 * x3 # b(i) * c(i) 68 | x1 <- x1 - 1 # decr. counter 69 | mem(256+x6)<- x7 # store a(i) 70 | x2 <- x2 + 8 # bump index 71 | P <- loop; x1!=0 # close loop 72 | ``` 73 | the resulting code is the following (i.e., filename 'program1': 74 | 75 | ``` 76 | 1 3 4 0 77 | 1 7 5 128 78 | 7 7 7 3 79 | 6 1 1 -1 80 | 2 7 6 256 81 | 6 2 2 8 82 | 4 1 0 -7 83 | ``` 84 | 85 | # running the program: 86 | ``` 87 | ./freess -exe program1 88 | ``` 89 | 90 | # for help 91 | ``` 92 | ./freess -h 93 | ``` 94 | 95 | ![Main Processor Parameters](parameters.png "Main parameters of the FREESS processor") 96 | 97 | # NEW (wasm branch) 98 | In addition here is a WebAssembly version! 99 | 100 | # Prerequistes: same as above and additionally (if you want to re-generate the WebAssembly via EMSCRIPTEN) 101 | ``` 102 | git clone https://github.com/emscripten-core/emsdk.git 103 | cd emsdk 104 | ./emsdk install latest 105 | ./emsdk activate latest 106 | 107 | ``` 108 | 109 | # to compile 110 | ``` 111 | cd freess 112 | git checkout wasm 113 | make wasm 114 | ``` 115 | 116 | # to run the examples 117 | Copy index.html freess.js freess.wasm to your web server and just access it via a web browser. 118 | or you can use it directly from here [https://robgiorgi.github.io/freess/](https://robgiorgi.github.io/freess/) 119 | 120 | # WARNING 121 | This is work in progress: if you have comments or would like to contribute, you are welcome! 122 | 123 | -------------------------------------------------------------------------------- /lib/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU General Public License as published by the 6 | Free Software Foundation; either version 2, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 17 | 18 | #ifndef _GETOPT_H 19 | #define _GETOPT_H 1 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /* For communication from `getopt' to the caller. 26 | When `getopt' finds an option that takes an argument, 27 | the argument value is returned here. 28 | Also, when `ordering' is RETURN_IN_ORDER, 29 | each non-option ARGV-element is returned here. */ 30 | 31 | extern char *optarg; 32 | 33 | /* Index in ARGV of the next element to be scanned. 34 | This is used for communication to and from the caller 35 | and for communication between successive calls to `getopt'. 36 | 37 | On entry to `getopt', zero means this is the first call; initialize. 38 | 39 | When `getopt' returns EOF, this is the index of the first of the 40 | non-option elements that the caller should itself scan. 41 | 42 | Otherwise, `optind' communicates from one call to the next 43 | how much of ARGV has been scanned so far. */ 44 | 45 | extern int optind; 46 | 47 | /* Callers store zero here to inhibit the error message `getopt' prints 48 | for unrecognized options. */ 49 | 50 | extern int opterr; 51 | 52 | /* Set to an option character which was unrecognized. */ 53 | 54 | extern int optopt; 55 | 56 | /* Describe the long-named options requested by the application. 57 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 58 | of `struct option' terminated by an element containing a name which is 59 | zero. 60 | 61 | The field `has_arg' is: 62 | no_argument (or 0) if the option does not take an argument, 63 | required_argument (or 1) if the option requires an argument, 64 | optional_argument (or 2) if the option takes an optional argument. 65 | 66 | If the field `flag' is not NULL, it points to a variable that is set 67 | to the value given in the field `val' when the option is found, but 68 | left unchanged if the option is not found. 69 | 70 | To have a long-named option do something other than set an `int' to 71 | a compiled-in constant, such as set a value from `optarg', set the 72 | option's `flag' field to zero and its `val' field to a nonzero 73 | value (the equivalent single-letter option character, if there is 74 | one). For long options that have a zero `flag' field, `getopt' 75 | returns the contents of the `val' field. */ 76 | 77 | struct option 78 | { 79 | #if defined (__STDC__) && __STDC__ 80 | const char *name; 81 | #else 82 | char *name; 83 | #endif 84 | /* has_arg can't be an enum because some compilers complain about 85 | type mismatches in all the code that assumes it is an int. */ 86 | int has_arg; 87 | int *flag; 88 | int val; 89 | }; 90 | 91 | /* Names for the values of the `has_arg' field of `struct option'. */ 92 | 93 | #define no_argument 0 94 | #define required_argument 1 95 | #define optional_argument 2 96 | 97 | #if defined (__STDC__) && __STDC__ 98 | #ifdef __GNU_LIBRARY__ 99 | /* Many other libraries have conflicting prototypes for getopt, with 100 | differences in the consts, in stdlib.h. To avoid compilation 101 | errors, only prototype getopt for the GNU C library. */ 102 | extern int getopt (int argc, char *const *argv, const char *shortopts); 103 | #else /* not __GNU_LIBRARY__ */ 104 | //extern int getopt (); 105 | extern int getopt (int argc, char *const *argv, const char *shortopts); 106 | #endif /* __GNU_LIBRARY__ */ 107 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, 108 | const struct option *longopts, int *longind); 109 | extern int getopt_long_only (int argc, char *const *argv, 110 | const char *shortopts, 111 | const struct option *longopts, int *longind); 112 | 113 | /* Internal only. Users should not call this directly. */ 114 | extern int _getopt_internal (int argc, char *const *argv, 115 | const char *shortopts, 116 | const struct option *longopts, int *longind, 117 | int long_only); 118 | #else /* not __STDC__ */ 119 | extern int getopt (); 120 | extern int getopt_long (); 121 | extern int getopt_long_only (); 122 | 123 | extern int _getopt_internal (); 124 | #endif /* __STDC__ */ 125 | 126 | #ifdef __cplusplus 127 | } 128 | #endif 129 | 130 | #endif /* _GETOPT_H */ 131 | -------------------------------------------------------------------------------- /lib/getopt1.c: -------------------------------------------------------------------------------- 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. 2 | Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 3 | Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU General Public License as published by the 7 | Free Software Foundation; either version 2, or (at your option) any 8 | later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 18 | 19 | #ifdef HAVE_CONFIG_H 20 | #include 21 | #endif 22 | 23 | #include "getopt.h" 24 | 25 | #if !defined (__STDC__) || !__STDC__ 26 | /* This is a separate conditional since some stdc systems 27 | reject `defined (const)'. */ 28 | #ifndef const 29 | #define const 30 | #endif 31 | #endif 32 | 33 | #include 34 | 35 | /* Comment out all this code if we are using the GNU C Library, and are not 36 | actually compiling the library itself. This code is part of the GNU C 37 | Library, but also included in many other GNU distributions. Compiling 38 | and linking in this code is a waste when using the GNU C library 39 | (especially if it is a shared library). Rather than having every GNU 40 | program understand `configure --with-gnu-libc' and omit the object files, 41 | it is simpler to just do this in the source for each such file. */ 42 | 43 | #if defined (_LIBC) || !defined (__GNU_LIBRARY__) 44 | 45 | 46 | /* This needs to come after some library #include 47 | to get __GNU_LIBRARY__ defined. */ 48 | #ifdef __GNU_LIBRARY__ 49 | #include 50 | #else 51 | char *getenv (char *); 52 | #endif 53 | 54 | #ifndef NULL 55 | #define NULL 0 56 | #endif 57 | 58 | //function prototypes 59 | int 60 | getopt_long ( 61 | int argc, 62 | char *const *argv, 63 | const char *options, 64 | const struct option *long_options, 65 | int *opt_index); 66 | int 67 | getopt_long_only ( 68 | int argc, 69 | char *const *argv, 70 | const char *options, 71 | const struct option *long_options, 72 | int *opt_index); 73 | 74 | int 75 | getopt_long ( 76 | int argc, 77 | char *const *argv, 78 | const char *options, 79 | const struct option *long_options, 80 | int *opt_index) 81 | { 82 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 83 | } 84 | 85 | /* Like getopt_long, but '-' as well as '--' can indicate a long option. 86 | If an option that starts with '-' (not '--') doesn't match a long option, 87 | but does match a short option, it is parsed as a short option 88 | instead. */ 89 | 90 | int 91 | getopt_long_only ( 92 | int argc, 93 | char *const *argv, 94 | const char *options, 95 | const struct option *long_options, 96 | int *opt_index) 97 | { 98 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 99 | } 100 | 101 | 102 | #endif /* _LIBC or not __GNU_LIBRARY__. */ 103 | 104 | #ifdef TEST 105 | 106 | #include 107 | 108 | int 109 | main (argc, argv) 110 | int argc; 111 | char **argv; 112 | { 113 | int c; 114 | int digit_optind = 0; 115 | 116 | while (1) 117 | { 118 | int this_option_optind = optind ? optind : 1; 119 | int option_index = 0; 120 | static struct option long_options[] = 121 | { 122 | {"add", 1, 0, 0}, 123 | {"append", 0, 0, 0}, 124 | {"delete", 1, 0, 0}, 125 | {"verbose", 0, 0, 0}, 126 | {"create", 0, 0, 0}, 127 | {"file", 1, 0, 0}, 128 | {0, 0, 0, 0} 129 | }; 130 | 131 | c = getopt_long (argc, argv, "abc:d:0123456789", 132 | long_options, &option_index); 133 | if (c == EOF) 134 | break; 135 | 136 | switch (c) 137 | { 138 | case 0: 139 | printf ("option %s", long_options[option_index].name); 140 | if (optarg) 141 | printf (" with arg %s", optarg); 142 | printf ("\n"); 143 | break; 144 | 145 | case '0': 146 | case '1': 147 | case '2': 148 | case '3': 149 | case '4': 150 | case '5': 151 | case '6': 152 | case '7': 153 | case '8': 154 | case '9': 155 | if (digit_optind != 0 && digit_optind != this_option_optind) 156 | printf ("digits occur in two different argv-elements.\n"); 157 | digit_optind = this_option_optind; 158 | printf ("option %c\n", c); 159 | break; 160 | 161 | case 'a': 162 | printf ("option a\n"); 163 | break; 164 | 165 | case 'b': 166 | printf ("option b\n"); 167 | break; 168 | 169 | case 'c': 170 | printf ("option c with value `%s'\n", optarg); 171 | break; 172 | 173 | case 'd': 174 | printf ("option d with value `%s'\n", optarg); 175 | break; 176 | 177 | case '?': 178 | break; 179 | 180 | default: 181 | printf ("?? getopt returned character code 0%o ??\n", c); 182 | } 183 | } 184 | 185 | if (optind < argc) 186 | { 187 | printf ("non-option ARGV-elements: "); 188 | while (optind < argc) 189 | printf ("%s ", argv[optind++]); 190 | printf ("\n"); 191 | } 192 | 193 | exit (0); 194 | } 195 | 196 | #endif /* TEST */ 197 | -------------------------------------------------------------------------------- /main.tbi: -------------------------------------------------------------------------------- 1 | # Tool Builder Interface V1.0 2 | 3 | ################################################################## 4 | Ini Section Name = General; G 5 | # Name Var Name Type L H Default Description Prio Opt 6 | Entry = Program Name; progname; STRING; 1; MAXFILENAMELEN; program; Name of program; 4; exe 7 | Entry = Silent; silent; YES_NO; 0; 0; no; Silent Mode; 4; s 8 | Entry = Interactive; interactive; YES_NO; 0; 0; yes; Interactive Mode; 4; int 9 | Entry = Mode; batch; YES_NO; 0; 0; no; Batch File Mode; 4; batch 10 | Entry = Iterations; iterations; NUMVAL; 1; 0; 3; Number of Iterations; 4; iter 11 | Entry = Starting Clock Cycle; start_ck; NUMVAL; -100; 100; 0; Starting Clock Cycle; 4; stck 12 | Entry = Tomasulo Mode; tomasulo; YES_NO; 0; 0; no; Tomasulo Pipeline + RS; 4; tom 13 | #------------------------------------------------- 14 | Ini Section Name = Architecture; AA 15 | # Name Var Name Type L H Default Description Prio Opt 16 | Entry = Logical Registers; lregs; NUMVAL; 1; MAXPHYSREGS; 8; Number of Logical Regs; 4; lregs 17 | Entry = Physical Registers; pregs; NUMVAL; 1; MAXPHYSREGS; 24; Number of Physical Regs; 4; pregs 18 | Entry = Pipeline Structure; pipestruct; STRING; 1; MAXFILENAMELEN; FDPIXWC; Pipeline Structure; 4; pstruct 19 | Entry = Unified LSU; uni_lsu; YES_NO; 0; 0; yes; Unified LSU; 4; unilsu 20 | Entry = Load over Store Pri; load_has_pri; YES_NO; 0; 0; yes; Load over Store Pri.; 4; loadpri 21 | Entry = In-Order Issue; io_issue; YES_NO; 0; 0; no; In-Order Issue; 4; ioi 22 | Entry = In-Order Complete; io_complete; YES_NO; 0; 0; no; In-Order Complete; 4; ioc 23 | Entry = Unified Disp./Issue; uni_di; YES_NO; 0; 0; yes; Unified Dispatch/Issue; 4; unidi 24 | Entry = Early RS Release; early_rs_rel; YES_NO; 0; 0; yes; Early RS Release; 4; rsrel 25 | Entry = Data Mem. Pipe; mem_pipe; YES_NO; 0; 0; yes; Pipelined Data Mempry; 4; mempipe 26 | # 27 | Entry = Fetch Width; f_width; NUMVAL; 1; MAXISSUEWIDTH; 4; Fetch Width; 4; fw 28 | Entry = Decode Width; d_width; NUMVAL; 1; MAXISSUEWIDTH; 4; Decode Width; 4; dw 29 | Entry = Dispatch Width; p_width; NUMVAL; 1; MAXISSUEWIDTH; 4; Dispatch Width; 4; pw 30 | Entry = Issue Width; i_width; NUMVAL; 1; MAXISSUEWIDTH; 4; Issue Width; 4; iw 31 | Entry = Write-Back Width; w_width; NUMVAL; 1; MAXISSUEWIDTH; 4; Write-Back Width; 4; ww 32 | Entry = Commit Width; c_width; NUMVAL; 1; MAXROBSIZE; 4; Commit Width; 4; cw 33 | Entry = Window Size; win_size; NUMVAL; 1; MAXWINDOWSIZE; 16; Instruction Window Size; 4; wins 34 | Entry = ROB Size; rob_size; NUMVAL; 1; MAXROBSIZE; 16; Reorder Buffer Size; 4; robs 35 | # 36 | Entry = Integer ALU Units; int_fu; NUMVAL; 1; MAXINTFU; 4; Number of Int. FU; 4; afu 37 | Entry = Integer ALU Latency; a_lat; NUMVAL; 0; MAXLATENCY; 0; Latency of INT ALU FU; 4; alat 38 | Entry = Int. ALU Res.Stat.; a_rs; NUMVAL; 1; MAXRSPERFU; 100; Reservation St. per FU; 4; ars 39 | # 40 | Entry = Integer Mult. Units; im_fu; NUMVAL; 1; MAXINTFU; 1; Number of Mult. FU; 4; mfu 41 | Entry = Integer Mul. Latency; im_lat; NUMVAL; 1; MAXLATENCY; 4; Latency of Mult. FU; 4; mlat 42 | Entry = Integer Mul. Pipe; im_pipe; YES_NO; 0; 0; yes; Pipelinization of Mult.; 4; mpipe 43 | Entry = Int. Mul. Res.Stat.; im_rs; NUMVAL; 1; MAXRSPERFU; 100; Reservation St. per FU; 4; mrs 44 | # 45 | Entry = Integer Div. Units; id_fu; NUMVAL; 1; MAXINTFU; 1; Number of Div. FU; 4; dfu 46 | Entry = Integer Div. Latency; id_lat; NUMVAL; 1; MAXLATENCY; 4; Latency of Div. FU; 4; dlat 47 | Entry = Integer Div. Pipe; id_pipe; YES_NO; 0; 0; yes; Pipelinization of Div.; 4; dpipe 48 | Entry = Int. Div. Res.Stat.; id_rs; NUMVAL; 1; MAXRSPERFU; 100; Reservation St. per FU; 4; drs 49 | # 50 | Entry = Floating Point Units; fp_fu; NUMVAL; 1; MAXFPFU; 4; Number of FP FU; 4; ffu 51 | # 52 | Entry = Floating Point Mul; fm_fu; NUMVAL; 1; MAXFPFU; 1; Number of FP Mult. FU; 4; xfu 53 | # 54 | Entry = Load Units; l_fu; NUMVAL; 1; MAXLFU; 1; Number of Load FU; 4; lfu 55 | Entry = Load Latency; l_lat; NUMVAL; 1; MAXLATENCY; 2; Latency of Load FU; 4; llat 56 | Entry = Load Pipe; l_pipe; YES_NO; 0; 0; yes; Pipelinization of Load; 4; lpipe 57 | # 58 | Entry = Store Units; s_fu; NUMVAL; 1; MAXSFU; 1; Number of Store FU; 4; sfu 59 | Entry = Store Latency; s_lat; NUMVAL; 1; MAXLATENCY; 1; Latency of Store FU; 4; slat 60 | Entry = Store Pipe; s_pipe; YES_NO; 0; 0; yes; Pipelinization of Store; 4; spipe 61 | Entry = Store Waits; s_waits; YES_NO; 0; 0; no; Store waits completion; 4; swaits 62 | Entry = Load/Store Res.Stat.; ls_rs; NUMVAL; 1; MAXRSPERFU; 100; Reservation St. per FU; 4; lsrs 63 | # 64 | Entry = Branch Units; b_fu; NUMVAL; 1; MAXBFU; 1; Number of Branch FU; 4; bfu 65 | Entry = Branch Latency; b_lat; NUMVAL; 0; MAXLATENCY; 0; Latency of Branch FU; 4; blat 66 | Entry = Branch Res.Stat.; b_rs; NUMVAL; 1; MAXRSPERFU; 100; Reservation St. per FU; 4; brs 67 | # 68 | Entry = Load Queue Size; lqsize; NUMVAL; 1; MAXLQSIZE; 1; Load Queue Size; 4; lqs 69 | Entry = Store Queue Size; sqsize; NUMVAL; 1; MAXSQSIZE; 1; Store Queue Size; 4; sqs 70 | # 71 | Entry = Speculation; speculation; YES_NO; 0; 0; yes; Enable Speculation; 4; spec 72 | Entry = Write Back Latency; wblat; NUMVAL; 1; 0; 0; Write Back Latency; 4; wblat 73 | 74 | Ini Section Name = Program Defaults; Pro 75 | Entry = Log File Name; logfile; STRING; 1; MAXFILENAMELEN; def.log; Log File; 4; logfile 76 | 77 | ################################################################## 78 | 79 | Tool Acronym = freess 80 | Tool Version = 1.1 81 | Tool Creation Date = 14-Oct-2025 82 | Tool Name = Free Superscalar Simulator 83 | Tool Purpose = Educational Tool 84 | 85 | Module1 Name = Superscalar 86 | Module1 Main Method = Start 87 | Module1 Constructor = Constr 88 | Module1 Destructor = Destru 89 | Module1 Purpose = Manage Superscalar Pipeline 90 | 91 | #Other Module Name = Degenerate 92 | 93 | #Define = MAXCPU; 64 94 | Define = MAXISSUEWIDTH; 64 95 | Define = MAXWINDOWSIZE; 1024 96 | Define = MAXROBSIZE; 2048 97 | Define = MAXPHYSREGS; 1024 98 | Define = MAXINTFU; 24 99 | Define = MAXFPFU; 24 100 | Define = MAXLFU; 24 101 | Define = MAXSFU; 24 102 | Define = MAXBFU; 24 103 | Define = MAXLQSIZE; 256 104 | Define = MAXSQSIZE; 256 105 | Define = MAXLATENCY; 10000 106 | Define = MAXITERATIONS; 10000 107 | Define = MAXRSPERFU; 100 108 | 109 | #Library = m 110 | MakeDef = SHARING_STAT 111 | MakeDef = DGEN 112 | MakeDef = DXP 113 | #MakeDef = OLDGEN 114 | #MakeDef = DEBUG1 115 | #MakeDef = DEBUG2 116 | #MakeDef = DEBUG3 117 | #MakeDef = ALEX 118 | 119 | #Command Line Variable = Time Slice; timeslice; NUMVAL; 1; LINF; 200000; ts in ms; 4; ts 120 | # 121 | Rule for Name =\ 122 | rfn=`echo "$progname"` 123 | # nnn=`echo $sproto |tr '[A-Z]' '[a-z]'| awk '{print substr($0, 0, 4)}' \\ 124 | # |awk '{printf("%%s____", $0)}' |awk '{print substr($0, 0, 4)}'`;\\ 125 | # rfn=`echo "$nnn $tracename $ncpu" | awk '{printf("%%s_%%s_%%03d", $1, $2, $3);}'` 126 | # 127 | Parameter Transformations =\ 128 | logfile=$rfn.log 129 | # if [ "$timeslice" != "" ]; then tmproc=`expr $timeslice / 1000`; fi;\\ 130 | # userdata="yes"; usercode="yes"; kerndata="yes"; kerncode="yes";\\ 131 | # if [ "$dbloc" != "_" ]; then\\ 132 | # dbloc1="_"$dbloc;\\ 133 | # fi;\\ 134 | # sftype="."$dbloc".s";\\ 135 | # wftype="."$dbloc".w";\\ 136 | # bftype="."$dbloc".b";\\ 137 | # pstname=`echo $skgdir| awk -F/ '{print $NF}'|tr '[A-Z]' '[a-z]'`;\\ 138 | # logfile=$rfn.log 139 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FREESS 6 | 47 | 48 | 49 | 50 |

51 | FREESS (WebAssembly beta version) 52 | [GitHub Repository] 53 |

54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

Program:

62 | 63 |
64 | 65 |
66 | 67 |
68 |

Simulation Parameters:

69 |
70 | -pw 71 | -wins 72 | -pregs 73 | -robs 74 |
75 |
76 | -lqs 77 | -sqs 78 | -llat 79 | -slat 80 |
81 |
82 | -cw 83 | -dw 84 | -iw 85 | -fw 86 |
87 |
88 | -ww 89 | -bfu 90 | -afu 91 | -mfu 92 |
93 |
94 | -alat 95 | -mlat 96 | -lfu 97 | -sfu 98 |
99 |
100 |
101 | 102 |

Output:

103 |

104 | 
105 |   
106 |   
200 | 
201 | 
202 | 


--------------------------------------------------------------------------------
/lib/queue.c:
--------------------------------------------------------------------------------
  1 | /*-----------------------------------------------------------------------------
  2 | FILE        : QUEUE.C
  3 | INFO        : Queuing stuff
  4 | DEVELOPEMENT: GCC 2.6.3 && Borland C++ 3.1, Model=Large, ANSI-Keywords
  5 | CREATED BY  : RG[28-Apr-1995]
  6 | MODIFIED BY : XX[XX-XXX-XXXX]
  7 | -----------------------------------------------------------------------------*/
  8 | /*------------- LIBRARY PROCEDURES ------------------------------------------*/
  9 | #include 	/* NULL */
 10 | #include "sui.h"
 11 | /* #include "queue.h" included in sui.h */
 12 | 
 13 | /*------------- GENERAL DEFINITIONS -----------------------------------------*/
 14 | typedef struct qelemTAG
 15 | {
 16 |    struct qelemTAG *next;
 17 |    struct qelemTAG *prev;
 18 |    char *info;
 19 | } qelem;
 20 | 
 21 | typedef struct QueueTAG
 22 | {
 23 |    qelem *head;
 24 |    qelem *tail;
 25 |    int items;
 26 |    int allocated;
 27 | } Queue;
 28 | 
 29 | /*------------- GLOBAL VARIABLES --------------------------------------------*/
 30 | static Queue *Q;
 31 | 
 32 | /*------------- INTERNAL FUNCTIONS PROTOTYPES -------------------------------*/
 33 | /*------------- FUNCTIONS IMPLEMENTATION ------------------------------------*/
 34 | /*---------------------------------------------------------------------------*
 35 |  NAME      :
 36 |  PURPOSE   :
 37 |  PARAMETERS:
 38 |  RETURN    :
 39 |  *---------------------------------------------------------------------------*/
 40 | int QueuePackage__Constr(void)
 41 | {
 42 |    int k;
 43 | 
 44 |    Q = Malloc(MAX_QUEUE * sizeof(Queue));
 45 |    for (k = 0; k < MAX_QUEUE; ++k) Q[k].allocated = 0;
 46 | 
 47 |    return (0);
 48 | }
 49 | 
 50 | /*---------------------------------------------------------------------------*
 51 |  NAME      :
 52 |  PURPOSE   :
 53 |  PARAMETERS:
 54 |  RETURN    :
 55 |  *---------------------------------------------------------------------------*/
 56 | void QueuePackage__Destru(void)
 57 | {
 58 |    int k;
 59 |   
 60 |    if (Q) for (k = 0; k < MAX_QUEUE; ++k) if (Q[k].allocated) Queue__Destru(k);
 61 |    Free(Q);
 62 | }
 63 | 
 64 | /*---------------------------------------------------------------------------*
 65 |  NAME      :
 66 |  PURPOSE   :
 67 |  PARAMETERS:
 68 |  RETURN    :
 69 |  *---------------------------------------------------------------------------*/
 70 | int Queue__Constr(void)
 71 | {
 72 |    int q;
 73 | 
 74 |    for (q = 0; q < MAX_QUEUE; ++q) if (Q[q].allocated == 0) break;
 75 |    if (q == MAX_QUEUE) ExitProg("Allowed only %d queues.", MAX_QUEUE);
 76 | 
 77 |    /* Initialize q-th queue */
 78 |    Q[q].head = NULL;
 79 |    Q[q].tail = NULL;
 80 |    Q[q].items = 0;
 81 |    Q[q].allocated = 1;
 82 | 
 83 |    return (q);
 84 | }
 85 | 
 86 | /*---------------------------------------------------------------------------*
 87 |  NAME      :
 88 |  PURPOSE   :
 89 |  PARAMETERS:
 90 |  RETURN    :
 91 |  *---------------------------------------------------------------------------*/
 92 | void Queue__Destru(int q)
 93 | {
 94 |    /* Sanity check */  
 95 |    if (q < 0 || q >= MAX_QUEUE) ExitProg("Queue index out of range.");
 96 | 
 97 |    if (Q[q].items > 0)
 98 |    {
 99 |       qelem *curr = Q[q].head, *temp;
100 | 
101 |       while (curr != NULL)
102 |       {
103 |          temp = curr->next;
104 |          Free(curr);
105 |          curr = temp;
106 |       }
107 |       Q[q].items = 0;
108 |       Q[q].head = NULL;
109 |       Q[q].tail = NULL;
110 |       Q[q].allocated = 0;
111 |    }
112 | }
113 | 
114 | /*---------------------------------------------------------------------------*
115 |  NAME      :
116 |  PURPOSE   : Insert in the tail
117 |  PARAMETERS:
118 |  RETURN    :
119 |  *---------------------------------------------------------------------------*/
120 | int Queue__Insert(char *i, int q)
121 | {
122 |    qelem *temp = Malloc(sizeof(qelem));
123 |  
124 |    /* Sanity check */  
125 |    if (temp == NULL) ExitProg("Not enough memory allocating queue %d.", q);
126 | 
127 |    /* Initialize queue element */
128 |    temp->info = i;
129 |    temp->next = NULL;
130 |    temp->prev = NULL;
131 | 
132 |    /* Update queue data */
133 |    ++Q[q].items;
134 |    if (Q[q].tail)
135 |    {
136 |       Q[q].tail->next = temp;
137 |       temp->prev = Q[q].tail;
138 |       Q[q].tail = temp;
139 |    }
140 |    else
141 |       Q[q].head = Q[q].tail = temp;
142 |    
143 |    return (0); 
144 | }
145 | 
146 | /*---------------------------------------------------------------------------*
147 |  NAME      :
148 |  PURPOSE   : Insert in the head
149 |  PARAMETERS:
150 |  RETURN    :
151 |  *---------------------------------------------------------------------------*/
152 | int Queue__HInsert(char *i, int q)
153 | {
154 |    qelem *temp = Malloc(sizeof(qelem));
155 |  
156 |    /* Sanity check */  
157 |    if (temp == NULL) ExitProg("Not enough memory allocating queue %d.", q);
158 | 
159 |    /* Initialize queue element */
160 |    temp->info = i;
161 |    temp->next = NULL;
162 |    temp->prev = NULL;
163 | 
164 |    /* Update queue data */
165 |    ++Q[q].items;
166 |    if (Q[q].head)
167 |    {
168 |       Q[q].head->prev = temp;
169 |       temp->next = Q[q].head;
170 |       Q[q].head = temp;
171 |    }
172 |    else
173 |       Q[q].head = Q[q].tail = temp;
174 |    
175 |    return (0); 
176 | }
177 | 
178 | /*---------------------------------------------------------------------------*
179 |  NAME      :
180 |  PURPOSE   : Extract from head
181 |  PARAMETERS:
182 |  RETURN    :
183 |  *---------------------------------------------------------------------------*/
184 | char *Queue__Extract(int q)
185 | {
186 |    char *tmp_info;
187 | 
188 |    if (Q[q].head)
189 |    {
190 |       qelem *temp = Q[q].head->next;
191 |       
192 |       if (temp) temp->prev = NULL;
193 |       if (Q[q].head == Q[q].tail) Q[q].tail = NULL;
194 |       tmp_info = Q[q].head->info;
195 |       Free(Q[q].head);
196 |       --Q[q].items;
197 |       Q[q].head = temp;
198 |    }
199 |    else
200 |    {
201 |       ExitProg("Cannot extract from empty queue %d.", q);
202 |    }
203 |   
204 |    return (tmp_info);
205 | }
206 | 
207 | /*---------------------------------------------------------------------------*
208 |  NAME      :
209 |  PURPOSE   : Extract By Content
210 |  PARAMETERS:
211 |  RETURN    :
212 |  *---------------------------------------------------------------------------*/
213 | char *Queue__ExtractBC(char *p,  int q)
214 | {
215 |    int k, found = 0;
216 |    qelem *temp;
217 |    char *tmp_info;
218 | 
219 |    /* Find element */
220 |    temp = Q[q].head;
221 |    while (! found && temp != NULL)
222 |       if (temp->info == p) found = 1; else temp = temp->next;
223 |    
224 |    /* Extract element */
225 |    if (! found) ExitProg("Element not found in queue %d.", q);
226 |    tmp_info = temp->info;
227 |    if (temp->prev) temp->prev->next = temp->next; else Q[q].head = temp->next;
228 |    if (temp->next) temp->next->prev = temp->prev; else Q[q].tail = temp->prev;
229 |    Free(temp);
230 |    --Q[q].items;
231 | 
232 |    return (tmp_info);
233 | }
234 | 
235 | /*---------------------------------------------------------------------------*
236 |  NAME      :
237 |  PURPOSE   : Extract i-th element
238 |  PARAMETERS:
239 |  RETURN    :
240 |  *---------------------------------------------------------------------------*/
241 | char *Queue__Pick(int i, int q)
242 | {
243 |    int k;
244 |    qelem *temp;
245 |    char *tmp_info;
246 | 
247 |    /* Sanity check */  
248 |    if (i >= Q[q].items)
249 |       ExitProg("Index out of range while picking from list %d.", q);
250 | 
251 |    /* Find i-th element */
252 |    temp = Q[q].head;
253 |    for (k = 1; k <= i; ++k) temp = temp->next; /* skip 0-element */
254 | 
255 |    /* Extract element */
256 |    tmp_info = temp->info;
257 |    if (temp->prev) temp->prev->next = temp->next; else Q[q].head = temp->next;
258 |    if (temp->next) temp->next->prev = temp->prev; else Q[q].tail = temp->prev;
259 |    Free(temp);
260 |    --Q[q].items;
261 | 
262 |    return (tmp_info);
263 | }
264 | 
265 | /*---------------------------------------------------------------------------*
266 |  NAME      :
267 |  PURPOSE   : Read i-th element
268 |  PARAMETERS:
269 |  RETURN    :
270 |  *---------------------------------------------------------------------------*/
271 | char *Queue__Read(int i, int q)
272 | {
273 |    int k;
274 |    qelem *temp;
275 |    char *tmp_info;
276 | 
277 |    /* Sanity check */  
278 |    if (i >= Q[q].items)
279 |       ExitProg("Index out of range while picking from list %d.", q);
280 | 
281 |    /* Find i-th element */
282 |    temp = Q[q].head;
283 |    for (k = 1; k <= i; ++k) temp = temp->next; /* skip 0-element */
284 | 
285 |    /* Read element */
286 |    tmp_info = temp->info;
287 | 
288 |    return (tmp_info);
289 | }
290 | 
291 | /*---------------------------------------------------------------------------*
292 |  NAME      :
293 |  PURPOSE   :
294 |  PARAMETERS:
295 |  RETURN    :
296 |  *---------------------------------------------------------------------------*/
297 | int Queue__Count(int q)
298 | {
299 |    return (Q[q].items);
300 | }
301 | 


--------------------------------------------------------------------------------
/lib/sui.h:
--------------------------------------------------------------------------------
  1 | /*-----------------------------------------------------------------------------
  2 | FILE        : SUI.H
  3 | INFO        : Shell User Interface
  4 | DEVELOPEMENT: GCC 2.6.3 && Borland C++ 3.1, Model=Large, ANSI-Keywords
  5 | CREATED BY  : RG[28-Apr-1995]
  6 | MODIFIED BY : XX[XX-XXX-XXXX]
  7 | -----------------------------------------------------------------------------*/
  8 | #ifndef	_SUI_H
  9 | #define	_SUI_H
 10 | 
 11 | #include 	/* FILE *,  */
 12 | #include 	/* toupper() */
 13 | #include 	/* strcpy(), strcat(),  */
 14 | #include 	/* atoi()  */
 15 | 
 16 | /*------------- GLOBAL DEFINITIONS ------------------------------------------*/
 17 | #ifdef	WIN32
 18 |    #define POPEN _popen
 19 |    #define PCLOSE _pclose
 20 | #else
 21 |    #define POPEN popen
 22 |    #define PCLOSE pclose
 23 | #endif
 24 | 
 25 | #define TRUE            1
 26 | #define FALSE           0
 27 | 
 28 | typedef int		mybool;
 29 | typedef unsigned long   ulng;
 30 | typedef unsigned int    uint;
 31 | typedef short int       shrt;
 32 | typedef	unsigned char	byte;
 33 | typedef double		real;
 34 | 
 35 | #define MAXNODENAMELEN  80
 36 | #define MAXUSERNAMELEN  32
 37 | #define MAXEXTLEN       16
 38 | 
 39 | #define MAXULNGBITS	32
 40 | 
 41 | #ifdef __BORLANDC__
 42 |    #define SLASH "\\"
 43 |    #define spanfn(a, u, dir, f, t, k, o) \
 44 |    { \
 45 |       char xxx[8]; \
 46 |       sprintf(xxx, "%d", k); \
 47 |       sprintf(a, "%s\\%s\\%c%c%s%s%s", u, dir, (f)[0], (f)[1], t, (k < 0) ? "" : xxx, o); \
 48 |    }
 49 |    #define spanfn01(a, u, dir, f, t, k, o) \
 50 |    { \
 51 |       char xxx[8]; \
 52 |       sprintf(xxx, "%03d", k); \
 53 |       sprintf(a, "%s\\%s\\%c%c%s%s%s", u, dir, (f)[0], (f)[1], t, (k < 0) ? "" : xxx, o); \
 54 |    }
 55 |    #define spanfn0(a, u, dir, f) \
 56 |       sprintf(a, "%s\\%s\\%s", u, dir, f)
 57 |    #define spanfn00(a, u, dir, f) \
 58 |       sprintf(a, "%s\\%s%s", u, dir, f)
 59 |    #define spanfn000(a, u, dir, f) \
 60 |       sprintf(a, "%s\\%s\\%s", u, dir, f)
 61 |    #define spanfn0000(a, u, dir, cdir, n, f) \
 62 |       sprintf(a, "%s\\%s\\%s.%d\\%s", u, dir, cdir, n, f)
 63 |    #define spanfn00000(a, u, dir, cdir, n, sdir, f) \
 64 |       sprintf(a, "%s\\%s\\%s.%d\\%s\\%s", u, dir, cdir, n, sdir, f)
 65 |    #define spanfn1(a, u, dir, t, pn, pi, ext) \
 66 |       sprintf(a, "%s\\%s\\%c%03d%03d%s", u, dir, (t)[0], pn, pi, ext)
 67 |    #define spanfn1(a, u, dir, t, pn, pi, ext) \
 68 |       sprintf(a, "%s\\%s\\%c%03d%03d%s", u, dir, (t)[0], pn, pi, ext)
 69 |    #define spanfn2(a, u, dir, t, pi, ext) \
 70 |       sprintf(a, "%s\\%s\\%c%03d%s", u, dir, (t)[0], pi, ext)
 71 |    #define spanfn3(a, u, dir, t, n, q, ext) \
 72 |       sprintf(a, "%s\\%s\\%c%s%s", u, dir, (t)[0], q, ext)
 73 |    #define spanfn3(a, u, dir, t, q, n, ext) \
 74 |       sprintf(a, "%s\\%s\\%c%03d%s%s", u, dir, (t)[0], q, n, ext)
 75 |    #define NULDEV " > NUL"
 76 | #else
 77 |    #define SLASH "/"
 78 |    #define spanfn(a, u, dir, f, t, k, o) \
 79 |    { \
 80 |       char xxx[8]; \
 81 |       sprintf(xxx, "%d", k); \
 82 |       sprintf(a, "%s/%s/%s%s%s%s", u, dir, f, t, (k < 0) ? "" : xxx, o); \
 83 |    }
 84 |    #define spanfn01(a, u, dir, f, t, k, o) \
 85 |    { \
 86 |       char xxx[8]; \
 87 |       sprintf(xxx, "%03d", k); \
 88 |       sprintf(a, "%s/%s/%s%s%s%s", u, dir, f, t, (k < 0) ? "" : xxx, o); \
 89 |    }
 90 |    #define spanfn0(a, u, dir, f) \
 91 |       sprintf(a, "%s/%s/%s", u, dir, f)
 92 |    #define spanfn00(a, u, dir, f) \
 93 |       sprintf(a, "%s/%s%s", u, dir, f)
 94 |    #define spanfn000(a, u, dir, f) \
 95 |       sprintf(a, "%s/%s/%s", u, dir, f)
 96 |    #define spanfn001(a, u, dir, sdir, f, ext) \
 97 |       sprintf(a, "%s/%s/%s/%s%s", u, dir, sdir, f, ext)
 98 |    #define spanfn0000(a, u, dir, cdir, n, f) \
 99 |       sprintf(a, "%s/%s/%s.%d/%s", u, dir, cdir, n, f)
100 |    #define spanfn00000(a, u, dir, cdir, n, sdir, f) \
101 |       sprintf(a, "%s/%s/%s.%d/%s/%s", u, dir, cdir, n, sdir, f)
102 |    #define spanfn000000(a, u, dir, cdir, n, sdir, f, ext) \
103 |       sprintf(a, "%s/%s/%s.%d/%s/%s%s", u, dir, cdir, n, sdir, f, ext)
104 |    #define spanfn1(a, u, dir, t, pn, pi, ext) \
105 |       sprintf(a, "%s/%s/%s_%03d%03d%s", u, dir, t, pn, pi, ext)
106 |    #define spanfn2(a, u, dir, t, pi, ext) \
107 |       sprintf(a, "%s/%s/%s_%03d%s", u, dir, t, pi, ext)
108 |    #define spanfn3(a, u, dir, t, q, ext) \
109 |       sprintf(a, "%s/%s/%s_%s%s", u, dir, t, q, ext)
110 |    #define spanfn4(a, u, dir, t, q, n, ext) \
111 |       sprintf(a, "%s/%s/%s_%s%03d%s", u, dir, t, q, n, ext)
112 |    #define NULDEV " 2> /dev/null"
113 | 
114 |    #define spanfn10(a, u, dir, t, pn, tn, pi, ext) \
115 |    {\
116 |       char x[32]; int i = 0;\
117 |       while ((t)[i] != '\0' && i < 31) { x[i] = toupper((t)[i]); ++i; }\
118 |       (x)[i] = '\0';\
119 |       sprintf(a, "%s/%s/%s/%d/%s_%03d%03d%s", u, dir, x, pn, t, tn, pi, ext);\
120 |    }
121 |    #define spanfn20(a, u, dir, t, pn, pi, ext) \
122 |    {\
123 |       char x[32]; int i = 0;\
124 |       while ((t)[i] != '\0' && i < 31) { x[i] = toupper((t)[i]); ++i; }\
125 |       (x)[i] = '\0';\
126 |       sprintf(a, "%s/%s/%s/%d/%s_%03d%s", u, dir, x, pn, t, pi, ext);\
127 |    }
128 | #endif
129 | 
130 | #define perc2s(x, tot) ((ulng)(((float)(x) / tot) * 100))
131 | #define perc2d(x, tot) \
132 |    ((ulng)(((float)(x) / tot) * 10000) - (perc2s(x, tot)) * 100)
133 | 
134 | #define myceil(a)       ((a) + ((((a) - ((long)(a))) > 0) ? 1 : 0)) 
135 | #define myceil1(a, b)   (((long)(a))/((long)(b)) + (((((long)(a)) % ((long)(b))) != 0) ? 1 : 0)) 
136 | 
137 | #define MAXLINELEN      1024 
138 | #define MAXFPNAMELEN	1024	/* MAX Full Path  NAME  LENgth */
139 | #define	MAXFILENAMELEN	1024    /* MAX FILE       NAME  LENgth */
140 | #define MAXIDNAMELEN	32	/* MAX IDentifier NAME  LENgth */
141 | #define MAXIDVALLEN	1024    /* MAX IDentifier VALue LENgth */
142 | 
143 | 
144 | #define	MAXINISECTIONS	64      /* No more than 64 IniSections !! */
145 | #define HEADER		0
146 | #define ENDING		255
147 | #define	STRING		1
148 | #define	NUMVAL		2
149 | #define	CHRVAL		3
150 | #define YES_NO		4
151 | #define	LNUMVAL		5
152 | #define	LINF		2147483647L
153 | typedef struct
154 | {
155 |    char varname[MAXIDNAMELEN];
156 |    int  vartype;
157 |    long minval;
158 |    long maxval;
159 |    void *value;
160 | } IniSection;
161 | typedef	IniSection	*IniT;
162 | 
163 | void	SUIConstr(void (*md)(void), const char *app[], char *ifn);
164 | void	SUIConstr1(void (*md)(void), const char *app[], char *ifn, int nolog);
165 | void	SUIDestru(void);
166 | 
167 | /* Send output string to                                  LOG DIS OUT FIL */
168 | int	Log(char *fmt, ...);                   /*          +              */
169 | int	Display(char *fmt, ...);               /*          +   +          */
170 | int	Out(char *fmt, ...);                   /*          +       +      */
171 | int	DisplayOut(char *fmt, ...);            /*          +   +   +      */
172 | int	FileOut(FILE *fp, char *fmt, ...);     /*          +           +  */
173 | 
174 | void	*Malloc(unsigned long size);
175 | void	*Calloc(unsigned long nmemb, unsigned long size);
176 | void	Free(void *block);
177 | void	ExitProg(char *fmt, ...);
178 | int	RegisterIniSec(IniSection *isp);
179 | void	LogIniParm(void);
180 | void	GenIniTemplate(void);
181 | 
182 | FILE	*FOpen(const char *fname, const char *mode, int	(**fc)(FILE *));
183 | 
184 | /* Parsing Primitives */
185 | int GetToken(char *str, int i, char *buf);
186 | int IsNumVal(char *buf, int *v);
187 | int IsUNumVal(char *buf, uint *v);
188 | int IsLNumVal(char *buf, ulng *v);
189 | 
190 | void Mysyspars(char *resu, char *key);
191 | void Mysysopen(char *strin);
192 | void Mysysclose(void);
193 | 
194 | extern char   flogname[MAXFPNAMELEN];
195 | 
196 | /*************************************************************/
197 | /* Common definitions for MSK and SKG */
198 | 
199 | #define PID_IDLE        32766
200 | #define PID_ENDTRACE    32767
201 | /*************************************************************/
202 | 
203 | /** QUEUE module ****************************************************/
204 | /** QUEUE.H **/
205 | #ifndef	_QUEUE_H
206 | #define	_QUEUE_H
207 | 
208 | #define MAX_QUEUE	500
209 | 
210 | int  QueuePackage__Constr(void);
211 | void QueuePackage__Destru(void);
212 | int  Queue__Constr(void);
213 | void Queue__Destru(int q);
214 | int  Queue__Insert(char *i, int q);
215 | int  Queue__HInsert(char *i, int q);
216 | char *Queue__Extract(int q);
217 | char *Queue__ExtractBC(char *i, int q);
218 | char *Queue__Pick(int i, int q);
219 | char *Queue__Read(int i, int q);
220 | int  Queue__Count(int q);
221 | 
222 | #endif  /* _QUEUE_H */
223 | 
224 | /********************************************************************/
225 | 
226 | /** VERSION module **************************************************/
227 | /** VERSION.H **/
228 | #include "version.h"
229 | /********************************************************************/
230 | 
231 | /** FGZIP module ****************************************************/
232 | /** FGZIP.H **/
233 | #ifndef	_FGZIP_H
234 | #define	_FGZIP_H
235 | #define MAXFPNAMELEN	1024	/* MAX Full Path  NAME  LENgth */
236 | 
237 | #ifdef __BORLANDC__
238 |    #define SLASH "\\"
239 |    #define NULDEV " > NUL"
240 | #else
241 |    #define SLASH "/"
242 |    #define NULDEV " 2> /dev/null"
243 | #endif
244 | 
245 | typedef struct FPnodeTAG
246 | {
247 |    FILE *fp;
248 |    int (*fc)(FILE *);
249 |    int (*gtc)(FILE *fp);
250 |    int (*ptc)(int c, FILE *fp);
251 |    int (*prf)(FILE *stream, const char *format, ...);
252 |    struct FPnodeTAG *next;
253 | } FPnode;
254 | 
255 | 
256 | FILE	*Fopen(const char *fname, const char *mode);
257 | int 	Fclose(FILE *fp);
258 | int	Fgetc(FILE *fp);
259 | int	Fputc(int c, FILE *fp);
260 | int	FPrintf(FILE *stream, const char *format, ...);
261 | 
262 | #endif  /* _FGZIP_H */
263 | /********************************************************************/
264 | 
265 | /********************************************************************/
266 | 
267 | /** PARRAY module****************************************************/
268 | /** PARRAY.H **/
269 | #ifndef	_PARRAY_H
270 | #define	_PARRAY_H
271 | 
272 | #define MAX_PARRAY	10
273 | 
274 | int  PArrayPackage__Constr(void);
275 | void PArrayPackage__Destru(void);
276 | int  PArray__Constr(int hbits, int lbits, int tbits);
277 | void PArray__Destru(int p);
278 | int  PArray__Store(ulng a, char *i, int p);
279 | int  PArray__Load(ulng a, char **i, int p);
280 | int  PArray__Count(int p);
281 | int  PArray__ForEach(int p, void (*f)(char *));
282 | 
283 | #endif  /* _PARRAY_H */
284 | /********************************************************************/
285 | 
286 | /* Uniform random number generator macros */
287 | #define NI 0xFFFFFFFFUL
288 | #define A0 69069
289 | #define C0 1
290 | 
291 | #ifdef OLDGEN
292 | extern ulng xx;
293 | #define UNIFORM1(u)     (((u = (u * A0 + C0))) / (real)NI)
294 | #define NF 4294967295.0
295 | #define Uniform1(u)     ((u = (u) * A0 + C0))
296 | #define UNIFORMN(u, n)  ((short)((Uniform1(u) / (NF + 1)) * (n)))
297 | #else
298 | /* Note: '&NI' is necessary when compiling on 64-bit processors (Alpha)*/
299 | #define UNIFORM1(u)     (((u = ((u * A0 + C0) & NI))) / (real)NI)
300 | #define UNIFORM0(u)     (((u = ((u * A0 + C0) & NI))) / ((real)NI + 1))
301 | #define UNIFORMN(u, n)  ((short)(UNIFORM0(u) * (n)))
302 | #endif
303 | 
304 | #endif  /* _SUI_H */
305 | 


--------------------------------------------------------------------------------
/freessini:
--------------------------------------------------------------------------------
  1 | #!/bin/sh
  2 | # Automatically generated by Tool Builder Interface V1.0. 
  3 | # File: freessini   (Don't edit this file.) 
  4 | 
  5 | # 14-Oct-2025
  6 | #
  7 | ############### OPTIONAL PARAMETERES 
  8 | # -exe		= Name of program
  9 | # -s		= Silent Mode
 10 | # -int		= Interactive Mode
 11 | # -batch	= Batch File Mode
 12 | # -iter		= Number of Iterations
 13 | # -stck		= Starting Clock Cycle
 14 | # -tom		= Tomasulo Pipeline + RS
 15 | # -lregs	= Number of Logical Regs
 16 | # -pregs	= Number of Physical Regs
 17 | # -pstruct	= Pipeline Structure
 18 | # -unilsu	= Unified LSU
 19 | # -loadpri	= Load over Store Pri.
 20 | # -ioi		= In-Order Issue
 21 | # -ioc		= In-Order Complete
 22 | # -unidi	= Unified Dispatch/Issue
 23 | # -rsrel	= Early RS Release
 24 | # -mempipe	= Pipelined Data Mempry
 25 | # -fw		= Fetch Width
 26 | # -dw		= Decode Width
 27 | # -pw		= Dispatch Width
 28 | # -iw		= Issue Width
 29 | # -ww		= Write-Back Width
 30 | # -cw		= Commit Width
 31 | # -wins		= Instruction Window Size
 32 | # -robs		= Reorder Buffer Size
 33 | # -afu			= Number of Int. FU
 34 | # -alat		= Latency of INT ALU FU
 35 | # -ars		= Reservation St. per FU
 36 | # -mfu			= Number of Mult. FU
 37 | # -mlat		= Latency of Mult. FU
 38 | # -mpipe	= Pipelinization of Mult.
 39 | # -mrs		= Reservation St. per FU
 40 | # -dfu			= Number of Div. FU
 41 | # -dlat		= Latency of Div. FU
 42 | # -dpipe	= Pipelinization of Div.
 43 | # -drs		= Reservation St. per FU
 44 | # -ffu			= Number of FP FU
 45 | # -xfu			= Number of FP Mult. FU
 46 | # -lfu			= Number of Load FU
 47 | # -llat		= Latency of Load FU
 48 | # -lpipe	= Pipelinization of Load
 49 | # -sfu			= Number of Store FU
 50 | # -slat		= Latency of Store FU
 51 | # -spipe	= Pipelinization of Store
 52 | # -swaits	= Store waits completion
 53 | # -lsrs		= Reservation St. per FU
 54 | # -bfu			= Number of Branch FU
 55 | # -blat		= Latency of Branch FU
 56 | # -brs		= Reservation St. per FU
 57 | # -lqs			= Load Queue Size
 58 | # -sqs			= Store Queue Size
 59 | # -spec		= Enable Speculation
 60 | # -wblat		= Write Back Latency
 61 | # -logfile	= Log File
 62 | #
 63 | 
 64 | #
 65 | 
 66 | # scr1=tool_name=name of this script without 3 trailing characters
 67 |   scr1=`echo $0 | awk -F/ '{l = length($NF); printf("%s", substr($NF, 1, l - 3))}'`
 68 | 
 69 | 
 70 | # scr=script name
 71 |   scr=`basename $0`
 72 | # bas=base directory
 73 |   bas1=`sh -c "type $0|cut -d\  -f 3"`
 74 |   bas=`echo $bas1 | awk -F'/' \
 75 |      '{printf("%s", $1); for (i = 2; i < NF; ++i) printf("/%s", $i); }'`
 76 | # isl=is a link?
 77 |   isl=`ls -F $0 | awk '/@/{print 1}'`
 78 | # tnm=true name
 79 |   if [ "$isl" = "1" ]; then
 80 |      tnm=`ls -l $0 |awk -F'>' '{print $2}' | awk '{print $1}'`
 81 |      chr=`echo $tnm | awk '{printf("%s", substr($1, 1, 1))}'`
 82 |      if [ ! "$chr" = "/" ]; then Tnm=$bas/$tnm; else Tnm=$tnm; fi
 83 |   else
 84 |      tnm=$0; Tnm=$0
 85 |   fi
 86 | # chr=first character
 87 |   chr=`echo $Tnm | awk '{printf("%s", substr($1, 1, 1))}'`
 88 | # cur=current directory holding this script
 89 |   if [ "$chr" = "/" ]; then
 90 |      cur=`echo $Tnm | awk -F/ \
 91 |         '{for (i = 1; i < NF - 1; ++i) printf("/%s", $(i + 1)); }'`
 92 |   else
 93 |      cur=$bas
 94 |   fi
 95 | 
 96 | ##########################################################################
 97 | #### TEMPLATE
 98 | #### tem=template path name
 99 | ###  ttt=freess
100 | ###  ccc="."
101 | ###  tem=$ccc/$ttt.tem                        # Precedence to dir '.'
102 | ###  if [ ! -f $tem ]; then                # If template not present here
103 | ###     ccc=$cur
104 | ###     tem=$ccc/$ttt.tem                  #   check for default template
105 | ###     if [ ! -f $tem ]; then
106 | ###        echo "Cannot find template file '$tem' nor './$ttt.tem'"
107 | ###        exit
108 | ###     fi
109 | ###  fi
110 | ###  echo "Template file is '$tem'" 
111 | ##########################################################################
112 | 
113 | 
114 | # Defaults
115 | progname=program
116 | silent=no
117 | interactive=yes
118 | batch=no
119 | iterations=3
120 | start_ck=0
121 | tomasulo=no
122 | lregs=8
123 | pregs=24
124 | pipestruct=FDPIXWC
125 | uni_lsu=yes
126 | load_has_pri=yes
127 | io_issue=no
128 | io_complete=no
129 | uni_di=yes
130 | early_rs_rel=yes
131 | mem_pipe=yes
132 | f_width=4
133 | d_width=4
134 | p_width=4
135 | i_width=4
136 | w_width=4
137 | c_width=4
138 | win_size=16
139 | rob_size=16
140 | int_fu=4
141 | a_lat=0
142 | a_rs=100
143 | im_fu=1
144 | im_lat=4
145 | im_pipe=yes
146 | im_rs=100
147 | id_fu=1
148 | id_lat=4
149 | id_pipe=yes
150 | id_rs=100
151 | fp_fu=4
152 | fm_fu=1
153 | l_fu=1
154 | l_lat=2
155 | l_pipe=yes
156 | s_fu=1
157 | s_lat=1
158 | s_pipe=yes
159 | s_waits=no
160 | ls_rs=100
161 | b_fu=1
162 | b_lat=0
163 | b_rs=100
164 | lqsize=1
165 | sqsize=1
166 | speculation=yes
167 | wblat=0
168 | logfile=def.log
169 | 
170 | 
171 | # Command line parsing
172 | c="0"
173 | version="0"
174 | auto="0"
175 | help="0"
176 | while [ $# -gt 0 ]; do
177 |    firstc=`echo "$1" | awk '{ printf("%s", substr($1, 1, 1)) }'`
178 |    if [ "'$1'" = "'-v'" ]; then
179 |       version="1"; shift
180 |    elif [ "'$1'" = "'-d'" ]; then
181 |       debug="1"; shift
182 |    elif [ "'$1'" = "'-auto'" ]; then
183 |       auto="1"; shift
184 |    elif [ "'$1'" = "'-help'" ]; then
185 |       help="1"; shift
186 |    elif [ "'$1'" = "'-template'" ]; then
187 |       template="1"; shift
188 |    elif [ "'$1'" = "'-exe'" ]; then
189 |       shift
190 |       progname=$1
191 |       shift
192 |    elif [ "'$1'" = "'-s'" ]; then
193 |       shift
194 |       silent=$1
195 |       shift
196 |    elif [ "'$1'" = "'-int'" ]; then
197 |       shift
198 |       interactive=$1
199 |       shift
200 |    elif [ "'$1'" = "'-batch'" ]; then
201 |       shift
202 |       batch=$1
203 |       shift
204 |    elif [ "'$1'" = "'-iter'" ]; then
205 |       shift
206 |       iterations=$1
207 |       shift
208 |    elif [ "'$1'" = "'-stck'" ]; then
209 |       shift
210 |       start_ck=$1
211 |       shift
212 |    elif [ "'$1'" = "'-tom'" ]; then
213 |       shift
214 |       tomasulo=$1
215 |       shift
216 |    elif [ "'$1'" = "'-lregs'" ]; then
217 |       shift
218 |       lregs=$1
219 |       shift
220 |    elif [ "'$1'" = "'-pregs'" ]; then
221 |       shift
222 |       pregs=$1
223 |       shift
224 |    elif [ "'$1'" = "'-pstruct'" ]; then
225 |       shift
226 |       pipestruct=$1
227 |       shift
228 |    elif [ "'$1'" = "'-unilsu'" ]; then
229 |       shift
230 |       uni_lsu=$1
231 |       shift
232 |    elif [ "'$1'" = "'-loadpri'" ]; then
233 |       shift
234 |       load_has_pri=$1
235 |       shift
236 |    elif [ "'$1'" = "'-ioi'" ]; then
237 |       shift
238 |       io_issue=$1
239 |       shift
240 |    elif [ "'$1'" = "'-ioc'" ]; then
241 |       shift
242 |       io_complete=$1
243 |       shift
244 |    elif [ "'$1'" = "'-unidi'" ]; then
245 |       shift
246 |       uni_di=$1
247 |       shift
248 |    elif [ "'$1'" = "'-rsrel'" ]; then
249 |       shift
250 |       early_rs_rel=$1
251 |       shift
252 |    elif [ "'$1'" = "'-mempipe'" ]; then
253 |       shift
254 |       mem_pipe=$1
255 |       shift
256 |    elif [ "'$1'" = "'-fw'" ]; then
257 |       shift
258 |       f_width=$1
259 |       shift
260 |    elif [ "'$1'" = "'-dw'" ]; then
261 |       shift
262 |       d_width=$1
263 |       shift
264 |    elif [ "'$1'" = "'-pw'" ]; then
265 |       shift
266 |       p_width=$1
267 |       shift
268 |    elif [ "'$1'" = "'-iw'" ]; then
269 |       shift
270 |       i_width=$1
271 |       shift
272 |    elif [ "'$1'" = "'-ww'" ]; then
273 |       shift
274 |       w_width=$1
275 |       shift
276 |    elif [ "'$1'" = "'-cw'" ]; then
277 |       shift
278 |       c_width=$1
279 |       shift
280 |    elif [ "'$1'" = "'-wins	'" ]; then
281 |       shift
282 |       win_size=$1
283 |       shift
284 |    elif [ "'$1'" = "'-robs	'" ]; then
285 |       shift
286 |       rob_size=$1
287 |       shift
288 |    elif [ "'$1'" = "'-afu	'" ]; then
289 |       shift
290 |       int_fu=$1
291 |       shift
292 |    elif [ "'$1'" = "'-alat'" ]; then
293 |       shift
294 |       a_lat=$1
295 |       shift
296 |    elif [ "'$1'" = "'-ars'" ]; then
297 |       shift
298 |       a_rs=$1
299 |       shift
300 |    elif [ "'$1'" = "'-mfu	'" ]; then
301 |       shift
302 |       im_fu=$1
303 |       shift
304 |    elif [ "'$1'" = "'-mlat'" ]; then
305 |       shift
306 |       im_lat=$1
307 |       shift
308 |    elif [ "'$1'" = "'-mpipe'" ]; then
309 |       shift
310 |       im_pipe=$1
311 |       shift
312 |    elif [ "'$1'" = "'-mrs'" ]; then
313 |       shift
314 |       im_rs=$1
315 |       shift
316 |    elif [ "'$1'" = "'-dfu	'" ]; then
317 |       shift
318 |       id_fu=$1
319 |       shift
320 |    elif [ "'$1'" = "'-dlat'" ]; then
321 |       shift
322 |       id_lat=$1
323 |       shift
324 |    elif [ "'$1'" = "'-dpipe'" ]; then
325 |       shift
326 |       id_pipe=$1
327 |       shift
328 |    elif [ "'$1'" = "'-drs'" ]; then
329 |       shift
330 |       id_rs=$1
331 |       shift
332 |    elif [ "'$1'" = "'-ffu	'" ]; then
333 |       shift
334 |       fp_fu=$1
335 |       shift
336 |    elif [ "'$1'" = "'-xfu	'" ]; then
337 |       shift
338 |       fm_fu=$1
339 |       shift
340 |    elif [ "'$1'" = "'-lfu	'" ]; then
341 |       shift
342 |       l_fu=$1
343 |       shift
344 |    elif [ "'$1'" = "'-llat'" ]; then
345 |       shift
346 |       l_lat=$1
347 |       shift
348 |    elif [ "'$1'" = "'-lpipe'" ]; then
349 |       shift
350 |       l_pipe=$1
351 |       shift
352 |    elif [ "'$1'" = "'-sfu	'" ]; then
353 |       shift
354 |       s_fu=$1
355 |       shift
356 |    elif [ "'$1'" = "'-slat'" ]; then
357 |       shift
358 |       s_lat=$1
359 |       shift
360 |    elif [ "'$1'" = "'-spipe'" ]; then
361 |       shift
362 |       s_pipe=$1
363 |       shift
364 |    elif [ "'$1'" = "'-swaits'" ]; then
365 |       shift
366 |       s_waits=$1
367 |       shift
368 |    elif [ "'$1'" = "'-lsrs'" ]; then
369 |       shift
370 |       ls_rs=$1
371 |       shift
372 |    elif [ "'$1'" = "'-bfu	'" ]; then
373 |       shift
374 |       b_fu=$1
375 |       shift
376 |    elif [ "'$1'" = "'-blat'" ]; then
377 |       shift
378 |       b_lat=$1
379 |       shift
380 |    elif [ "'$1'" = "'-brs'" ]; then
381 |       shift
382 |       b_rs=$1
383 |       shift
384 |    elif [ "'$1'" = "'-lqs	'" ]; then
385 |       shift
386 |       lqsize=$1
387 |       shift
388 |    elif [ "'$1'" = "'-sqs	'" ]; then
389 |       shift
390 |       sqsize=$1
391 |       shift
392 |    elif [ "'$1'" = "'-spec'" ]; then
393 |       shift
394 |       speculation=$1
395 |       shift
396 |    elif [ "'$1'" = "'-wblat	'" ]; then
397 |       shift
398 |       wblat=$1
399 |       shift
400 |    elif [ "'$1'" = "'-logfile'" ]; then
401 |       shift
402 |       logfile=$1
403 |       shift
404 | 
405 |    else
406 |       if [ 1 = 2 ]; then echo "";
407 | 
408 |       elif [ "$firstc" = "-" ]; then shift; c=`expr $c - 1`
409 |       fi
410 |       shift
411 |       c=`expr $c + 1`
412 |    fi
413 | done
414 | 
415 | # Print version information
416 | if [ "$version" = "1" ]; then
417 |    echo "Version $vers"
418 |    exit 0
419 | fi
420 | 
421 | # Template File String
422 | uuu="\
423 | ;Free Superscalar Simulator initialization file
424 | 
425 | [General]							
426 |  Program Name		= __REFO1__		;  Name of program
427 |  Silent			= __REFO2__		;  Silent Mode
428 |  Interactive		= __REFO3__		;  Interactive Mode
429 |  Mode			= __REFO4__		;  Batch File Mode
430 |  Iterations		= __REFO5__		;  Number of Iterations
431 |  Starting Clock Cycle	= __REFO6__		;  Starting Clock Cycle
432 |  Tomasulo Mode		= __REFO7__		;  Tomasulo Pipeline + RS
433 | 
434 | [Architecture]							
435 |  Logical Registers	= __REFO8__		;  Number of Logical Regs
436 |  Physical Registers	= __REFO9__		;  Number of Physical Regs
437 |  Pipeline Structure	= __REFO10__		;  Pipeline Structure
438 |  Unified LSU		= __REFO11__		;  Unified LSU
439 |  Load over Store Pri	= __REFO12__		;  Load over Store Pri.
440 |  In-Order Issue		= __REFO13__		;  In-Order Issue
441 |  In-Order Complete	= __REFO14__		;  In-Order Complete
442 |  Unified Disp./Issue	= __REFO15__		;  Unified Dispatch/Issue
443 |  Early RS Release	= __REFO16__		;  Early RS Release
444 |  Data Mem. Pipe		= __REFO17__		;  Pipelined Data Mempry
445 |  Fetch Width		= __REFO18__		;  Fetch Width
446 |  Decode Width		= __REFO19__		;  Decode Width
447 |  Dispatch Width		= __REFO20__		;  Dispatch Width
448 |  Issue Width		= __REFO21__		;  Issue Width
449 |  Write-Back Width	= __REFO22__		;  Write-Back Width
450 |  Commit Width		= __REFO23__		;  Commit Width
451 |  Window Size		= __REFO24__		;  Instruction Window Size
452 |  ROB Size		= __REFO25__		;  Reorder Buffer Size
453 |  Integer ALU Units	= __REFO26__		;  Number of Int. FU
454 |  Integer ALU Latency	= __REFO27__		;  Latency of INT ALU FU
455 |  Int. ALU Res.Stat.	= __REFO28__		;  Reservation St. per FU
456 |  Integer Mult. Units	= __REFO29__		;  Number of Mult. FU
457 |  Integer Mul. Latency	= __REFO30__		;  Latency of Mult. FU
458 |  Integer Mul. Pipe	= __REFO31__		;  Pipelinization of Mult.
459 |  Int. Mul. Res.Stat.	= __REFO32__		;  Reservation St. per FU
460 |  Integer Div. Units	= __REFO33__		;  Number of Div. FU
461 |  Integer Div. Latency	= __REFO34__		;  Latency of Div. FU
462 |  Integer Div. Pipe	= __REFO35__		;  Pipelinization of Div.
463 |  Int. Div. Res.Stat.	= __REFO36__		;  Reservation St. per FU
464 |  Floating Point Units	= __REFO37__		;  Number of FP FU
465 |  Floating Point Mul	= __REFO38__		;  Number of FP Mult. FU
466 |  Load Units		= __REFO39__		;  Number of Load FU
467 |  Load Latency		= __REFO40__		;  Latency of Load FU
468 |  Load Pipe		= __REFO41__		;  Pipelinization of Load
469 |  Store Units		= __REFO42__		;  Number of Store FU
470 |  Store Latency		= __REFO43__		;  Latency of Store FU
471 |  Store Pipe		= __REFO44__		;  Pipelinization of Store
472 |  Store Waits		= __REFO45__		;  Store waits completion
473 |  Load/Store Res.Stat.	= __REFO46__		;  Reservation St. per FU
474 |  Branch Units		= __REFO47__		;  Number of Branch FU
475 |  Branch Latency		= __REFO48__		;  Latency of Branch FU
476 |  Branch Res.Stat.	= __REFO49__		;  Reservation St. per FU
477 |  Load Queue Size	= __REFO50__		;  Load Queue Size
478 |  Store Queue Size	= __REFO51__		;  Store Queue Size
479 |  Speculation		= __REFO52__		;  Enable Speculation
480 |  Write Back Latency	= __REFO53__		;  Write Back Latency
481 | 
482 | [Program Defaults]						
483 |  Log File Name		= __REFO54__		;  Log File
484 | 
485 | 
486 | "
487 | 
488 | # Generate a template
489 | if [ "$template" = "1" ]; then
490 |    echo "$uuu" > $cur/$scr1.tem
491 |    echo "Template is in file '$cur/$scr1.tem'"
492 |    exit
493 | fi
494 | 
495 | if [ "$help" = "1" -o "$c" != "0" ]; then
496 |    echo "Usage:"
497 |    echo "   $scr [-exe ] [-s ] [-int ] [-batch ] [-iter ] [-stck ] [-tom ] [-lregs ] [-pregs ] [-pstruct ] [-unilsu ] [-loadpri ] [-ioi ] [-ioc ] [-unidi ] [-rsrel ] [-mempipe ] [-fw ] [-dw ] [-pw ] [-iw ] [-ww ] [-cw ] [-wins	 ] [-robs	 ] [-afu	 ] [-alat ] [-ars ] [-mfu	 ] [-mlat ] [-mpipe ] [-mrs ] [-dfu	 ] [-dlat ] [-dpipe ] [-drs ] [-ffu	 ] [-xfu	 ] [-lfu	 ] [-llat ] [-lpipe ] [-sfu	 ] [-slat ] [-spipe ] [-swaits ] [-lsrs ] [-bfu	 ] [-blat ] [-brs ] [-lqs	 ] [-sqs	 ] [-spec ] [-wblat	 ] [-logfile ] "
498 |    echo ""
499 |    echo "   PARAMETER NAME                       DESCRIPTION             DEFAULT VALUE"
500 |    echo "   			Name of program		program"
501 |    echo "   				Silent Mode		no"
502 |    echo "   			Interactive Mode	yes"
503 |    echo "   				Batch File Mode		no"
504 |    echo "   				Number of Iterations	3"
505 |    echo "   		Starting Clock Cycle	0"
506 |    echo "   			Tomasulo Pipeline + RS	no"
507 |    echo "   			Number of Logical Regs	8"
508 |    echo "   			Number of Physical Regs	24"
509 |    echo "   			Pipeline Structure	FDPIXWC"
510 |    echo "   			Unified LSU		yes"
511 |    echo "   		Load over Store Pri.	yes"
512 |    echo "   			In-Order Issue		no"
513 |    echo "   			In-Order Complete	no"
514 |    echo "   		Unified Dispatch/Issue	yes"
515 |    echo "   			Early RS Release	yes"
516 |    echo "   			Pipelined Data Mempry	yes"
517 |    echo "   			Fetch Width		4"
518 |    echo "   			Decode Width		4"
519 |    echo "   			Dispatch Width		4"
520 |    echo "   			Issue Width		4"
521 |    echo "   			Write-Back Width	4"
522 |    echo "   			Commit Width		4"
523 |    echo "   			Instruction Window Size	16"
524 |    echo "   				Reorder Buffer Size	16"
525 |    echo "   			Number of Int. FU	4"
526 |    echo "   		Latency of INT ALU FU	0"
527 |    echo "   			Reservation St. per FU	100"
528 |    echo "   		Number of Mult. FU	1"
529 |    echo "   		Latency of Mult. FU	4"
530 |    echo "   			Pipelinization of Mult.	yes"
531 |    echo "   		Reservation St. per FU	100"
532 |    echo "   			Number of Div. FU	1"
533 |    echo "   		Latency of Div. FU	4"
534 |    echo "   			Pipelinization of Div.	yes"
535 |    echo "   		Reservation St. per FU	100"
536 |    echo "   		Number of FP FU		4"
537 |    echo "   			Number of FP Mult. FU	1"
538 |    echo "   				Number of Load FU	1"
539 |    echo "   			Latency of Load FU	2"
540 |    echo "   				Pipelinization of Load	yes"
541 |    echo "   			Number of Store FU	1"
542 |    echo "   			Latency of Store FU	1"
543 |    echo "   				Pipelinization of Store	yes"
544 |    echo "   			Store waits completion	no"
545 |    echo "   		Reservation St. per FU	100"
546 |    echo "   			Number of Branch FU	1"
547 |    echo "   			Latency of Branch FU	0"
548 |    echo "   			Reservation St. per FU	100"
549 |    echo "   			Load Queue Size		1"
550 |    echo "   			Store Queue Size	1"
551 |    echo "   			Enable Speculation	yes"
552 |    echo "   			Write Back Latency	0"
553 |    echo "   			Log File		def.log"
554 | 
555 |    echo ""
556 |    exit
557 | fi
558 | 
559 | #__PARAMETERS_SYMBOL_ASSO__
560 | 
561 | # Rule for name: MUST USE 'rfn' FOR HOLDING RESULT
562 |   rfn=`echo "$progname"`
563 | 
564 | # Input parameters transformations
565 |   logfile=$rfn.log
566 | 
567 | # Create Actual .ini File
568 | echo "$uuu" |sed -e "{
569 | s:__REFO1__:$progname:
570 | s:__REFO2__:$silent:
571 | s:__REFO3__:$interactive:
572 | s:__REFO4__:$batch:
573 | s:__REFO5__:$iterations:
574 | s:__REFO6__:$start_ck:
575 | s:__REFO7__:$tomasulo:
576 | s:__REFO8__:$lregs:
577 | s:__REFO9__:$pregs:
578 | s:__REFO10__:$pipestruct:
579 | s:__REFO11__:$uni_lsu:
580 | s:__REFO12__:$load_has_pri:
581 | s:__REFO13__:$io_issue:
582 | s:__REFO14__:$io_complete:
583 | s:__REFO15__:$uni_di:
584 | s:__REFO16__:$early_rs_rel:
585 | s:__REFO17__:$mem_pipe:
586 | s:__REFO18__:$f_width:
587 | s:__REFO19__:$d_width:
588 | s:__REFO20__:$p_width:
589 | s:__REFO21__:$i_width:
590 | s:__REFO22__:$w_width:
591 | s:__REFO23__:$c_width:
592 | s:__REFO24__:$win_size:
593 | s:__REFO25__:$rob_size:
594 | s:__REFO26__:$int_fu:
595 | s:__REFO27__:$a_lat:
596 | s:__REFO28__:$a_rs:
597 | s:__REFO29__:$im_fu:
598 | s:__REFO30__:$im_lat:
599 | s:__REFO31__:$im_pipe:
600 | s:__REFO32__:$im_rs:
601 | s:__REFO33__:$id_fu:
602 | s:__REFO34__:$id_lat:
603 | s:__REFO35__:$id_pipe:
604 | s:__REFO36__:$id_rs:
605 | s:__REFO37__:$fp_fu:
606 | s:__REFO38__:$fm_fu:
607 | s:__REFO39__:$l_fu:
608 | s:__REFO40__:$l_lat:
609 | s:__REFO41__:$l_pipe:
610 | s:__REFO42__:$s_fu:
611 | s:__REFO43__:$s_lat:
612 | s:__REFO44__:$s_pipe:
613 | s:__REFO45__:$s_waits:
614 | s:__REFO46__:$ls_rs:
615 | s:__REFO47__:$b_fu:
616 | s:__REFO48__:$b_lat:
617 | s:__REFO49__:$b_rs:
618 | s:__REFO50__:$lqsize:
619 | s:__REFO51__:$sqsize:
620 | s:__REFO52__:$speculation:
621 | s:__REFO53__:$wblat:
622 | s:__REFO54__:$logfile:
623 | }" > ./$rfn.ini
624 | 
625 | 
626 | opt_d=""
627 | if [ "$debug" = "1" ]; then
628 |    opt_d="-d"
629 | fi
630 | if [ "$auto" = "1" ]; then
631 | ###   exec $ccc/freess -i $rfn.ini
632 |    exec $cur/$scr1 $opt_d -i $rfn.ini
633 | else
634 | ###   echo "You can now issue '$ccc/freess -i $rfn.ini'."
635 |    echo "You can now issue '$cur/$scr1 -i $rfn.ini'."
636 | fi
637 | 
638 | 
639 | 


--------------------------------------------------------------------------------
/lib/getopt.c:
--------------------------------------------------------------------------------
  1 | /* Getopt for GNU.
  2 |    NOTE: getopt is now part of the C library, so if you don't know what
  3 |    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
  4 |    before changing it!
  5 | 
  6 |    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
  7 |    	Free Software Foundation, Inc.
  8 | 
  9 |    This program is free software; you can redistribute it and/or modify it
 10 |    under the terms of the GNU General Public License as published by the
 11 |    Free Software Foundation; either version 2, or (at your option) any
 12 |    later version.
 13 | 
 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.
 18 | 
 19 |    You should have received a copy of the GNU General Public License
 20 |    along with this program; if not, write to the Free Software
 21 |    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 22 | 
 23 | #include 
 24 | /* This tells Alpha OSF/1 not to define a getopt prototype in .
 25 |    Ditto for AIX 3.2 and .  */
 26 | #ifndef _NO_PROTO
 27 | #define _NO_PROTO
 28 | #endif
 29 | 
 30 | #ifdef HAVE_CONFIG_H
 31 | #include 
 32 | #endif
 33 | 
 34 | #if !defined (__STDC__) || !__STDC__
 35 | /* This is a separate conditional since some stdc systems
 36 |    reject `defined (const)'.  */
 37 | #ifndef const
 38 | #define const
 39 | #endif
 40 | #endif
 41 | 
 42 | #include 
 43 | 
 44 | /* Comment out all this code if we are using the GNU C Library, and are not
 45 |    actually compiling the library itself.  This code is part of the GNU C
 46 |    Library, but also included in many other GNU distributions.  Compiling
 47 |    and linking in this code is a waste when using the GNU C library
 48 |    (especially if it is a shared library).  Rather than having every GNU
 49 |    program understand `configure --with-gnu-libc' and omit the object files,
 50 |    it is simpler to just do this in the source for each such file.  */
 51 | 
 52 | #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
 53 | 
 54 | 
 55 | /* This needs to come after some library #include
 56 |    to get __GNU_LIBRARY__ defined.  */
 57 | #ifdef	__GNU_LIBRARY__
 58 | /* Don't include stdlib.h for non-GNU C libraries because some of them
 59 |    contain conflicting prototypes for getopt.  */
 60 | #include 
 61 | #endif	/* GNU C library.  */
 62 | 
 63 | /* This version of `getopt' appears to the caller like standard Unix `getopt'
 64 |    but it behaves differently for the user, since it allows the user
 65 |    to intersperse the options with the other arguments.
 66 | 
 67 |    As `getopt' works, it permutes the elements of ARGV so that,
 68 |    when it is done, all the options precede everything else.  Thus
 69 |    all application programs are extended to handle flexible argument order.
 70 | 
 71 |    Setting the environment variable POSIXLY_CORRECT disables permutation.
 72 |    Then the behavior is completely standard.
 73 | 
 74 |    GNU application programs can use a third alternative mode in which
 75 |    they can distinguish the relative order of options and other arguments.  */
 76 | 
 77 | #include "getopt.h"
 78 | 
 79 | /* For communication from `getopt' to the caller.
 80 |    When `getopt' finds an option that takes an argument,
 81 |    the argument value is returned here.
 82 |    Also, when `ordering' is RETURN_IN_ORDER,
 83 |    each non-option ARGV-element is returned here.  */
 84 | 
 85 | char *optarg = NULL;
 86 | 
 87 | /* Index in ARGV of the next element to be scanned.
 88 |    This is used for communication to and from the caller
 89 |    and for communication between successive calls to `getopt'.
 90 | 
 91 |    On entry to `getopt', zero means this is the first call; initialize.
 92 | 
 93 |    When `getopt' returns EOF, this is the index of the first of the
 94 |    non-option elements that the caller should itself scan.
 95 | 
 96 |    Otherwise, `optind' communicates from one call to the next
 97 |    how much of ARGV has been scanned so far.  */
 98 | 
 99 | /* XXX 1003.2 says this must be 1 before any call.  */
100 | int optind = 0;
101 | 
102 | /* The next char to be scanned in the option-element
103 |    in which the last option character we returned was found.
104 |    This allows us to pick up the scan where we left off.
105 | 
106 |    If this is zero, or a null string, it means resume the scan
107 |    by advancing to the next ARGV-element.  */
108 | 
109 | static char *nextchar;
110 | 
111 | /* Callers store zero here to inhibit the error message
112 |    for unrecognized options.  */
113 | 
114 | int opterr = 1;
115 | 
116 | /* Set to an option character which was unrecognized.
117 |    This must be initialized on some systems to avoid linking in the
118 |    system's own getopt implementation.  */
119 | 
120 | int optopt = '?';
121 | 
122 | /* Describe how to deal with options that follow non-option ARGV-elements.
123 | 
124 |    If the caller did not specify anything,
125 |    the default is REQUIRE_ORDER if the environment variable
126 |    POSIXLY_CORRECT is defined, PERMUTE otherwise.
127 | 
128 |    REQUIRE_ORDER means don't recognize them as options;
129 |    stop option processing when the first non-option is seen.
130 |    This is what Unix does.
131 |    This mode of operation is selected by either setting the environment
132 |    variable POSIXLY_CORRECT, or using `+' as the first character
133 |    of the list of option characters.
134 | 
135 |    PERMUTE is the default.  We permute the contents of ARGV as we scan,
136 |    so that eventually all the non-options are at the end.  This allows options
137 |    to be given in any order, even with programs that were not written to
138 |    expect this.
139 | 
140 |    RETURN_IN_ORDER is an option available to programs that were written
141 |    to expect options and other ARGV-elements in any order and that care about
142 |    the ordering of the two.  We describe each non-option ARGV-element
143 |    as if it were the argument of an option with character code 1.
144 |    Using `-' as the first character of the list of option characters
145 |    selects this mode of operation.
146 | 
147 |    The special argument `--' forces an end of option-scanning regardless
148 |    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
149 |    `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
150 | 
151 | static enum
152 | {
153 |   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
154 | } ordering;
155 | 
156 | /* Value of POSIXLY_CORRECT environment variable.  */
157 | static char *posixly_correct;
158 | 
159 | #ifdef	__GNU_LIBRARY__
160 | /* We want to avoid inclusion of string.h with non-GNU libraries
161 |    because there are many ways it can cause trouble.
162 |    On some systems, it contains special magic macros that don't work
163 |    in GCC.  */
164 | #include 
165 | #define	my_index	strchr
166 | #else
167 | 
168 | /* Avoid depending on library functions or files
169 |    whose names are inconsistent.  */
170 | 
171 | // function prototypes
172 | char *getenv (char *);
173 | static char *my_index(const char *str, int chr);
174 | static void exchange (char **argv);
175 | static const char *_getopt_initialize (const char *optstring);
176 | int _getopt_internal (
177 |      int argc,
178 |      char *const *argv,
179 |      const char *optstring,
180 |      const struct option *longopts,
181 |      int *longind,
182 |      int long_only);
183 | int getopt (
184 |      int argc,
185 |      char *const *argv,
186 |      const char *optstring);
187 | 
188 | static char *my_index(const char *str, int chr)
189 | {
190 |   while (*str)
191 |     {
192 |       if (*str == chr)
193 | 	return (char *) str;
194 |       str++;
195 |     }
196 |   return 0;
197 | }
198 | 
199 | /* If using GCC, we can safely declare strlen this way.
200 |    If not using GCC, it is ok not to declare it.  */
201 | #ifdef __GNUC__
202 | /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
203 |    That was relevant to code that was here before.  */
204 | #if !defined (__STDC__) || !__STDC__
205 | /* gcc with -traditional declares the built-in strlen to return int,
206 |    and has done so at least since version 2.4.5. -- rms.  */
207 | extern int strlen (const char *);
208 | #endif /* not __STDC__ */
209 | #endif /* __GNUC__ */
210 | 
211 | #endif /* not __GNU_LIBRARY__ */
212 | 
213 | /* Handle permutation of arguments.  */
214 | 
215 | /* Describe the part of ARGV that contains non-options that have
216 |    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
217 |    `last_nonopt' is the index after the last of them.  */
218 | 
219 | static int first_nonopt;
220 | static int last_nonopt;
221 | 
222 | /* Exchange two adjacent subsequences of ARGV.
223 |    One subsequence is elements [first_nonopt,last_nonopt)
224 |    which contains all the non-options that have been skipped so far.
225 |    The other is elements [last_nonopt,optind), which contains all
226 |    the options processed since those non-options were skipped.
227 | 
228 |    `first_nonopt' and `last_nonopt' are relocated so that they describe
229 |    the new indices of the non-options in ARGV after they are moved.  */
230 | 
231 | static void exchange (char **argv)
232 | {
233 |   int bottom = first_nonopt;
234 |   int middle = last_nonopt;
235 |   int top = optind;
236 |   char *tem;
237 | 
238 |   /* Exchange the shorter segment with the far end of the longer segment.
239 |      That puts the shorter segment into the right place.
240 |      It leaves the longer segment in the right place overall,
241 |      but it consists of two parts that need to be swapped next.  */
242 | 
243 |   while (top > middle && middle > bottom)
244 |     {
245 |       if (top - middle > middle - bottom)
246 | 	{
247 | 	  /* Bottom segment is the short one.  */
248 | 	  int len = middle - bottom;
249 | 	  register int i;
250 | 
251 | 	  /* Swap it with the top part of the top segment.  */
252 | 	  for (i = 0; i < len; i++)
253 | 	    {
254 | 	      tem = argv[bottom + i];
255 | 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
256 | 	      argv[top - (middle - bottom) + i] = tem;
257 | 	    }
258 | 	  /* Exclude the moved bottom segment from further swapping.  */
259 | 	  top -= len;
260 | 	}
261 |       else
262 | 	{
263 | 	  /* Top segment is the short one.  */
264 | 	  int len = top - middle;
265 | 	  register int i;
266 | 
267 | 	  /* Swap it with the bottom part of the bottom segment.  */
268 | 	  for (i = 0; i < len; i++)
269 | 	    {
270 | 	      tem = argv[bottom + i];
271 | 	      argv[bottom + i] = argv[middle + i];
272 | 	      argv[middle + i] = tem;
273 | 	    }
274 | 	  /* Exclude the moved top segment from further swapping.  */
275 | 	  bottom += len;
276 | 	}
277 |     }
278 | 
279 |   /* Update records for the slots the non-options now occupy.  */
280 | 
281 |   first_nonopt += (optind - last_nonopt);
282 |   last_nonopt = optind;
283 | }
284 | 
285 | /* Initialize the internal data when the first call is made.  */
286 | 
287 | static const char *_getopt_initialize (const char *optstring)
288 | {
289 |   /* Start processing options with ARGV-element 1 (since ARGV-element 0
290 |      is the program name); the sequence of previously skipped
291 |      non-option ARGV-elements is empty.  */
292 | 
293 |   first_nonopt = last_nonopt = optind = 1;
294 | 
295 |   nextchar = NULL;
296 | 
297 |   posixly_correct = getenv ("POSIXLY_CORRECT");
298 | 
299 |   /* Determine how to handle the ordering of options and nonoptions.  */
300 | 
301 |   if (optstring[0] == '-')
302 |     {
303 |       ordering = RETURN_IN_ORDER;
304 |       ++optstring;
305 |     }
306 |   else if (optstring[0] == '+')
307 |     {
308 |       ordering = REQUIRE_ORDER;
309 |       ++optstring;
310 |     }
311 |   else if (posixly_correct != NULL)
312 |     ordering = REQUIRE_ORDER;
313 |   else
314 |     ordering = PERMUTE;
315 | 
316 |   return optstring;
317 | }
318 | 
319 | /* Scan elements of ARGV (whose length is ARGC) for option characters
320 |    given in OPTSTRING.
321 | 
322 |    If an element of ARGV starts with '-', and is not exactly "-" or "--",
323 |    then it is an option element.  The characters of this element
324 |    (aside from the initial '-') are option characters.  If `getopt'
325 |    is called repeatedly, it returns successively each of the option characters
326 |    from each of the option elements.
327 | 
328 |    If `getopt' finds another option character, it returns that character,
329 |    updating `optind' and `nextchar' so that the next call to `getopt' can
330 |    resume the scan with the following option character or ARGV-element.
331 | 
332 |    If there are no more option characters, `getopt' returns `EOF'.
333 |    Then `optind' is the index in ARGV of the first ARGV-element
334 |    that is not an option.  (The ARGV-elements have been permuted
335 |    so that those that are not options now come last.)
336 | 
337 |    OPTSTRING is a string containing the legitimate option characters.
338 |    If an option character is seen that is not listed in OPTSTRING,
339 |    return '?' after printing an error message.  If you set `opterr' to
340 |    zero, the error message is suppressed but we still return '?'.
341 | 
342 |    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
343 |    so the following text in the same ARGV-element, or the text of the following
344 |    ARGV-element, is returned in `optarg'.  Two colons mean an option that
345 |    wants an optional arg; if there is text in the current ARGV-element,
346 |    it is returned in `optarg', otherwise `optarg' is set to zero.
347 | 
348 |    If OPTSTRING starts with `-' or `+', it requests different methods of
349 |    handling the non-option ARGV-elements.
350 |    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
351 | 
352 |    Long-named options begin with `--' instead of `-'.
353 |    Their names may be abbreviated as long as the abbreviation is unique
354 |    or is an exact match for some defined option.  If they have an
355 |    argument, it follows the option name in the same ARGV-element, separated
356 |    from the option name by a `=', or else the in next ARGV-element.
357 |    When `getopt' finds a long-named option, it returns 0 if that option's
358 |    `flag' field is nonzero, the value of the option's `val' field
359 |    if the `flag' field is zero.
360 | 
361 |    The elements of ARGV aren't really const, because we permute them.
362 |    But we pretend they're const in the prototype to be compatible
363 |    with other systems.
364 | 
365 |    LONGOPTS is a vector of `struct option' terminated by an
366 |    element containing a name which is zero.
367 | 
368 |    LONGIND returns the index in LONGOPT of the long-named option found.
369 |    It is only valid when a long-named option has been found by the most
370 |    recent call.
371 | 
372 |    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
373 |    long-named options.  */
374 | 
375 | int _getopt_internal (
376 |      int argc,
377 |      char *const *argv,
378 |      const char *optstring,
379 |      const struct option *longopts,
380 |      int *longind,
381 |      int long_only)
382 | {
383 |   optarg = NULL;
384 | 
385 |   if (optind == 0)
386 |     optstring = _getopt_initialize (optstring);
387 | 
388 |   if (nextchar == NULL || *nextchar == '\0')
389 |     {
390 |       /* Advance to the next ARGV-element.  */
391 | 
392 |       if (ordering == PERMUTE)
393 | 	{
394 | 	  /* If we have just processed some options following some non-options,
395 | 	     exchange them so that the options come first.  */
396 | 
397 | 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
398 | 	    exchange ((char **) argv);
399 | 	  else if (last_nonopt != optind)
400 | 	    first_nonopt = optind;
401 | 
402 | 	  /* Skip any additional non-options
403 | 	     and extend the range of non-options previously skipped.  */
404 | 
405 | 	  while (optind < argc
406 | 		 && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
407 | 	    optind++;
408 | 	  last_nonopt = optind;
409 | 	}
410 | 
411 |       /* The special ARGV-element `--' means premature end of options.
412 | 	 Skip it like a null option,
413 | 	 then exchange with previous non-options as if it were an option,
414 | 	 then skip everything else like a non-option.  */
415 | 
416 |       if (optind != argc && !strcmp (argv[optind], "--"))
417 | 	{
418 | 	  optind++;
419 | 
420 | 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
421 | 	    exchange ((char **) argv);
422 | 	  else if (first_nonopt == last_nonopt)
423 | 	    first_nonopt = optind;
424 | 	  last_nonopt = argc;
425 | 
426 | 	  optind = argc;
427 | 	}
428 | 
429 |       /* If we have done all the ARGV-elements, stop the scan
430 | 	 and back over any non-options that we skipped and permuted.  */
431 | 
432 |       if (optind == argc)
433 | 	{
434 | 	  /* Set the next-arg-index to point at the non-options
435 | 	     that we previously skipped, so the caller will digest them.  */
436 | 	  if (first_nonopt != last_nonopt)
437 | 	    optind = first_nonopt;
438 | 	  return EOF;
439 | 	}
440 | 
441 |       /* If we have come to a non-option and did not permute it,
442 | 	 either stop the scan or describe it to the caller and pass it by.  */
443 | 
444 |       if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
445 | 	{
446 | 	  if (ordering == REQUIRE_ORDER)
447 | 	    return EOF;
448 | 	  optarg = argv[optind++];
449 | 	  return 1;
450 | 	}
451 | 
452 |       /* We have found another option-ARGV-element.
453 | 	 Skip the initial punctuation.  */
454 | 
455 |       nextchar = (argv[optind] + 1
456 | 		  + (longopts != NULL && argv[optind][1] == '-'));
457 |     }
458 | 
459 |   /* Decode the current option-ARGV-element.  */
460 | 
461 |   /* Check whether the ARGV-element is a long option.
462 | 
463 |      If long_only and the ARGV-element has the form "-f", where f is
464 |      a valid short option, don't consider it an abbreviated form of
465 |      a long option that starts with f.  Otherwise there would be no
466 |      way to give the -f short option.
467 | 
468 |      On the other hand, if there's a long option "fubar" and
469 |      the ARGV-element is "-fu", do consider that an abbreviation of
470 |      the long option, just like "--fu", and not "-f" with arg "u".
471 | 
472 |      This distinction seems to be the most useful approach.  */
473 | 
474 |   if (longopts != NULL
475 |       && (argv[optind][1] == '-'
476 | 	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
477 |     {
478 |       char *nameend;
479 |       const struct option *p;
480 |       const struct option *pfound = NULL;
481 |       int exact = 0;
482 |       int ambig = 0;
483 |       int indfound;
484 |       int option_index;
485 | 
486 |       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
487 | 	/* Do nothing.  */ ;
488 | 
489 |       /* Test all long options for either exact match
490 | 	 or abbreviated matches.  */
491 |       for (p = longopts, option_index = 0; p->name; p++, option_index++)
492 | 	if (!strncmp (p->name, nextchar, nameend - nextchar))
493 | 	  {
494 | 	    if (nameend - nextchar == strlen (p->name))
495 | 	      {
496 | 		/* Exact match found.  */
497 | 		pfound = p;
498 | 		indfound = option_index;
499 | 		exact = 1;
500 | 		break;
501 | 	      }
502 | 	    else if (pfound == NULL)
503 | 	      {
504 | 		/* First nonexact match found.  */
505 | 		pfound = p;
506 | 		indfound = option_index;
507 | 	      }
508 | 	    else
509 | 	      /* Second or later nonexact match found.  */
510 | 	      ambig = 1;
511 | 	  }
512 | 
513 |       if (ambig && !exact)
514 | 	{
515 | 	  if (opterr)
516 | 	    fprintf (stderr, "%s: option `%s' is ambiguous\n",
517 | 		     argv[0], argv[optind]);
518 | 	  nextchar += strlen (nextchar);
519 | 	  optind++;
520 | 	  return '?';
521 | 	}
522 | 
523 |       if (pfound != NULL)
524 | 	{
525 | 	  option_index = indfound;
526 | 	  optind++;
527 | 	  if (*nameend)
528 | 	    {
529 | 	      /* Don't test has_arg with >, because some C compilers don't
530 | 		 allow it to be used on enums.  */
531 | 	      if (pfound->has_arg)
532 | 		optarg = nameend + 1;
533 | 	      else
534 | 		{
535 | 		  if (opterr)
536 | 		    {
537 | 		      if (argv[optind - 1][1] == '-')
538 | 			/* --option */
539 | 			fprintf (stderr,
540 | 				 "%s: option `--%s' doesn't allow an argument\n",
541 | 				 argv[0], pfound->name);
542 | 		      else
543 | 			/* +option or -option */
544 | 			fprintf (stderr,
545 | 			     "%s: option `%c%s' doesn't allow an argument\n",
546 | 			     argv[0], argv[optind - 1][0], pfound->name);
547 | 		    }
548 | 		  nextchar += strlen (nextchar);
549 | 		  return '?';
550 | 		}
551 | 	    }
552 | 	  else if (pfound->has_arg == 1)
553 | 	    {
554 | 	      if (optind < argc)
555 | 		optarg = argv[optind++];
556 | 	      else
557 | 		{
558 | 		  if (opterr)
559 | 		    fprintf (stderr, "%s: option `%s' requires an argument\n",
560 | 			     argv[0], argv[optind - 1]);
561 | 		  nextchar += strlen (nextchar);
562 | 		  return optstring[0] == ':' ? ':' : '?';
563 | 		}
564 | 	    }
565 | 	  nextchar += strlen (nextchar);
566 | 	  if (longind != NULL)
567 | 	    *longind = option_index;
568 | 	  if (pfound->flag)
569 | 	    {
570 | 	      *(pfound->flag) = pfound->val;
571 | 	      return 0;
572 | 	    }
573 | 	  return pfound->val;
574 | 	}
575 | 
576 |       /* Can't find it as a long option.  If this is not getopt_long_only,
577 | 	 or the option starts with '--' or is not a valid short
578 | 	 option, then it's an error.
579 | 	 Otherwise interpret it as a short option.  */
580 |       if (!long_only || argv[optind][1] == '-'
581 | 	  || my_index (optstring, *nextchar) == NULL)
582 | 	{
583 | 	  if (opterr)
584 | 	    {
585 | 	      if (argv[optind][1] == '-')
586 | 		/* --option */
587 | 		fprintf (stderr, "%s: unrecognized option `--%s'\n",
588 | 			 argv[0], nextchar);
589 | 	      else
590 | 		/* +option or -option */
591 | 		fprintf (stderr, "%s: unrecognized option `%c%s'\n",
592 | 			 argv[0], argv[optind][0], nextchar);
593 | 	    }
594 | 	  nextchar = (char *) "";
595 | 	  optind++;
596 | 	  return '?';
597 | 	}
598 |     }
599 | 
600 |   /* Look at and handle the next short option-character.  */
601 | 
602 |   {
603 |     char c = *nextchar++;
604 |     char *temp = my_index (optstring, c);
605 | 
606 |     /* Increment `optind' when we start to process its last character.  */
607 |     if (*nextchar == '\0')
608 |       ++optind;
609 | 
610 |     if (temp == NULL || c == ':')
611 |       {
612 | 	if (opterr)
613 | 	  {
614 | 	    if (posixly_correct)
615 | 	      /* 1003.2 specifies the format of this message.  */
616 | 	      fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
617 | 	    else
618 | 	      fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
619 | 	  }
620 | 	optopt = c;
621 | 	return '?';
622 |       }
623 |     if (temp[1] == ':')
624 |       {
625 | 	if (temp[2] == ':')
626 | 	  {
627 | 	    /* This is an option that accepts an argument optionally.  */
628 | 	    if (*nextchar != '\0')
629 | 	      {
630 | 		optarg = nextchar;
631 | 		optind++;
632 | 	      }
633 | 	    else
634 | 	      optarg = NULL;
635 | 	    nextchar = NULL;
636 | 	  }
637 | 	else
638 | 	  {
639 | 	    /* This is an option that requires an argument.  */
640 | 	    if (*nextchar != '\0')
641 | 	      {
642 | 		optarg = nextchar;
643 | 		/* If we end this ARGV-element by taking the rest as an arg,
644 | 		   we must advance to the next element now.  */
645 | 		optind++;
646 | 	      }
647 | 	    else if (optind == argc)
648 | 	      {
649 | 		if (opterr)
650 | 		  {
651 | 		    /* 1003.2 specifies the format of this message.  */
652 | 		    fprintf (stderr, "%s: option requires an argument -- %c\n",
653 | 			     argv[0], c);
654 | 		  }
655 | 		optopt = c;
656 | 		if (optstring[0] == ':')
657 | 		  c = ':';
658 | 		else
659 | 		  c = '?';
660 | 	      }
661 | 	    else
662 | 	      /* We already incremented `optind' once;
663 | 		 increment it again when taking next ARGV-elt as argument.  */
664 | 	      optarg = argv[optind++];
665 | 	    nextchar = NULL;
666 | 	  }
667 |       }
668 |     return c;
669 |   }
670 | }
671 | 
672 | int getopt (
673 |      int argc,
674 |      char *const *argv,
675 |      const char *optstring)
676 | {
677 |   return _getopt_internal (argc, argv, optstring,
678 | 			   (const struct option *) 0,
679 | 			   (int *) 0,
680 | 			   0);
681 | }
682 | 
683 | #endif	/* _LIBC or not __GNU_LIBRARY__.  */
684 | 
685 | #ifdef TEST
686 | 
687 | /* Compile with -DTEST to make an executable for use in testing
688 |    the above definition of `getopt'.  */
689 | 
690 | int
691 | main (
692 |      int argc,
693 |      char **argv)
694 | {
695 |   int c;
696 |   int digit_optind = 0;
697 | 
698 |   while (1)
699 |     {
700 |       int this_option_optind = optind ? optind : 1;
701 | 
702 |       c = getopt (argc, argv, "abc:d:0123456789");
703 |       if (c == EOF)
704 | 	break;
705 | 
706 |       switch (c)
707 | 	{
708 | 	case '0':
709 | 	case '1':
710 | 	case '2':
711 | 	case '3':
712 | 	case '4':
713 | 	case '5':
714 | 	case '6':
715 | 	case '7':
716 | 	case '8':
717 | 	case '9':
718 | 	  if (digit_optind != 0 && digit_optind != this_option_optind)
719 | 	    printf ("digits occur in two different argv-elements.\n");
720 | 	  digit_optind = this_option_optind;
721 | 	  printf ("option %c\n", c);
722 | 	  break;
723 | 
724 | 	case 'a':
725 | 	  printf ("option a\n");
726 | 	  break;
727 | 
728 | 	case 'b':
729 | 	  printf ("option b\n");
730 | 	  break;
731 | 
732 | 	case 'c':
733 | 	  printf ("option c with value `%s'\n", optarg);
734 | 	  break;
735 | 
736 | 	case '?':
737 | 	  break;
738 | 
739 | 	default:
740 | 	  printf ("?? getopt returned character code 0%o ??\n", c);
741 | 	}
742 |     }
743 | 
744 |   if (optind < argc)
745 |     {
746 |       printf ("non-option ARGV-elements: ");
747 |       while (optind < argc)
748 | 	printf ("%s ", argv[optind++]);
749 |       printf ("\n");
750 |     }
751 | 
752 |   exit (0);
753 | }
754 | 
755 | #endif /* TEST */
756 | 


--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
  1 | /*-----------------------------------------------------------------------------
  2 | FILE        : MAIN.C
  3 | INFO        : Free Superscalar Simulator - Main program file for FREESS
  4 | PURPOSE     : Educational Tool
  5 | DEVELOPEMENT: GCC 2.7.0
  6 | CREATED BY  : RG[14-Oct-2025]
  7 | MODIFIED BY : XX[XX-XXX-XXXX]
  8 | -----------------------------------------------------------------------------*/
  9 | /* Automatically generated by Tool Builder Interface V1.0. */
 10 | /* File: main.c   (Don't edit this file.) */
 11 | 
 12 | /*------------- LIBRARY PROCEDURES ------------------------------------------*/
 13 | #include "sui.h"
 14 | #include "getopt1.h"
 15 | #include "superscalar.h"
 16 | #include "main.h"
 17 | 
 18 | /*------------- GENERAL DEFINITIONS -----------------------------------------*/
 19 | #define PROG_NAME       "freess"
 20 | #define PROG_PRESEN     \
 21 |    "Free Superscalar Simulator - Copyright Roberto Giorgi - giorgi@acm.org\n"\
 22 |    "v1.1 - Released 29-Oct-25 "
 23 | #define PROG_PRESEN2    \
 24 |    "FREESS v1.1 - Released 29-Oct-25 "
 25 | #define PROG_ULINE      \
 26 |    "-------------------------------------------------------------------"
 27 | 
 28 | /*------------- GLOBAL VARIABLES --------------------------------------------*/
 29 | /* Structure that I pass to SUI */
 30 | static const char *freess_app[] =
 31 | {
 32 |    PROG_NAME,
 33 |    PROG_PRESEN,
 34 |    PROG_ULINE
 35 | };
 36 | 
 37 | /* The version of program */
 38 | const char *version_string = PROG_PRESEN;
 39 | 
 40 | /* If nonzero, ... */
 41 | static int autox;
 42 | int Tracing;
 43 | int ETracing;
 44 | int verbose;   /* I need THIS in TRACE FACTORY tools */
 45 | int debug;     /* I need THIS in TRACE FACTORY tools */
 46 | static int template;
 47 | static int nolog;
 48 | static int logga;
 49 | 
 50 | /* If non-zero, display usage information and exit.  */
 51 | static int show_help;
 52 | 
 53 | /* If non-zero, print the version on standard output and exit.  */
 54 | static int show_version;
 55 | 
 56 | /* User selected name of .ini file */
 57 | static char *inifile = NULL;
 58 | 
 59 | /* Declare option-variables */
 60 | static char	clv1[MAXLINELEN] = "program";
 61 | static char	clv2[MAXLINELEN] = "no";
 62 | static char	clv3[MAXLINELEN] = "yes";
 63 | static char	clv4[MAXLINELEN] = "no";
 64 | static char	clv5[MAXLINELEN] = "3";
 65 | static char	clv6[MAXLINELEN] = "0";
 66 | static char	clv7[MAXLINELEN] = "no";
 67 | static char	clv8[MAXLINELEN] = "8";
 68 | static char	clv9[MAXLINELEN] = "24";
 69 | static char	clv10[MAXLINELEN] = "FDPIXWC";
 70 | static char	clv11[MAXLINELEN] = "yes";
 71 | static char	clv12[MAXLINELEN] = "yes";
 72 | static char	clv13[MAXLINELEN] = "no";
 73 | static char	clv14[MAXLINELEN] = "no";
 74 | static char	clv15[MAXLINELEN] = "yes";
 75 | static char	clv16[MAXLINELEN] = "yes";
 76 | static char	clv17[MAXLINELEN] = "yes";
 77 | static char	clv18[MAXLINELEN] = "4";
 78 | static char	clv19[MAXLINELEN] = "4";
 79 | static char	clv20[MAXLINELEN] = "4";
 80 | static char	clv21[MAXLINELEN] = "4";
 81 | static char	clv22[MAXLINELEN] = "4";
 82 | static char	clv23[MAXLINELEN] = "4";
 83 | static char	clv24[MAXLINELEN] = "16";
 84 | static char	clv25[MAXLINELEN] = "16";
 85 | static char	clv26[MAXLINELEN] = "4";
 86 | static char	clv27[MAXLINELEN] = "0";
 87 | static char	clv28[MAXLINELEN] = "100";
 88 | static char	clv29[MAXLINELEN] = "1";
 89 | static char	clv30[MAXLINELEN] = "4";
 90 | static char	clv31[MAXLINELEN] = "yes";
 91 | static char	clv32[MAXLINELEN] = "100";
 92 | static char	clv33[MAXLINELEN] = "1";
 93 | static char	clv34[MAXLINELEN] = "4";
 94 | static char	clv35[MAXLINELEN] = "yes";
 95 | static char	clv36[MAXLINELEN] = "100";
 96 | static char	clv37[MAXLINELEN] = "4";
 97 | static char	clv38[MAXLINELEN] = "1";
 98 | static char	clv39[MAXLINELEN] = "1";
 99 | static char	clv40[MAXLINELEN] = "2";
100 | static char	clv41[MAXLINELEN] = "yes";
101 | static char	clv42[MAXLINELEN] = "1";
102 | static char	clv43[MAXLINELEN] = "1";
103 | static char	clv44[MAXLINELEN] = "yes";
104 | static char	clv45[MAXLINELEN] = "no";
105 | static char	clv46[MAXLINELEN] = "100";
106 | static char	clv47[MAXLINELEN] = "1";
107 | static char	clv48[MAXLINELEN] = "0";
108 | static char	clv49[MAXLINELEN] = "100";
109 | static char	clv50[MAXLINELEN] = "1";
110 | static char	clv51[MAXLINELEN] = "1";
111 | static char	clv52[MAXLINELEN] = "yes";
112 | static char	clv53[MAXLINELEN] = "0";
113 | static char	clv54[MAXLINELEN] = "def.log";
114 | 
115 | 
116 | static struct option long_options[] =
117 | {
118 |   {"inifile", required_argument, NULL, 0},
119 |   {"auto", no_argument, &autox, 1},
120 |   {"tracing", no_argument, &Tracing, 1},
121 |   {"etracing", no_argument, &ETracing, 1},
122 |   {"verbose", no_argument, &verbose, 1},
123 |   {"debug", required_argument, NULL, 0},
124 |   {"template", no_argument, &template, 1},
125 |   {"log", no_argument, &logga, 1},
126 |   {"help", no_argument, &show_help, 1},
127 |   {"version", no_argument, &show_version, 1},
128 |   {"exe", required_argument, NULL, 0},
129 |   {"s", required_argument, NULL, 0},
130 |   {"int", required_argument, NULL, 0},
131 |   {"batch", required_argument, NULL, 0},
132 |   {"iter", required_argument, NULL, 0},
133 |   {"stck", required_argument, NULL, 0},
134 |   {"tom", required_argument, NULL, 0},
135 |   {"lregs", required_argument, NULL, 0},
136 |   {"pregs", required_argument, NULL, 0},
137 |   {"pstruct", required_argument, NULL, 0},
138 |   {"unilsu", required_argument, NULL, 0},
139 |   {"loadpri", required_argument, NULL, 0},
140 |   {"ioi", required_argument, NULL, 0},
141 |   {"ioc", required_argument, NULL, 0},
142 |   {"unidi", required_argument, NULL, 0},
143 |   {"rsrel", required_argument, NULL, 0},
144 |   {"mempipe", required_argument, NULL, 0},
145 |   {"fw", required_argument, NULL, 0},
146 |   {"dw", required_argument, NULL, 0},
147 |   {"pw", required_argument, NULL, 0},
148 |   {"iw", required_argument, NULL, 0},
149 |   {"ww", required_argument, NULL, 0},
150 |   {"cw", required_argument, NULL, 0},
151 |   {"wins	", required_argument, NULL, 0},
152 |   {"robs	", required_argument, NULL, 0},
153 |   {"afu	", required_argument, NULL, 0},
154 |   {"alat", required_argument, NULL, 0},
155 |   {"ars", required_argument, NULL, 0},
156 |   {"mfu	", required_argument, NULL, 0},
157 |   {"mlat", required_argument, NULL, 0},
158 |   {"mpipe", required_argument, NULL, 0},
159 |   {"mrs", required_argument, NULL, 0},
160 |   {"dfu	", required_argument, NULL, 0},
161 |   {"dlat", required_argument, NULL, 0},
162 |   {"dpipe", required_argument, NULL, 0},
163 |   {"drs", required_argument, NULL, 0},
164 |   {"ffu	", required_argument, NULL, 0},
165 |   {"xfu	", required_argument, NULL, 0},
166 |   {"lfu	", required_argument, NULL, 0},
167 |   {"llat", required_argument, NULL, 0},
168 |   {"lpipe", required_argument, NULL, 0},
169 |   {"sfu	", required_argument, NULL, 0},
170 |   {"slat", required_argument, NULL, 0},
171 |   {"spipe", required_argument, NULL, 0},
172 |   {"swaits", required_argument, NULL, 0},
173 |   {"lsrs", required_argument, NULL, 0},
174 |   {"bfu	", required_argument, NULL, 0},
175 |   {"blat", required_argument, NULL, 0},
176 |   {"brs", required_argument, NULL, 0},
177 |   {"lqs	", required_argument, NULL, 0},
178 |   {"sqs	", required_argument, NULL, 0},
179 |   {"spec", required_argument, NULL, 0},
180 |   {"wblat	", required_argument, NULL, 0},
181 |   {"logfile", required_argument, NULL, 0},
182 | 
183 |   {NULL, 0, NULL, 0}
184 | };
185 | 
186 | General				G;
187 | Architecture			AA;
188 | Program_Defaults		Pro;
189 | 
190 | static IniSection GeneralSec[] =
191 | {
192 |    "General",				HEADER,	0,	0,	NULL,
193 |    "Program Name",			STRING,	0,	0,	&G.progname,
194 |    "Silent",				YES_NO,	0,	0,	&G.silent,
195 |    "Interactive",			YES_NO,	0,	0,	&G.interactive,
196 |    "Mode",				YES_NO,	0,	0,	&G.batch,
197 |    "Iterations",			NUMVAL,	1,	0,	&G.iterations,
198 |    "Starting Clock Cycle",		NUMVAL,	-100,	100,	&G.start_ck,
199 |    "Tomasulo Mode",			YES_NO,	0,	0,	&G.tomasulo,
200 |    "",					ENDING,	0,	0,	NULL
201 | };
202 | 
203 | static IniSection ArchitectureSec[] =
204 | {
205 |    "Architecture",			HEADER,	0,	0,	NULL,
206 |    "Logical Registers",			NUMVAL,	1,	MAXPHYSREGS,	&AA.lregs,
207 |    "Physical Registers",		NUMVAL,	1,	MAXPHYSREGS,	&AA.pregs,
208 |    "Pipeline Structure",		STRING,	0,	0,	&AA.pipestruct,
209 |    "Unified LSU",			YES_NO,	0,	0,	&AA.uni_lsu,
210 |    "Load over Store Pri",		YES_NO,	0,	0,	&AA.load_has_pri,
211 |    "In-Order Issue",			YES_NO,	0,	0,	&AA.io_issue,
212 |    "In-Order Complete",			YES_NO,	0,	0,	&AA.io_complete,
213 |    "Unified Disp./Issue",		YES_NO,	0,	0,	&AA.uni_di,
214 |    "Early RS Release",			YES_NO,	0,	0,	&AA.early_rs_rel,
215 |    "Data Mem. Pipe",			YES_NO,	0,	0,	&AA.mem_pipe,
216 |    "Fetch Width",			NUMVAL,	1,	MAXISSUEWIDTH,	&AA.f_width,
217 |    "Decode Width",			NUMVAL,	1,	MAXISSUEWIDTH,	&AA.d_width,
218 |    "Dispatch Width",			NUMVAL,	1,	MAXISSUEWIDTH,	&AA.p_width,
219 |    "Issue Width",			NUMVAL,	1,	MAXISSUEWIDTH,	&AA.i_width,
220 |    "Write-Back Width",			NUMVAL,	1,	MAXISSUEWIDTH,	&AA.w_width,
221 |    "Commit Width",			NUMVAL,	1,	MAXROBSIZE,	&AA.c_width,
222 |    "Window Size",			NUMVAL,	1,	MAXWINDOWSIZE,	&AA.win_size,
223 |    "ROB Size",				NUMVAL,	1,	MAXROBSIZE,	&AA.rob_size,
224 |    "Integer ALU Units",			NUMVAL,	1,	MAXINTFU,	&AA.int_fu,
225 |    "Integer ALU Latency",		NUMVAL,	0,	MAXLATENCY,	&AA.a_lat,
226 |    "Int. ALU Res.Stat.",		NUMVAL,	1,	MAXRSPERFU,	&AA.a_rs,
227 |    "Integer Mult. Units",		NUMVAL,	1,	MAXINTFU,	&AA.im_fu,
228 |    "Integer Mul. Latency",		NUMVAL,	1,	MAXLATENCY,	&AA.im_lat,
229 |    "Integer Mul. Pipe",			YES_NO,	0,	0,	&AA.im_pipe,
230 |    "Int. Mul. Res.Stat.",		NUMVAL,	1,	MAXRSPERFU,	&AA.im_rs,
231 |    "Integer Div. Units",		NUMVAL,	1,	MAXINTFU,	&AA.id_fu,
232 |    "Integer Div. Latency",		NUMVAL,	1,	MAXLATENCY,	&AA.id_lat,
233 |    "Integer Div. Pipe",			YES_NO,	0,	0,	&AA.id_pipe,
234 |    "Int. Div. Res.Stat.",		NUMVAL,	1,	MAXRSPERFU,	&AA.id_rs,
235 |    "Floating Point Units",		NUMVAL,	1,	MAXFPFU,	&AA.fp_fu,
236 |    "Floating Point Mul",		NUMVAL,	1,	MAXFPFU,	&AA.fm_fu,
237 |    "Load Units",			NUMVAL,	1,	MAXLFU,	&AA.l_fu,
238 |    "Load Latency",			NUMVAL,	1,	MAXLATENCY,	&AA.l_lat,
239 |    "Load Pipe",				YES_NO,	0,	0,	&AA.l_pipe,
240 |    "Store Units",			NUMVAL,	1,	MAXSFU,	&AA.s_fu,
241 |    "Store Latency",			NUMVAL,	1,	MAXLATENCY,	&AA.s_lat,
242 |    "Store Pipe",			YES_NO,	0,	0,	&AA.s_pipe,
243 |    "Store Waits",			YES_NO,	0,	0,	&AA.s_waits,
244 |    "Load/Store Res.Stat.",		NUMVAL,	1,	MAXRSPERFU,	&AA.ls_rs,
245 |    "Branch Units",			NUMVAL,	1,	MAXBFU,	&AA.b_fu,
246 |    "Branch Latency",			NUMVAL,	0,	MAXLATENCY,	&AA.b_lat,
247 |    "Branch Res.Stat.",			NUMVAL,	1,	MAXRSPERFU,	&AA.b_rs,
248 |    "Load Queue Size",			NUMVAL,	1,	MAXLQSIZE,	&AA.lqsize,
249 |    "Store Queue Size",			NUMVAL,	1,	MAXSQSIZE,	&AA.sqsize,
250 |    "Speculation",			YES_NO,	0,	0,	&AA.speculation,
251 |    "Write Back Latency",		NUMVAL,	1,	0,	&AA.wblat,
252 |    "",					ENDING,	0,	0,	NULL
253 | };
254 | 
255 | static IniSection Program_DefaultsSec[] =
256 | {
257 |    "Program Defaults",			HEADER,	0,	0,	NULL,
258 |    "Log File Name",			STRING,	0,	0,	&Pro.logfile,
259 |    "",					ENDING,	0,	0,	NULL
260 | };
261 | 
262 | 
263 | 
264 | static char rfn[MAXFILENAMELEN];
265 | static char iniv1[12*MAXLINELEN];
266 | static char iniv[10*MAXLINELEN];
267 | static char aux1[MAXFILENAMELEN];
268 | 
269 | /*------------- INTERNAL FUNCTIONS PROTOTYPES -------------------------------*/
270 | static  int     MainConstr(int argc, char **argv);
271 | static  void    MainDestru(void);
272 | static  void    Usage(int status);
273 | 
274 | /*------------- MAIN PROGRAM ------------------------------------------------*/
275 | int main(int argc, char **argv)
276 | {
277 |    MainConstr(argc, argv);
278 |    Superscalar__Start(argc, argv);
279 |    ExitProg("-Goodbye.");
280 |    return (0);
281 | }
282 | 
283 | /*------------- FUNCTION IMPLEMENTATION -------------------------------------*/
284 | /*---------------------------------------------------------------------------*
285 |  NAME      :
286 |  PURPOSE   :
287 |  PARAMETERS: None
288 |  RETURN    : None
289 |  *---------------------------------------------------------------------------*/
290 | int MainConstr(int argc, char **argv)
291 | {
292 |    int  c, usage = 0, ok = 0, option_index;
293 |    FILE *fp;
294 |    char fn[MAXFILENAMELEN];
295 | 
296 |    /* Scan command line */
297 |    while (1) {
298 |       option_index = 0;
299 | 
300 |       c = getopt_long_only(argc, argv, "i:vd", long_options, &option_index);
301 |       if (c == EOF) break;
302 | 
303 |       switch (c) {
304 |       case 0: /* Long-named option. */
305 |          if (strcmp("verbose", long_options[option_index].name) == 0)
306 |             if (optarg) { ++verbose; ok = 1; }
307 |          if (strcmp("debug", long_options[option_index].name) == 0)
308 |             if (optarg) { debug = atoi(optarg); ok = 1; }
309 |          if (strcmp("inifile", long_options[option_index].name) == 0)
310 |             if (optarg) { inifile = optarg; ok = 1; }
311 |          if (strcmp("template", long_options[option_index].name) == 0)
312 |             { logga = 0; ok = 1; }
313 |          if (strcmp("auto", long_options[option_index].name) == 0)
314 |             { autox = 1; ok = 1; }
315 |          if (strcmp("tracing", long_options[option_index].name) == 0)
316 |             { Tracing = 1; ok = 1; }
317 |          if (strcmp("etracing", long_options[option_index].name) == 0)
318 |             { ETracing = 1; Tracing = 1; ok = 1; }
319 |          if (strcmp("log", long_options[option_index].name) == 0)
320 |             { logga = 1; ok = 1; }
321 |          if (strcmp("exe", long_options[option_index].name) == 0)
322 |             if (optarg) { strcpy(clv1, optarg); ok = 1; }
323 |          if (strcmp("s", long_options[option_index].name) == 0)
324 |             if (optarg) { strcpy(clv2, optarg); ok = 1; }
325 |          if (strcmp("int", long_options[option_index].name) == 0)
326 |             if (optarg) { strcpy(clv3, optarg); ok = 1; }
327 |          if (strcmp("batch", long_options[option_index].name) == 0)
328 |             if (optarg) { strcpy(clv4, optarg); ok = 1; }
329 |          if (strcmp("iter", long_options[option_index].name) == 0)
330 |             if (optarg) { strcpy(clv5, optarg); ok = 1; }
331 |          if (strcmp("stck", long_options[option_index].name) == 0)
332 |             if (optarg) { strcpy(clv6, optarg); ok = 1; }
333 |          if (strcmp("tom", long_options[option_index].name) == 0)
334 |             if (optarg) { strcpy(clv7, optarg); ok = 1; }
335 |          if (strcmp("lregs", long_options[option_index].name) == 0)
336 |             if (optarg) { strcpy(clv8, optarg); ok = 1; }
337 |          if (strcmp("pregs", long_options[option_index].name) == 0)
338 |             if (optarg) { strcpy(clv9, optarg); ok = 1; }
339 |          if (strcmp("pstruct", long_options[option_index].name) == 0)
340 |             if (optarg) { strcpy(clv10, optarg); ok = 1; }
341 |          if (strcmp("unilsu", long_options[option_index].name) == 0)
342 |             if (optarg) { strcpy(clv11, optarg); ok = 1; }
343 |          if (strcmp("loadpri", long_options[option_index].name) == 0)
344 |             if (optarg) { strcpy(clv12, optarg); ok = 1; }
345 |          if (strcmp("ioi", long_options[option_index].name) == 0)
346 |             if (optarg) { strcpy(clv13, optarg); ok = 1; }
347 |          if (strcmp("ioc", long_options[option_index].name) == 0)
348 |             if (optarg) { strcpy(clv14, optarg); ok = 1; }
349 |          if (strcmp("unidi", long_options[option_index].name) == 0)
350 |             if (optarg) { strcpy(clv15, optarg); ok = 1; }
351 |          if (strcmp("rsrel", long_options[option_index].name) == 0)
352 |             if (optarg) { strcpy(clv16, optarg); ok = 1; }
353 |          if (strcmp("mempipe", long_options[option_index].name) == 0)
354 |             if (optarg) { strcpy(clv17, optarg); ok = 1; }
355 |          if (strcmp("fw", long_options[option_index].name) == 0)
356 |             if (optarg) { strcpy(clv18, optarg); ok = 1; }
357 |          if (strcmp("dw", long_options[option_index].name) == 0)
358 |             if (optarg) { strcpy(clv19, optarg); ok = 1; }
359 |          if (strcmp("pw", long_options[option_index].name) == 0)
360 |             if (optarg) { strcpy(clv20, optarg); ok = 1; }
361 |          if (strcmp("iw", long_options[option_index].name) == 0)
362 |             if (optarg) { strcpy(clv21, optarg); ok = 1; }
363 |          if (strcmp("ww", long_options[option_index].name) == 0)
364 |             if (optarg) { strcpy(clv22, optarg); ok = 1; }
365 |          if (strcmp("cw", long_options[option_index].name) == 0)
366 |             if (optarg) { strcpy(clv23, optarg); ok = 1; }
367 |          if (strcmp("wins	", long_options[option_index].name) == 0)
368 |             if (optarg) { strcpy(clv24, optarg); ok = 1; }
369 |          if (strcmp("robs	", long_options[option_index].name) == 0)
370 |             if (optarg) { strcpy(clv25, optarg); ok = 1; }
371 |          if (strcmp("afu	", long_options[option_index].name) == 0)
372 |             if (optarg) { strcpy(clv26, optarg); ok = 1; }
373 |          if (strcmp("alat", long_options[option_index].name) == 0)
374 |             if (optarg) { strcpy(clv27, optarg); ok = 1; }
375 |          if (strcmp("ars", long_options[option_index].name) == 0)
376 |             if (optarg) { strcpy(clv28, optarg); ok = 1; }
377 |          if (strcmp("mfu	", long_options[option_index].name) == 0)
378 |             if (optarg) { strcpy(clv29, optarg); ok = 1; }
379 |          if (strcmp("mlat", long_options[option_index].name) == 0)
380 |             if (optarg) { strcpy(clv30, optarg); ok = 1; }
381 |          if (strcmp("mpipe", long_options[option_index].name) == 0)
382 |             if (optarg) { strcpy(clv31, optarg); ok = 1; }
383 |          if (strcmp("mrs", long_options[option_index].name) == 0)
384 |             if (optarg) { strcpy(clv32, optarg); ok = 1; }
385 |          if (strcmp("dfu	", long_options[option_index].name) == 0)
386 |             if (optarg) { strcpy(clv33, optarg); ok = 1; }
387 |          if (strcmp("dlat", long_options[option_index].name) == 0)
388 |             if (optarg) { strcpy(clv34, optarg); ok = 1; }
389 |          if (strcmp("dpipe", long_options[option_index].name) == 0)
390 |             if (optarg) { strcpy(clv35, optarg); ok = 1; }
391 |          if (strcmp("drs", long_options[option_index].name) == 0)
392 |             if (optarg) { strcpy(clv36, optarg); ok = 1; }
393 |          if (strcmp("ffu	", long_options[option_index].name) == 0)
394 |             if (optarg) { strcpy(clv37, optarg); ok = 1; }
395 |          if (strcmp("xfu	", long_options[option_index].name) == 0)
396 |             if (optarg) { strcpy(clv38, optarg); ok = 1; }
397 |          if (strcmp("lfu	", long_options[option_index].name) == 0)
398 |             if (optarg) { strcpy(clv39, optarg); ok = 1; }
399 |          if (strcmp("llat", long_options[option_index].name) == 0)
400 |             if (optarg) { strcpy(clv40, optarg); ok = 1; }
401 |          if (strcmp("lpipe", long_options[option_index].name) == 0)
402 |             if (optarg) { strcpy(clv41, optarg); ok = 1; }
403 |          if (strcmp("sfu	", long_options[option_index].name) == 0)
404 |             if (optarg) { strcpy(clv42, optarg); ok = 1; }
405 |          if (strcmp("slat", long_options[option_index].name) == 0)
406 |             if (optarg) { strcpy(clv43, optarg); ok = 1; }
407 |          if (strcmp("spipe", long_options[option_index].name) == 0)
408 |             if (optarg) { strcpy(clv44, optarg); ok = 1; }
409 |          if (strcmp("swaits", long_options[option_index].name) == 0)
410 |             if (optarg) { strcpy(clv45, optarg); ok = 1; }
411 |          if (strcmp("lsrs", long_options[option_index].name) == 0)
412 |             if (optarg) { strcpy(clv46, optarg); ok = 1; }
413 |          if (strcmp("bfu	", long_options[option_index].name) == 0)
414 |             if (optarg) { strcpy(clv47, optarg); ok = 1; }
415 |          if (strcmp("blat", long_options[option_index].name) == 0)
416 |             if (optarg) { strcpy(clv48, optarg); ok = 1; }
417 |          if (strcmp("brs", long_options[option_index].name) == 0)
418 |             if (optarg) { strcpy(clv49, optarg); ok = 1; }
419 |          if (strcmp("lqs	", long_options[option_index].name) == 0)
420 |             if (optarg) { strcpy(clv50, optarg); ok = 1; }
421 |          if (strcmp("sqs	", long_options[option_index].name) == 0)
422 |             if (optarg) { strcpy(clv51, optarg); ok = 1; }
423 |          if (strcmp("spec", long_options[option_index].name) == 0)
424 |             if (optarg) { strcpy(clv52, optarg); ok = 1; }
425 |          if (strcmp("wblat	", long_options[option_index].name) == 0)
426 |             if (optarg) { strcpy(clv53, optarg); ok = 1; }
427 |          if (strcmp("logfile", long_options[option_index].name) == 0)
428 |             if (optarg) { strcpy(clv54, optarg); ok = 1; }
429 | 
430 |          break;
431 |       case 'i':
432 |          if (optarg) { inifile = optarg; ok = 1; }
433 |          break; 
434 |       case 'v':
435 |          ++verbose; ok = 1;
436 |          break;
437 |       case 'd':
438 |          ++debug; ok = 1;
439 |          break;
440 |       default:
441 |          usage = 1;
442 |          break;
443 |       }
444 |    }
445 |    if (show_version)
446 |    {
447 |       printf("%s\n", version_string);
448 |       ExitProg("%s", "-");
449 |    }
450 |    if (show_help) Usage(0);
451 |    if (usage || ok == 0 || optind < argc) Usage(1);
452 | 
453 | 
454 |    RegisterIniSec(GeneralSec);
455 |    RegisterIniSec(ArchitectureSec);
456 |    RegisterIniSec(Program_DefaultsSec);
457 | 
458 |    /* Shell script execution */
459 |    strcat(iniv, "progname="); strcat(iniv, clv1); strcat(iniv, ";");
460 |    strcat(iniv, "silent="); strcat(iniv, clv2); strcat(iniv, ";");
461 |    strcat(iniv, "interactive="); strcat(iniv, clv3); strcat(iniv, ";");
462 |    strcat(iniv, "batch="); strcat(iniv, clv4); strcat(iniv, ";");
463 |    strcat(iniv, "iterations="); strcat(iniv, clv5); strcat(iniv, ";");
464 |    strcat(iniv, "start_ck="); strcat(iniv, clv6); strcat(iniv, ";");
465 |    strcat(iniv, "tomasulo="); strcat(iniv, clv7); strcat(iniv, ";");
466 |    strcat(iniv, "lregs="); strcat(iniv, clv8); strcat(iniv, ";");
467 |    strcat(iniv, "pregs="); strcat(iniv, clv9); strcat(iniv, ";");
468 |    strcat(iniv, "pipestruct="); strcat(iniv, clv10); strcat(iniv, ";");
469 |    strcat(iniv, "uni_lsu="); strcat(iniv, clv11); strcat(iniv, ";");
470 |    strcat(iniv, "load_has_pri="); strcat(iniv, clv12); strcat(iniv, ";");
471 |    strcat(iniv, "io_issue="); strcat(iniv, clv13); strcat(iniv, ";");
472 |    strcat(iniv, "io_complete="); strcat(iniv, clv14); strcat(iniv, ";");
473 |    strcat(iniv, "uni_di="); strcat(iniv, clv15); strcat(iniv, ";");
474 |    strcat(iniv, "early_rs_rel="); strcat(iniv, clv16); strcat(iniv, ";");
475 |    strcat(iniv, "mem_pipe="); strcat(iniv, clv17); strcat(iniv, ";");
476 |    strcat(iniv, "f_width="); strcat(iniv, clv18); strcat(iniv, ";");
477 |    strcat(iniv, "d_width="); strcat(iniv, clv19); strcat(iniv, ";");
478 |    strcat(iniv, "p_width="); strcat(iniv, clv20); strcat(iniv, ";");
479 |    strcat(iniv, "i_width="); strcat(iniv, clv21); strcat(iniv, ";");
480 |    strcat(iniv, "w_width="); strcat(iniv, clv22); strcat(iniv, ";");
481 |    strcat(iniv, "c_width="); strcat(iniv, clv23); strcat(iniv, ";");
482 |    strcat(iniv, "win_size="); strcat(iniv, clv24); strcat(iniv, ";");
483 |    strcat(iniv, "rob_size="); strcat(iniv, clv25); strcat(iniv, ";");
484 |    strcat(iniv, "int_fu="); strcat(iniv, clv26); strcat(iniv, ";");
485 |    strcat(iniv, "a_lat="); strcat(iniv, clv27); strcat(iniv, ";");
486 |    strcat(iniv, "a_rs="); strcat(iniv, clv28); strcat(iniv, ";");
487 |    strcat(iniv, "im_fu="); strcat(iniv, clv29); strcat(iniv, ";");
488 |    strcat(iniv, "im_lat="); strcat(iniv, clv30); strcat(iniv, ";");
489 |    strcat(iniv, "im_pipe="); strcat(iniv, clv31); strcat(iniv, ";");
490 |    strcat(iniv, "im_rs="); strcat(iniv, clv32); strcat(iniv, ";");
491 |    strcat(iniv, "id_fu="); strcat(iniv, clv33); strcat(iniv, ";");
492 |    strcat(iniv, "id_lat="); strcat(iniv, clv34); strcat(iniv, ";");
493 |    strcat(iniv, "id_pipe="); strcat(iniv, clv35); strcat(iniv, ";");
494 |    strcat(iniv, "id_rs="); strcat(iniv, clv36); strcat(iniv, ";");
495 |    strcat(iniv, "fp_fu="); strcat(iniv, clv37); strcat(iniv, ";");
496 |    strcat(iniv, "fm_fu="); strcat(iniv, clv38); strcat(iniv, ";");
497 |    strcat(iniv, "l_fu="); strcat(iniv, clv39); strcat(iniv, ";");
498 |    strcat(iniv, "l_lat="); strcat(iniv, clv40); strcat(iniv, ";");
499 |    strcat(iniv, "l_pipe="); strcat(iniv, clv41); strcat(iniv, ";");
500 |    strcat(iniv, "s_fu="); strcat(iniv, clv42); strcat(iniv, ";");
501 |    strcat(iniv, "s_lat="); strcat(iniv, clv43); strcat(iniv, ";");
502 |    strcat(iniv, "s_pipe="); strcat(iniv, clv44); strcat(iniv, ";");
503 |    strcat(iniv, "s_waits="); strcat(iniv, clv45); strcat(iniv, ";");
504 |    strcat(iniv, "ls_rs="); strcat(iniv, clv46); strcat(iniv, ";");
505 |    strcat(iniv, "b_fu="); strcat(iniv, clv47); strcat(iniv, ";");
506 |    strcat(iniv, "b_lat="); strcat(iniv, clv48); strcat(iniv, ";");
507 |    strcat(iniv, "b_rs="); strcat(iniv, clv49); strcat(iniv, ";");
508 |    strcat(iniv, "lqsize="); strcat(iniv, clv50); strcat(iniv, ";");
509 |    strcat(iniv, "sqsize="); strcat(iniv, clv51); strcat(iniv, ";");
510 |    strcat(iniv, "speculation="); strcat(iniv, clv52); strcat(iniv, ";");
511 |    strcat(iniv, "wblat="); strcat(iniv, clv53); strcat(iniv, ";");
512 |    strcat(iniv, "logfile="); strcat(iniv, clv54); strcat(iniv, ";");
513 | 
514 | 
515 |    strcpy(iniv1, iniv);
516 |    strcat(iniv1, "rfn=`echo \"$progname\"`");
517 |    Mysysopen(iniv1);
518 |    Mysyspars(rfn, "rfn");
519 |    Mysysclose();
520 | 
521 |    strcpy(iniv1, iniv);
522 |    strcat(iniv1, "rfn="); strcat(iniv1, rfn); strcat(iniv1, ";");
523 |    strcat(iniv1, "logfile=$rfn.log");
524 |    Mysysopen(iniv1);
525 | 
526 |    Mysysclose();
527 | 
528 |    /* Command Line Variable Initialization */
529 |    strcpy(G.progname, clv1);
530 |    G.silent = (0 == strcmp(clv2, "yes") ? 1 : 0);
531 |    G.interactive = (0 == strcmp(clv3, "yes") ? 1 : 0);
532 |    G.batch = (0 == strcmp(clv4, "yes") ? 1 : 0);
533 |    IsNumVal(clv5, &(G.iterations));;
534 |    IsNumVal(clv6, &(G.start_ck));;
535 |    G.tomasulo = (0 == strcmp(clv7, "yes") ? 1 : 0);
536 |    IsNumVal(clv8, &(AA.lregs));;
537 |    IsNumVal(clv9, &(AA.pregs));;
538 |    strcpy(AA.pipestruct, clv10);
539 |    AA.uni_lsu = (0 == strcmp(clv11, "yes") ? 1 : 0);
540 |    AA.load_has_pri = (0 == strcmp(clv12, "yes") ? 1 : 0);
541 |    AA.io_issue = (0 == strcmp(clv13, "yes") ? 1 : 0);
542 |    AA.io_complete = (0 == strcmp(clv14, "yes") ? 1 : 0);
543 |    AA.uni_di = (0 == strcmp(clv15, "yes") ? 1 : 0);
544 |    AA.early_rs_rel = (0 == strcmp(clv16, "yes") ? 1 : 0);
545 |    AA.mem_pipe = (0 == strcmp(clv17, "yes") ? 1 : 0);
546 |    IsNumVal(clv18, &(AA.f_width));;
547 |    IsNumVal(clv19, &(AA.d_width));;
548 |    IsNumVal(clv20, &(AA.p_width));;
549 |    IsNumVal(clv21, &(AA.i_width));;
550 |    IsNumVal(clv22, &(AA.w_width));;
551 |    IsNumVal(clv23, &(AA.c_width));;
552 |    IsNumVal(clv24, &(AA.win_size));;
553 |    IsNumVal(clv25, &(AA.rob_size));;
554 |    IsNumVal(clv26, &(AA.int_fu));;
555 |    IsNumVal(clv27, &(AA.a_lat));;
556 |    IsNumVal(clv28, &(AA.a_rs));;
557 |    IsNumVal(clv29, &(AA.im_fu));;
558 |    IsNumVal(clv30, &(AA.im_lat));;
559 |    AA.im_pipe = (0 == strcmp(clv31, "yes") ? 1 : 0);
560 |    IsNumVal(clv32, &(AA.im_rs));;
561 |    IsNumVal(clv33, &(AA.id_fu));;
562 |    IsNumVal(clv34, &(AA.id_lat));;
563 |    AA.id_pipe = (0 == strcmp(clv35, "yes") ? 1 : 0);
564 |    IsNumVal(clv36, &(AA.id_rs));;
565 |    IsNumVal(clv37, &(AA.fp_fu));;
566 |    IsNumVal(clv38, &(AA.fm_fu));;
567 |    IsNumVal(clv39, &(AA.l_fu));;
568 |    IsNumVal(clv40, &(AA.l_lat));;
569 |    AA.l_pipe = (0 == strcmp(clv41, "yes") ? 1 : 0);
570 |    IsNumVal(clv42, &(AA.s_fu));;
571 |    IsNumVal(clv43, &(AA.s_lat));;
572 |    AA.s_pipe = (0 == strcmp(clv44, "yes") ? 1 : 0);
573 |    AA.s_waits = (0 == strcmp(clv45, "yes") ? 1 : 0);
574 |    IsNumVal(clv46, &(AA.ls_rs));;
575 |    IsNumVal(clv47, &(AA.b_fu));;
576 |    IsNumVal(clv48, &(AA.b_lat));;
577 |    IsNumVal(clv49, &(AA.b_rs));;
578 |    IsNumVal(clv50, &(AA.lqsize));;
579 |    IsNumVal(clv51, &(AA.sqsize));;
580 |    AA.speculation = (0 == strcmp(clv52, "yes") ? 1 : 0);
581 |    IsNumVal(clv53, &(AA.wblat));;
582 |    strcpy(Pro.logfile, clv54);
583 | 
584 |    strcpy(flogname, Pro.logfile);
585 | 
586 |    /* Call all constructors */
587 |    nolog = 1 - logga;
588 |    SUIConstr1(MainDestru, freess_app, inifile, nolog);
589 | 
590 |    /*  */
591 |    if (template) {
592 |       GenIniTemplate();
593 |       ExitProg("%s", "-");
594 |    }
595 | 
596 |    /* Log Ini Parameters */
597 |    if (!G.silent) LogIniParm();
598 | 
599 |    /* Show Program Headings */
600 |    if (verbose) Display("%s", PROG_PRESEN2);
601 |    Superscalar__Constr();
602 | 
603 |    return (0);
604 | }
605 | 
606 | /*---------------------------------------------------------------------------*
607 |  NAME      :
608 |  PURPOSE   :
609 |  PARAMETERS:
610 |  RETURN    : 
611 |  *---------------------------------------------------------------------------*/
612 | void MainDestru(void)
613 | {
614 |    /* Call all destructors */
615 |    Superscalar__Destru();
616 |    SUIDestru();
617 | }
618 | 
619 | 
620 | /*---------------------------------------------------------------------------*
621 |  NAME      :
622 |  PURPOSE   :
623 |  PARAMETERS:
624 |  RETURN    : 
625 |  *---------------------------------------------------------------------------*/
626 | void Usage(int status)
627 | {
628 |    if (status != 0)
629 |       fprintf (stderr, "Try `%s -help' for more information.\n\n", PROG_NAME);
630 |    else
631 |    {
632 |       printf ("\
633 | Usage: %s [OPTION(s)]\n\
634 | Options:\n\
635 | ", PROG_NAME);
636 |       printf ("\
637 | \n\
638 |   -i, -inifile=FILENAME		  set inifile to FILENAME\n\
639 |   -v, -verbose			  print detailed operations on screen\n\
640 |   -help				  display this help and exit\n\
641 |   -version			  output version information and exit\n\
642 |   -auto				  allow the autostart (with no options)\n\
643 |   -tracing			  trace functions (for debugging)\n\
644 |   -log				  enable log-file creation\n\
645 |   -template			  produce inifile with current parameters\n\
646 |   -exe 		  Name of program (program)\n\
647 |   -s 			  Silent Mode (no)\n\
648 |   -int 		  Interactive Mode (yes)\n\
649 |   -batch 			  Batch File Mode (no)\n\
650 |   -iter 		  Number of Iterations (3)\n\
651 |   -stck 	  Starting Clock Cycle (0)\n\
652 |   -tom 		  Tomasulo Pipeline + RS (no)\n\
653 |   -lregs 	  Number of Logical Regs (8)\n\
654 |   -pregs 	  Number of Physical Regs (24)\n\
655 |   -pstruct 	  Pipeline Structure (FDPIXWC)\n\
656 |   -unilsu 		  Unified LSU (yes)\n\
657 |   -loadpri   Load over Store Pri. (yes)\n\
658 |   -ioi 		  In-Order Issue (no)\n\
659 |   -ioc 	  In-Order Complete (no)\n\
660 |   -unidi 	  Unified Dispatch/Issue (yes)\n\
661 |   -rsrel 	  Early RS Release (yes)\n\
662 |   -mempipe 	  Pipelined Data Mempry (yes)\n\
663 |   -fw 		  Fetch Width (4)\n\
664 |   -dw 		  Decode Width (4)\n\
665 |   -pw 		  Dispatch Width (4)\n\
666 |   -iw 		  Issue Width (4)\n\
667 |   -ww 	  Write-Back Width (4)\n\
668 |   -cw 		  Commit Width (4)\n\
669 |   -wins	 		  Instruction Window Size (16)\n\
670 |   -robs	 		  Reorder Buffer Size (16)\n\
671 |   -afu	 	  Number of Int. FU (4)\n\
672 |   -alat 	  Latency of INT ALU FU (0)\n\
673 |   -ars 	  Reservation St. per FU (100)\n\
674 |   -mfu	 	  Number of Mult. FU (1)\n\
675 |   -mlat 	  Latency of Mult. FU (4)\n\
676 |   -mpipe 	  Pipelinization of Mult. (yes)\n\
677 |   -mrs 	  Reservation St. per FU (100)\n\
678 |   -dfu	 	  Number of Div. FU (1)\n\
679 |   -dlat 	  Latency of Div. FU (4)\n\
680 |   -dpipe 	  Pipelinization of Div. (yes)\n\
681 |   -drs 	  Reservation St. per FU (100)\n\
682 |   -ffu	 	  Number of FP FU (4)\n\
683 |   -xfu	 	  Number of FP Mult. FU (1)\n\
684 |   -lfu	 		  Number of Load FU (1)\n\
685 |   -llat 		  Latency of Load FU (2)\n\
686 |   -lpipe 		  Pipelinization of Load (yes)\n\
687 |   -sfu	 		  Number of Store FU (1)\n\
688 |   -slat 		  Latency of Store FU (1)\n\
689 |   -spipe 		  Pipelinization of Store (yes)\n\
690 |   -swaits 		  Store waits completion (no)\n\
691 |   -lsrs 	  Reservation St. per FU (100)\n\
692 |   -bfu	 		  Number of Branch FU (1)\n\
693 |   -blat 	  Latency of Branch FU (0)\n\
694 |   -brs 	  Reservation St. per FU (100)\n\
695 |   -lqs	 	  Load Queue Size (1)\n\
696 |   -sqs	 	  Store Queue Size (1)\n\
697 |   -spec 		  Enable Speculation (yes)\n\
698 |   -wblat	 	  Write Back Latency (0)\n\
699 |   -logfile 	  Log File (def.log)\n\
700 | \n\
701 | ");
702 |    }
703 |    ExitProg("%s", "-");
704 | }
705 | 
706 | 
707 | 


--------------------------------------------------------------------------------
/lib/sui.c:
--------------------------------------------------------------------------------
   1 | /*-----------------------------------------------------------------------------
   2 | FILE        : SUI.C
   3 | INFO        : Shell User Interface
   4 | PURPOSE     : Interface user program with shell
   5 | DEVELOPEMENT: GCC 2.6.3 && Borland C++ 3.1, Model=Large, ANSI-Keywords
   6 | CREATED BY  : RG[28-Apr-1995]
   7 | MODIFIED BY : XX[XX-XXX-XXXX]
   8 | -----------------------------------------------------------------------------*/
   9 | /*------------- LIBRARY PROCEDURES ------------------------------------------*/
  10 | #include 	/* printf(), fprintf() */
  11 | #include 	/* malloc(), free(), size_t */
  12 | #include      /* strcpy(), bzero() */
  13 | #include       /* toupper() */
  14 | #include      /* va_list, va_start() */
  15 | #include 	/* EACCES */
  16 | #include        /* localtime(), time(), asctime() */
  17 | #include 	/* signal(), SIG_DFL */
  18 | #include 	/* unlink() */
  19 | #include "sui.h"
  20 | #include "getopt1.h"
  21 | 
  22 | /*------------- GENERAL DEFINITIONS -----------------------------------------*/
  23 | #define FINI_EXTENSION	"ini"
  24 | #define FLOG_EXTENSION	"log"
  25 | #define FOUT_EXTENSION	"out"
  26 | #define	MAXBUFFERLEN	8192
  27 | 
  28 | /*------------- GLOBAL VARIABLES --------------------------------------------*/
  29 | static	const char **App;
  30 | 
  31 | static	char    errmsg[MAXLINELEN] = "";
  32 | static	int     errcod = 0;
  33 | static	char	buf[MAXBUFFERLEN] = "";
  34 | static	char	blog[MAXBUFFERLEN] = "";
  35 | static	char	bout[MAXBUFFERLEN] = "";
  36 | static	FILE	*fpini = NULL;
  37 | static	char	fininame[MAXFPNAMELEN] = "";
  38 | 
  39 | FILE	*fplog = NULL;
  40 | 
  41 | /*
  42 | static	FILE	*fpout = NULL;
  43 | static	char	foutname[MAXFPNAMELEN] = "";
  44 | */
  45 | static	FILE	*fptmp = NULL;
  46 | static	char	tlogname[L_tmpnam] = "";
  47 | static	int	detail_flag = 0;
  48 | static	long	max_allocated = 0;
  49 | static	long	cur_allocated = 0;
  50 | static	long	calls_to_Malloc = 0;
  51 | static	long	calls_to_Free = 0;
  52 | static	time_t	t0 = 0, t1 = 0;
  53 | static	int	time_counter_initialized = 0;
  54 | 
  55 | static	void (*MAINDestru)(void) = NULL;
  56 | 
  57 | static	IniT	ITAB[MAXINISECTIONS];
  58 | static	int	ITABdim = 0;
  59 | /*
  60 | static	IniSection Pro[] =
  61 | {
  62 |    "Program Defaults",          HEADER,         0,      0,      NULL,
  63 |    "Log File Name",             STRING,         0,      0,      &flogname,
  64 |    "",                          ENDING,         0,      0,      NULL
  65 | };
  66 | */
  67 | 
  68 | static FILE *Mysysfp;
  69 | static char Mysystn[MAXFILENAMELEN];
  70 | 
  71 | char	flogname[MAXFPNAMELEN] = "";
  72 | 
  73 | /*------------- INTERNAL FUNCTIONS PROTOTYPES -------------------------------*/
  74 | static	void	CmdArg(char *param, int sec);
  75 | static	void	CmdFile(FILE *handle);
  76 | static	char	*StrLower(char *s);
  77 | static	int	TransformLog(void);
  78 | static	char	*StrVal(char *s, int n, int sec, int k);
  79 | 
  80 | void sigsui(int);
  81 | void sigsui11(int);
  82 | void sigsui17(int);
  83 | 
  84 | /*------------- FUNCTION IMPLEMENTATION -------------------------------------*/
  85 | /*---------------------------------------------------------------------------*
  86 |  NAME      :
  87 |  PURPOSE   :
  88 |  PARAMETERS: None
  89 |  RETURN    : None
  90 |  *---------------------------------------------------------------------------*/
  91 | void SUIConstr(void (*md)(void), const char *app[], char *ifn)
  92 | {
  93 |    SUIConstr1(md, app, ifn, 0);
  94 | }
  95 | 
  96 | /*---------------------------------------------------------------------------*
  97 |  NAME      :
  98 |  PURPOSE   :
  99 |  PARAMETERS: None
 100 |  RETURN    : None
 101 |  *---------------------------------------------------------------------------*/
 102 | void SUIConstr1(void (*md)(void), const char *app[], char *ifn, int nolog)
 103 | {
 104 |    char aux[MAXFPNAMELEN];
 105 |    int res;
 106 |    int k;
 107 | 
 108 |    /* Setup signal handlers */
 109 |    signal(SIGSEGV, sigsui11);
 110 |    #ifndef _Linux_
 111 |       #define SIGUNUSED 31
 112 |    #else
 113 |       #define SIGUNUSED SIGSYS
 114 |    #endif
 115 |    for (k = 1; k < SIGUNUSED && k != SIGSEGV; ++k) signal(k, sigsui);
 116 | 
 117 |    MAINDestru = md;
 118 |    App = app;
 119 | 
 120 |    /*-----------------------------------*/
 121 |    /* RegisterIniSec(Pro); */
 122 | 
 123 |    /*-----------------------------------*/
 124 |    if (nolog == 0) {
 125 | /*
 126 |       tlogname[0] = '\0';
 127 |       tmpnam(tlogname);
 128 | 
 129 |       if (NULL == (fplog = fopen(tlogname, "wt")))
 130 |          ExitProg("Cannot create tmp log file '%s'.", tlogname);
 131 | */
 132 |       strcpy(tlogname, "suilibXXXXXX");
 133 |       res = mkstemp(tlogname);
 134 |       if (-1 == res)
 135 |          ExitProg("Cannot create tmp log file through mkstemp().");
 136 | 
 137 |       if (NULL == (fplog = fdopen(res, "wt")))
 138 |          ExitProg("Cannot create tmp log file '%s'.", tlogname);
 139 | /**/
 140 | 
 141 |       sprintf(buf, "___Log file created using temporary name '%s'.", tlogname);
 142 |       Log(buf);
 143 | 
 144 |       Log("Initializing.");
 145 |    }
 146 |    fininame[0] = '\0';
 147 |    /* flogname[0] = '\0'; */
 148 | 
 149 |    /*-----------------------------------*/
 150 |    if (ifn == NULL) {
 151 | /*
 152 |       strcpy(fininame, App[0]);
 153 |       strcat(fininame, ".");
 154 |       strcat(fininame, FINI_EXTENSION);
 155 |       spanfn0(aux, ".", ".", fininame);
 156 |       if (NULL == (fpini = fopen(aux, "rt")))
 157 |          ExitProg("Cannot find init file '%s'.", aux);
 158 |       CmdFile(fpini);
 159 |       fclose(fpini); fpini = NULL;
 160 | */
 161 |    } else {
 162 |       strcpy(fininame, ifn);
 163 |       strcpy(aux, ifn);
 164 |       if (NULL == (fpini = fopen(aux, "rt")))
 165 |          ExitProg("Cannot find init file '%s'.", aux);
 166 |       CmdFile(fpini);
 167 |    }
 168 | 
 169 |    /* Transform temporary log file in current log file */
 170 |    if (nolog == 0) {
 171 |       if (0 != TransformLog()) ExitProg(errmsg);
 172 |       setbuf(fplog, NULL);
 173 |    }
 174 | 
 175 |    /*-----------------------------------*/
 176 | /*
 177 |    if (*foutname == '\0') {
 178 |       strcpy(foutname, App[0]);
 179 |       strcat(foutname, ".");
 180 |       strcat(foutname, FOUT_EXTENSION);
 181 |       spanfn0(aux, ".", ".", foutname);
 182 |    } else {
 183 |       strcpy(aux, foutname);
 184 |    }
 185 |    if (NULL == (fpout = fopen(aux, "wt")))
 186 |       ExitProg("Cannot create out file '%s'.", aux);
 187 |    setbuf(fpout, NULL);
 188 | */
 189 | 
 190 |    /*-----------------------------------*/
 191 |    /* Initialize Queue Package */
 192 |    QueuePackage__Constr();
 193 | 
 194 |    /*-----------------------------------*/
 195 |    if (nolog == 0) {
 196 |       time(&t0); strftime(aux, 80, "%H:%M:%S %Z, %a %b %d %Y", localtime(&t0));
 197 |       time_counter_initialized = 1;
 198 |       Out("___Starting execution (%s).", aux);
 199 |    }
 200 | }
 201 | 
 202 | /*---------------------------------------------------------------------------*
 203 |  NAME      :
 204 |  PURPOSE   :
 205 |  PARAMETERS: None
 206 |  RETURN    : None
 207 |  *---------------------------------------------------------------------------*/
 208 | void SUIDestru(void)
 209 | {
 210 |    QueuePackage__Destru();
 211 | }
 212 | 
 213 | /*---------------------------------------------------------------------------*
 214 |  NAME      :
 215 |  PURPOSE   :
 216 |  PARAMETERS: None
 217 |  RETURN    : None
 218 |  *---------------------------------------------------------------------------*/
 219 | void sigsui(int i)
 220 | {
 221 |    ExitProg("SIGNAL %d", i);
 222 | }
 223 | 
 224 | /*---------------------------------------------------------------------------*
 225 |  NAME      :
 226 |  PURPOSE   :
 227 |  PARAMETERS: None
 228 |  RETURN    : None
 229 |  *---------------------------------------------------------------------------*/
 230 | void sigsui11(int i)
 231 | {
 232 |    ExitProg("Segment violation.");
 233 | }
 234 | 
 235 | /*---------------------------------------------------------------------------*
 236 |  NAME      :
 237 |  PURPOSE   :
 238 |  PARAMETERS: None
 239 |  RETURN    : None
 240 |  *---------------------------------------------------------------------------*/
 241 | void sigsui17(int i)
 242 | {
 243 |    ExitProg("Termination requested by user.");
 244 | }
 245 | 
 246 | /*---------------------------------------------------------------------------*
 247 |  NAME      : ExitProg
 248 |  PURPOSE   : Exit program taking some actions...
 249 |  PARAMETERS: msg - message string:
 250 | 		if null string then return immediatly
 251 | 		if string starts with '-' don't understand as error
 252 | 		otherwise print message no stderr on log it as error
 253 |  RETURN    : None
 254 |  *---------------------------------------------------------------------------*/
 255 | void ExitProg(char *fmt, ...)
 256 | {
 257 |    int		k, n;
 258 |    va_list	ap;
 259 | 
 260 |    va_start(ap, fmt);
 261 |    vsprintf(buf, fmt, ap);
 262 |    switch (buf[0])
 263 |    {
 264 |       case '\0':
 265 | 	 return;
 266 |       case '-':
 267 | 	 /* kindly exit printing an information message */
 268 | 	 strncpy(errmsg, buf, MAXLINELEN - 2); 
 269 |          errmsg[MAXLINELEN - 2] = '\0'; 
 270 | 	 n = 0;
 271 | 	 break;
 272 |       default:
 273 | 	 /* Set errmsg to at most MAXLINELEN-2 char of msg; pad with spaces */
 274 | 	    strncpy(errmsg, buf, MAXLINELEN - 2); 
 275 |             errmsg[MAXLINELEN - 2] = '\0'; 
 276 |   	 /* for (k = strlen(buf); k < MAXLINELEN - 2; ++k) errmsg[k] = ' '; 
 277 | 	    strcat(errmsg, "\n"); 
 278 | 	    fprintf(stderr, "%s", errmsg); */
 279 | 	 Display("ERROR: %s", errmsg);
 280 |          errcod = 1;
 281 | /*
 282 |          Display(errmsg);
 283 | */
 284 | 	 n = -1;
 285 | 	 break;
 286 |    }
 287 | 
 288 |    if (time_counter_initialized == 1)
 289 |    {
 290 |       int d, h, m, s, x;
 291 |       long dt;
 292 | 
 293 |       time(&t1); strftime(buf, 80, "%H:%M:%S %Z, %a %b %d %Y", localtime(&t1));
 294 |       dt = t1 - t0;
 295 |       d = dt / 86400UL; x = dt % 86400UL;
 296 |       h = x / 3600;   x = x % 3600; 
 297 |       m = x / 60;     s = x % 60;
 298 |       Out("___Ending execution   (%s).", buf);
 299 |       Display("___Total execution_time   = %ld s    (%dd %dh %dm %ds).",
 300 |          dt, d, h, m, s);
 301 |    }
 302 | 
 303 |    /* Call all destructors */
 304 |    if (MAINDestru != NULL) MAINDestru();
 305 |    if (fpini != NULL) fclose(fpini);
 306 | /*
 307 |    if (fpout != NULL) fclose(fpout);
 308 | */
 309 | 
 310 |    sprintf(buf, "Maximum allocated memory: %ldK.", max_allocated >> 10);
 311 |    Out(buf);
 312 |    sprintf(buf, "Malloc/Free = %ld/%ld.", calls_to_Malloc, calls_to_Free);
 313 |    Out(buf);
 314 | 
 315 |    /* Maybe that only temporary log file was created but not renamed */
 316 |    if (*tlogname != '\0') if (0 != TransformLog()) printf("%s", errmsg);
 317 | 
 318 |    Log("Exiting program.");
 319 |    if (n == 0) {
 320 |       if (buf[1] != '\0') {
 321 |          if (fplog) { Log("%s", errmsg + 1); }
 322 |          else { printf("%s\n", errmsg + 1); }
 323 |       }
 324 |    }
 325 | 
 326 |    if (fplog != NULL) { fclose(fplog); fplog = NULL; }
 327 |    va_end(ap);
 328 | 
 329 |    exit(n);
 330 | }
 331 | 
 332 | /*---------------------------------------------------------------------------*
 333 |  NAME      :
 334 |  PURPOSE   :
 335 |  PARAMETERS:
 336 |  RETURN    : None
 337 |  *---------------------------------------------------------------------------*/
 338 | int RegisterIniSec(IniSection *isp)
 339 | {
 340 |    if (ITABdim < MAXINISECTIONS - 1)
 341 |    {
 342 |       ITAB[ITABdim++] = isp;
 343 |    }
 344 |    return (0);
 345 | }
 346 | 
 347 | /*---------------------------------------------------------------------------*
 348 |  NAME      : CmdArg
 349 |  PURPOSE   : Processes a single command-line/command-file argument
 350 | 	     isolate 'variable=value' (or 'variable:=value') into
 351 | 	     its components and process it.
 352 | 	     All components have already been converted to lower case.
 353 |  PARAMETERS:
 354 |  RETURN    : None
 355 |  *---------------------------------------------------------------------------*/
 356 | void CmdArg(char *param, int sec)
 357 | {
 358 |    char	variable[MAXIDNAMELEN];	/* variable name goes here */
 359 |    char	value[MAXIDVALLEN];	/* variable value goes here*/
 360 |    long	numval;			/* numeric value of arg    */
 361 |    char	charval;		/* character value of arg  */
 362 |    int	f, j, k = 0;		/* temporary loop counters */
 363 | 
 364 |    /* Get variable name */
 365 |    for (j = 1; j < strlen(param) && param[j] != '='; j++);
 366 |    f = j + 1;
 367 |    if (j >= MAXIDNAMELEN || j >= strlen(param))
 368 |       ExitProg("'=' not found in argument '%s' of file '%s'.", param, fininame);
 369 |       						/* '=' not found             */
 370 |    strncpy(variable, param, j--);	        /* get the variable name     */
 371 |    /* Strip any trailing ':' or space or tab */
 372 |    while (j > 0 && (variable[j] == ':') || variable[j] <= ' ') --j;
 373 |    variable[++j] = '\0';	                /* truncate it               */
 374 | 
 375 |    /* Get the value string */
 376 |    while (param[f] <= ' ') ++f;			/* strip leading space or tab*/
 377 |    strcpy(value, ¶m[f]);
 378 |    /* Strip any trailing space or tab */
 379 |    for (j = 0; j < strlen(value) && value[j] != ';'; ++j);
 380 |    --j;
 381 |    while (j > 0 && value[j] <= ' ') --j;
 382 |    value[++j] = '\0';		                /* truncate it               */
 383 |    sscanf(value, "%ld", &numval);		/* get any numeric value     */
 384 |    charval = value[0];				/* get any letter  value     */
 385 | 
 386 |    /* Do associated action */
 387 |    for (k = 0; ITAB[sec][k].vartype != ENDING; ++k)
 388 |    {
 389 |       if (0 == strcmp(ITAB[sec][k].varname, variable))
 390 |       {
 391 |          switch (ITAB[sec][k].vartype)
 392 |          {
 393 |             case STRING:
 394 |                strcpy((char *)(ITAB[sec][k].value), value);
 395 |                break;
 396 |             case NUMVAL:
 397 |                if (numval < ITAB[sec][k].minval 
 398 |                   || numval > ITAB[sec][k].maxval)
 399 |                {
 400 |                   char aux[MAXBUFFERLEN];
 401 | 
 402 |                   sprintf(aux, "Value of '%s' must be ", variable);
 403 |                   if (ITAB[sec][k].minval != -LINF)
 404 |                      sprintf(aux + strlen(aux), "more than %ld", 
 405 |                         ITAB[sec][k].minval - 1);
 406 |                   if (ITAB[sec][k].minval != -LINF 
 407 |                      && ITAB[sec][k].maxval != LINF)
 408 |                         sprintf(aux + strlen(aux), " and " );
 409 |                   if (ITAB[sec][k].maxval != LINF)
 410 |                      sprintf(aux + strlen(aux), "less than %ld",
 411 |                         ITAB[sec][k].minval + 1);
 412 |                   sprintf(aux + strlen(aux), " in file '%s'.", fininame);
 413 |                   ExitProg(aux );
 414 |                }
 415 |                *((long *)(ITAB[sec][k].value)) = numval;
 416 |                break;
 417 |             case CHRVAL:
 418 |                *((char *)(ITAB[sec][k].value)) = charval;
 419 |                break;
 420 |             case YES_NO:
 421 |                StrLower(value);
 422 |                if 
 423 |                   (0 == strcmp(value, "yes") || charval == 'y') 
 424 | 		  {
 425 |                      *((int *)(ITAB[sec][k].value)) = 1;
 426 |                   }
 427 |                else if 
 428 |                   (0 == strcmp(value, "no")  || charval == 'n') 
 429 | 		  {
 430 |                      *((int *)(ITAB[sec][k].value)) = 0;
 431 |                   }
 432 |                else
 433 |                   ExitProg("Bad init value '%s' in file '%s'.", param,
 434 |                      fininame);
 435 |                break; 
 436 |             default:
 437 |                ExitProg("Bad init argument '%s' in file '%s'.", param, 
 438 |                      fininame);
 439 |          }
 440 |          break;
 441 |       }
 442 |    }
 443 |    if (ITAB[sec][k].vartype == ENDING) 
 444 |    {
 445 |       ExitProg("Argument unknown '%s' in file '%s'.", param, fininame);
 446 |    }
 447 | }
 448 | 
 449 | /*---------------------------------------------------------------------------*
 450 |  NAME      :
 451 |  PURPOSE   : Processes a single command-file. If (inifile), it looks
 452 | 	     for '[...]' codes as well
 453 |  PARAMETERS:
 454 |  RETURN    : None
 455 |  *---------------------------------------------------------------------------*/
 456 | void CmdFile(FILE *fp)
 457 | {
 458 |    char	line[MAXBUFFERLEN + 1];
 459 |    int	toolsection = 1;
 460 |    int	i, j, k;
 461 | 
 462 |    while (fgets(line, MAXBUFFERLEN, fp) != NULL)
 463 |    {          					/* read thru a line at a time*/
 464 |       /* Strip trailing \n */
 465 |       i = strlen(line);
 466 |       if (i > 0) { if (line[i - 1] == '\n') line[i - 1] = '\0'; }
 467 |       else line[i + 1] = 0;			/* add second null   	     */
 468 | 
 469 |       /* Is it a section header? */
 470 |       if (line[0] == '[')
 471 |       {
 472 | 	 toolsection = 0;
 473 | 	 i = strchr(line, ']') - line - 1;
 474 |          for (k = 0; k < ITABdim; ++k)
 475 |          {
 476 |             if (0 == strncmp(line + 1, ITAB[k][0].varname, i))
 477 |             {
 478 |                toolsection = k + 1; break;
 479 |             }
 480 |          }
 481 | 	 continue;				/* skip this line in any case*/
 482 |       }
 483 | 
 484 |       if (! toolsection) continue;		/* not our section	     */
 485 | 
 486 |       i = -1;					/* get a running start	     */
 487 |       while (line[++i] != '\0')
 488 |       {		                      		/* scan through the line     */
 489 | 	 if (line[i] <= ' ') continue;          /* white space or tabs	     */
 490 | 	 if (line[i] == ';') break;             /* comments		     */
 491 | 	 j = i;	        			/* argument starts here	     */
 492 | 	 while (line[++i] != '\0');		/* find the argument end     */
 493 | 	 CmdArg(&line[j], toolsection - 1);	/* process the argument      */
 494 |       }
 495 |    }
 496 | }
 497 | 
 498 | /*---------------------------------------------------------------------------*
 499 |  NAME      :
 500 |  PURPOSE   :
 501 |  PARAMETERS:
 502 |  RETURN    :
 503 |  *---------------------------------------------------------------------------*/
 504 | char *StrLower(char *s)
 505 | {
 506 |    char *p = s;
 507 | 
 508 |    while (*p != '\0') { *p = tolower(*p); ++p; }
 509 |    return (s);
 510 | }
 511 | 
 512 | /*---------------------------------------------------------------------------*
 513 |  NAME      :
 514 |  PURPOSE   :
 515 |  PARAMETERS: None
 516 |  RETURN    : None
 517 |  *---------------------------------------------------------------------------*/
 518 | int Display(char *fmt, ...)
 519 | {
 520 |    va_list	ap;
 521 |    int		res;
 522 | 
 523 |    va_start(ap, fmt);
 524 |    if (errcod == 0) {
 525 |       vsprintf(buf, fmt, ap);
 526 |       res = printf("%s\n", buf);
 527 |       if (fplog) res = fprintf(fplog, "%s\n", buf);
 528 |    }
 529 |    va_end(ap);
 530 | 
 531 |    return (res);
 532 | }
 533 | 
 534 | /*---------------------------------------------------------------------------*
 535 |  NAME      :
 536 |  PURPOSE   :
 537 |  PARAMETERS:
 538 |  RETURN    : None
 539 |  *---------------------------------------------------------------------------*/
 540 | int DisplayOut(char *fmt, ...)
 541 | {
 542 |    va_list	ap;
 543 |    int		res = -1;
 544 | 
 545 |    va_start(ap, fmt);
 546 |    vsprintf(bout, fmt, ap);
 547 |    printf("%s\n", bout);
 548 |    if (fplog) fprintf(fplog, "%s\n", bout);
 549 | /*
 550 |    if (fpout) res = fprintf(fpout, "%s\n", bout);
 551 | */
 552 |    va_end(ap);
 553 | 
 554 |    return (res);
 555 | }
 556 | 
 557 | /*---------------------------------------------------------------------------*
 558 |  NAME      :
 559 |  PURPOSE   :
 560 |  PARAMETERS:
 561 |  RETURN    : None
 562 |  *---------------------------------------------------------------------------*/
 563 | int Out(char *fmt, ...)
 564 | {
 565 |    va_list	ap;
 566 |    int		res = -1;
 567 | 
 568 |    va_start(ap, fmt);
 569 |    vsprintf(bout, fmt, ap);
 570 |    if (fplog) fprintf(fplog, "%s\n", bout);
 571 | /*
 572 |    if (fpout) res = fprintf(fpout, "%s\n", bout);
 573 | */
 574 |    va_end(ap);
 575 | 
 576 |    return (res);
 577 | }
 578 | 
 579 | /*---------------------------------------------------------------------------*
 580 |  NAME      :
 581 |  PURPOSE   :
 582 |  PARAMETERS:
 583 |  RETURN    : None
 584 |  *---------------------------------------------------------------------------*/
 585 | int Log(char *fmt, ...)
 586 | {
 587 |    va_list	ap;
 588 |    int		res = -1;
 589 | 
 590 |    va_start(ap, fmt);
 591 |    vsprintf(blog, fmt, ap);
 592 |    if (fplog) res = fprintf(fplog, "%s\n", blog);
 593 |    va_end(ap);
 594 | 
 595 |    return (res);
 596 | }
 597 | 
 598 | /*---------------------------------------------------------------------------*
 599 |  NAME      :
 600 |  PURPOSE   :
 601 |  PARAMETERS:
 602 |  RETURN    : None
 603 |  *---------------------------------------------------------------------------*/
 604 | int FileOut(FILE *fp, char *fmt, ...)
 605 | {
 606 |    va_list	ap;
 607 |    int		res = -1;
 608 | 
 609 |    va_start(ap, fmt);
 610 |    vsprintf(buf, fmt, ap);
 611 |    if (fp) fprintf(fp, "%s\n", buf);
 612 | /*
 613 |    if (fpout) res = fprintf(fpout, "%s\n", buf);
 614 | */
 615 |    if (fplog) res = fprintf(fplog, "%s\n", buf);
 616 |    va_end(ap);
 617 | 
 618 |    return (res);
 619 | }
 620 | 
 621 | /*---------------------------------------------------------------------------*
 622 |  NAME      :
 623 |  PURPOSE   :
 624 |  PARAMETERS: None
 625 |  RETURN    : None
 626 |  *---------------------------------------------------------------------------*/
 627 | void *Malloc(unsigned long size)
 628 | {
 629 |    void *p;
 630 | 
 631 |    p = malloc((size_t)size);
 632 |    if (p != NULL) cur_allocated += size;
 633 |    if (cur_allocated >= max_allocated) max_allocated = cur_allocated;
 634 | 
 635 |    if (p == NULL) 
 636 |       ExitProg("Failed to allocate %ldK (%ldK).", 
 637 |          size >> 10, max_allocated >> 10);
 638 |    ++calls_to_Malloc;
 639 | 
 640 |    /* Initialize to zero the allocated memory */
 641 |    bzero(p, size);
 642 | 
 643 |    return(p);
 644 | }
 645 | 
 646 | /*---------------------------------------------------------------------------*
 647 |  NAME      :
 648 |  PURPOSE   :
 649 |  PARAMETERS: None
 650 |  RETURN    : None
 651 |  *---------------------------------------------------------------------------*/
 652 | void *Calloc(unsigned long nmemb, unsigned long size)
 653 | {
 654 |    void *p;
 655 | 
 656 |    p = calloc((size_t)nmemb, (size_t)size);
 657 |    if (p != NULL) cur_allocated += size * nmemb;
 658 |    if (cur_allocated >= max_allocated) max_allocated = cur_allocated;
 659 | 
 660 |    if (p == NULL) 
 661 |       ExitProg("Failed to allocate %ldK (%ldK).", 
 662 |          size >> 10, max_allocated >> 10);
 663 |    ++calls_to_Malloc;
 664 | 
 665 |    return(p);
 666 | }
 667 | 
 668 | /*---------------------------------------------------------------------------*
 669 |  NAME      :
 670 |  PURPOSE   :
 671 |  PARAMETERS: None
 672 |  RETURN    : None
 673 |  *---------------------------------------------------------------------------*/
 674 | void Free(void *block)
 675 | {
 676 |     if (block != NULL) {
 677 |        ++calls_to_Free;
 678 |        /* for now don't decrement cur_allocated */
 679 |        free(block);
 680 |     }
 681 | }
 682 | 
 683 | /*---------------------------------------------------------------------------*
 684 |  NAME      :
 685 |  PURPOSE   :
 686 |  PARAMETERS: None
 687 |  RETURN    : 0 if successful, -1 otherwise
 688 |  *---------------------------------------------------------------------------*/
 689 | int TransformLog(void)
 690 | {
 691 |    /* Make sure that flogname is set */
 692 |    if (*flogname == '\0')
 693 |    {
 694 |       strncpy(flogname, App[0], MAXFPNAMELEN - 5);
 695 |       flogname[MAXFPNAMELEN - 6] = '\0';
 696 |       strcat(flogname, ".");
 697 |       strcat(flogname, FLOG_EXTENSION);
 698 |    }
 699 | 
 700 |    /* Remove eventual old log file */
 701 |    if (EACCES == remove(flogname))
 702 |    {
 703 |       sprintf(errmsg, "Permission denied removing old log file '%s'.",
 704 | 	 flogname);
 705 |       return (-1);
 706 |    }
 707 | 
 708 |    /* Close current log file whose name is temporary to flush buffers */
 709 |    if (fplog != NULL) fclose(fplog);
 710 | 
 711 |    /* Create new log file now that i have its name */
 712 |    if (NULL == (fplog = fopen(flogname, "wt")))
 713 |    {
 714 |       sprintf(errmsg, "Cannot create log file '%s'.", flogname);
 715 |       return (-1);
 716 |    }
 717 | 
 718 |    /* Reopen temporary log file */
 719 |    if (NULL == (fptmp = fopen(tlogname, "rt")))
 720 |    {
 721 |       sprintf(errmsg, "Cannot reopen tmp log file '%s'.", tlogname);
 722 |       return (-1);
 723 |    }
 724 | 
 725 |    /* Copy temporary content to new log file */
 726 |    while (NULL != fgets(buf, MAXBUFFERLEN - 1, fptmp)) fputs(buf, fplog);
 727 | 
 728 |    /* Close temporary file and remove it */
 729 |    if (fptmp != NULL) fclose(fptmp);
 730 |    if (EACCES == remove(tlogname))
 731 |    {
 732 |       sprintf(errmsg, "Permission denied removing tmp log file '%s'.",
 733 | 	 tlogname);
 734 |       return (-1);
 735 |    }
 736 |    tlogname[0] = '\0';
 737 | 
 738 |    return (0);
 739 | }
 740 | 
 741 | /*---------------------------------------------------------------------------*
 742 |  NAME      :
 743 |  PURPOSE   :
 744 |  PARAMETERS:
 745 |  RETURN    : 
 746 |  *---------------------------------------------------------------------------*/
 747 | void GenIniTemplate(void)
 748 | {
 749 |    int sec, k;
 750 |    char aux[MAXLINELEN];
 751 |    char fn[MAXFILENAMELEN];
 752 |    FILE *fp;
 753 | 
 754 |    strncpy(fn, App[0], MAXFPNAMELEN - 5);
 755 |    fn[MAXFPNAMELEN - 6] = '\0';
 756 |    strcat(fn, ".");
 757 |    strcat(fn, "tem");
 758 |    if (NULL == (fp = fopen(fn, "wt"))) {
 759 |       ExitProg("Cannot create template file '%s'.", fn);
 760 |    }
 761 | 
 762 |    for (sec = 0; sec < ITABdim; ++sec)
 763 |    {
 764 |       fprintf(fp, "[%s]\n", ITAB[sec][0].varname);
 765 |       for (k = 1; ITAB[sec][k].vartype != ENDING; ++k) {
 766 |          fprintf(fp, "%-22s = %s\n", ITAB[sec][k].varname, 
 767 |             StrVal(aux, MAXLINELEN, sec, k));
 768 |       }
 769 |       fprintf(fp, "\n");
 770 |    }
 771 | 
 772 |    fclose(fp);
 773 | 
 774 |    printf("Template file is %s\n", fn);
 775 | }
 776 | 
 777 | /*---------------------------------------------------------------------------*
 778 |  NAME      :
 779 |  PURPOSE   :
 780 |  PARAMETERS:
 781 |  RETURN    : 
 782 |  *---------------------------------------------------------------------------*/
 783 | void LogIniParm(void)
 784 | {
 785 |    int sec, k;
 786 |    char aux[MAXLINELEN];
 787 | 
 788 |    Display("\nLIST OF INITALIZATION PARAMETERS");
 789 |    for (sec = 0; sec < ITABdim; ++sec)
 790 |    {
 791 |       Display("--------------------------------------------[%s]", 
 792 |          ITAB[sec][0].varname);
 793 |       for (k = 1; ITAB[sec][k].vartype != ENDING; ++k)
 794 |          Display("%-22s = %s", ITAB[sec][k].varname, 
 795 |             StrVal(aux, MAXLINELEN, sec, k));
 796 |    }
 797 |    Display("--------------------------------------------"); 
 798 | }
 799 | 
 800 | /*---------------------------------------------------------------------------*
 801 |  NAME      :
 802 |  PURPOSE   :
 803 |  PARAMETERS:
 804 |  RETURN    : 
 805 |  *---------------------------------------------------------------------------*/
 806 | char *StrVal(char *s, int n, int sec, int k)
 807 | {
 808 |    switch(ITAB[sec][k].vartype)
 809 |    {
 810 |       case STRING:
 811 |          strncpy(s, (char *)(ITAB[sec][k].value), n - 1);
 812 | 	 s[MAXLINELEN - 1] = '\0';
 813 | 	 break;
 814 |       case NUMVAL:
 815 | 	 sprintf(s, "%d", *((int *)(ITAB[sec][k].value)));
 816 | 	 break;
 817 |       case LNUMVAL:
 818 | 	 sprintf(s, "%ld", *((long *)(ITAB[sec][k].value)));
 819 | 	 break;
 820 |       case CHRVAL:
 821 | 	 sprintf(s, "%c", *((char *)(ITAB[sec][k].value)));
 822 | 	 break;
 823 |       case YES_NO:
 824 | 	 sprintf(s, "%s", *((int *)(ITAB[sec][k].value)) ? "yes" : "no ");
 825 | 	 break;
 826 |       default:
 827 | 	 s[0] = '\0';
 828 | 	 break;
 829 |    }
 830 |    return (s);
 831 | }
 832 | 
 833 | /*---------------------------------------------------------------------------*
 834 |  NAME      :
 835 |  PURPOSE   :
 836 |  PARAMETERS:
 837 |  RETURN    : 
 838 |  *---------------------------------------------------------------------------*/
 839 | FILE *FOpen(const char *fname, const char *mode, int (**fc)(FILE *))
 840 | {
 841 |    FILE *fp;
 842 |    char GZcmd[2 * MAXFPNAMELEN];
 843 |    FILE *(*fo)(const char *, const char *);
 844 | 
 845 |    /* Verify if input file can be open */
 846 |    if (NULL == (fp = fopen(fname, mode)))
 847 |    {
 848 |       perror("FOpen");
 849 |       ExitProg("Cannot open file '%s'.", fname);
 850 |    }
 851 |    else
 852 |    {
 853 |       fclose(fp);
 854 |    }
 855 | 
 856 |    GZcmd[0] = '\0';
 857 |    if (0 == strcmp(fname + strlen(fname) - 2, "gz"))
 858 |    {
 859 |       #ifdef __BORLANDC__
 860 |       ExitProg("POpen not supported, .gz must be expanded.");
 861 |       #else
 862 |       if (0 == strcmp(mode, "r"))
 863 |          strcpy(GZcmd, "exec gzip -dc ");
 864 |       else
 865 |          strcpy(GZcmd, "exec gzip -c >");
 866 |       strncat(GZcmd, fname, 2*MAXFPNAMELEN-1); ; GZcmd[2*MAXFPNAMELEN-1]='\0';
 867 |       strncat(GZcmd, NULDEV, 2*MAXFPNAMELEN-1); ; GZcmd[2*MAXFPNAMELEN-1]='\0';
 868 |    
 869 |       fo = POPEN;
 870 |       *fc = PCLOSE;
 871 |       #endif
 872 |    }
 873 |    else if (0 == strcmp(fname + strlen(fname) - 3, "bz2"))
 874 |    {
 875 |       #ifdef __BORLANDC__
 876 |       ExitProg("POpen not supported, .bz2 must be expanded.");
 877 |       #else
 878 |       if (0 == strcmp(mode, "r"))
 879 |          strcpy(GZcmd, "exec bzip2 -dc ");
 880 |       else
 881 |          strcpy(GZcmd, "exec bzip2 -c >");
 882 |       strncat(GZcmd, fname, 2*MAXFPNAMELEN-1); ; GZcmd[2*MAXFPNAMELEN-1]='\0';
 883 |       strncat(GZcmd, NULDEV, 2*MAXFPNAMELEN-1); ; GZcmd[2*MAXFPNAMELEN-1]='\0';
 884 |    
 885 |       fo = POPEN;
 886 |       *fc = PCLOSE;
 887 |       #endif
 888 |    }
 889 |    else
 890 |    {
 891 |       strncat(GZcmd, fname, 2*MAXFPNAMELEN-1); ; GZcmd[2*MAXFPNAMELEN-1]='\0';
 892 |       fo = fopen;
 893 |       *fc = fclose;
 894 |    }
 895 | 
 896 |    /* Open file */
 897 |    if (NULL == (fp = fo(GZcmd, mode)))
 898 |    {
 899 |       perror("FOpen");
 900 |       ExitProg("Cannot do '%s'.", GZcmd);
 901 |    }
 902 |    Log("FOpen: '%s'.", GZcmd);
 903 | 
 904 |    return (fp);
 905 | }
 906 | 
 907 | /*---------------------------------------------------------------------------*
 908 |  NAME      :
 909 |  PURPOSE   : Get the i-th token into a string list
 910 |  PARAMETERS:
 911 |  RETURN    : 1 if token found, 0 if not found
 912 |  *---------------------------------------------------------------------------*/
 913 | int GetToken(char *str, int i, char *buf)
 914 | {
 915 |    char aux[MAXFPNAMELEN];
 916 |    char *p;
 917 |    int j = 0, r = 0;
 918 | 
 919 |    strcpy(aux, str);
 920 |    p = aux;
 921 |    if (*p != '{') {
 922 |       if (i == 1) {
 923 |          strcpy(buf, p); r = 1;
 924 |       }
 925 |    } else {
 926 |       p = strtok(aux, "{,}");
 927 |       for (j = 1; j < i && p != NULL; ++j) {
 928 |          p = strtok(NULL, ",}");
 929 |       }
 930 |       if (j == i && p != NULL) { strcpy(buf, p); r = 1; }
 931 |    }
 932 | 
 933 |    return (r);
 934 | }
 935 | 
 936 | /*---------------------------------------------------------------------------*
 937 |  NAME      :
 938 |  PURPOSE   : Check if string is a numeric int value
 939 |  PARAMETERS:
 940 |  RETURN    : 1 if found and v contains the value, 0 otherwise
 941 |  *---------------------------------------------------------------------------*/
 942 | int IsNumVal(char *str, int *v)
 943 | {
 944 |    char *c = str;
 945 |    int r = 0, l1, l2 = 0;
 946 |    uint t = 0;
 947 |    int sign = 1;
 948 |    
 949 |    l1 = strlen(str);
 950 |    while ((*c < '0' || *c > '9') && (*c != 0)) {
 951 |       if (*c == '-') { sign = -1; ++l2; } 
 952 |       if (*c == '+') { sign = 1; ++l2; }
 953 |       ++c;
 954 |    }
 955 |    while (*c >= '0' && *c <= '9')
 956 |    {
 957 |       t = t * 10 + *c - '0';
 958 |       ++c;
 959 |       ++l2;
 960 |    }
 961 |    if (l1 == l2 && l2 != 0) { r = 1; *v = sign * t; }
 962 | 
 963 |    return (r);
 964 | }
 965 | 
 966 | /*---------------------------------------------------------------------------*
 967 |  NAME      :
 968 |  PURPOSE   : Check if string is a numeric unsigned int value
 969 |  PARAMETERS:
 970 |  RETURN    : 1 if found and v contains the value, 0 otherwise
 971 |  *---------------------------------------------------------------------------*/
 972 | int IsUNumVal(char *str, uint *v)
 973 | {
 974 |    char *c = str;
 975 |    int r = 0, l1, l2 = 0;
 976 |    uint t = 0;
 977 |    
 978 |    l1 = strlen(str);
 979 |    while ((*c < '0' || *c > '9') && (*c != 0)) ++c;
 980 |    while (*c >= '0' && *c <= '9')
 981 |    {
 982 |       t = t * 10 + *c - '0';
 983 |       ++c;
 984 |       ++l2;
 985 |    }
 986 |    if (l1 == l2 && l2 != 0) { r = 1; *v = t; }
 987 | 
 988 |    return (r);
 989 | }
 990 | 
 991 | /*---------------------------------------------------------------------------*
 992 |  NAME      :
 993 |  PURPOSE   : Check if string is a numeric int value
 994 |  PARAMETERS:
 995 |  RETURN    : 1 if found and v contains the value, 0 otherwise
 996 |  *---------------------------------------------------------------------------*/
 997 | int IsLNumVal(char *str, ulng *v)
 998 | {
 999 |    char *c = str;
1000 |    int r = 0, l1, l2 = 0;
1001 |    ulng t = 0;
1002 |    
1003 |    l1 = strlen(str);
1004 |    while ((*c < '0' || *c > '9') && (*c != 0)) ++c;
1005 |    while (*c >= '0' && *c <= '9')
1006 |    {
1007 |       t = t * 10 + *c - '0';
1008 |       ++c;
1009 |       ++l2;
1010 |    }
1011 |    if (l1 == l2 && l2 != 0) { r = 1; *v = t; }
1012 | 
1013 |    return (r);
1014 | }
1015 | 
1016 | /*---------------------------------------------------------------------------*
1017 |  NAME      :
1018 |  PURPOSE   :
1019 |  PARAMETERS:
1020 |  RETURN    :
1021 |  *---------------------------------------------------------------------------*/
1022 | void Mysysopen(char *strin)
1023 | {
1024 | #ifdef __EMSCRIPTEN__
1025 |   // In WebAssembly (Node.js or Browser), no system() available.
1026 |   // Directly open the input file as Mysysfp.
1027 |   Mysysfp = fopen("/program-ex1", "r"); // hard-coded embedded file
1028 |   if (Mysysfp == NULL) {
1029 |     ExitProg("Mysysopen: Failed to open /program-ex1 in Emscripten virtual FS.");
1030 |   }
1031 | #else
1032 |   char aaa[10*MAXLINELEN];
1033 |   int res1, res2;
1034 | 
1035 |   strcpy(Mysystn, "suigenXXXXXX");
1036 |   res1 = mkstemp(Mysystn);
1037 |   if (-1 == res1)
1038 |     ExitProg("Mysysopen: Cannot create tmp file through mkstemp().");
1039 | 
1040 |   sprintf(aaa, "%s; set| cat >>%s", strin, Mysystn);
1041 |   res2 = system(aaa);
1042 |   Mysysfp = fdopen(res1, "rt");
1043 | #endif
1044 | }
1045 | 
1046 | /*---------------------------------------------------------------------------*
1047 |  NAME      :
1048 |  PURPOSE   :
1049 |  PARAMETERS:
1050 |  RETURN    :
1051 |  *---------------------------------------------------------------------------*/
1052 | void Mysysclose(void)
1053 | {
1054 |    if (Mysysfp != NULL) fclose(Mysysfp);
1055 | #ifndef __EMSCRIPTEN__
1056 |    unlink(Mysystn);
1057 | #endif
1058 | }
1059 | 
1060 | /*---------------------------------------------------------------------------*
1061 |  NAME      :
1062 |  PURPOSE   : resu is assigned only if the key is found
1063 |  PARAMETERS:
1064 |  RETURN    :
1065 |  *---------------------------------------------------------------------------*/
1066 | void Mysyspars(char *resu, char *key)
1067 | {
1068 |    char ccc[10*MAXLINELEN];
1069 |    char vvv[10*MAXLINELEN];
1070 |    char aux[10*MAXLINELEN];
1071 |    char c[2] = "x";
1072 |    size_t cnt;
1073 | 
1074 |    /* printf("SUI: key=%s\n", key); */
1075 |    aux[0] = '\0';
1076 |    fseek(Mysysfp, 0L, SEEK_SET);
1077 | //   while (!feof(Mysysfp)) {
1078 | //      cnt = fread(c, 1, 1, Mysysfp);
1079 | //      if (cnt != 1)
1080 | //         ExitProg("Mysyspars: Error while reading from Mysysfp.");
1081 |     while ((cnt = fread(c, 1, 1, Mysysfp)) == 1) {
1082 |       if (*c != '=' && *c != '\n') {
1083 |          strcat(aux, c);
1084 |       }
1085 |       if (*c == '=') {
1086 |          strcpy(ccc, aux);
1087 |          aux[0] = '\0';
1088 |       }
1089 |       if (*c == '\n') {
1090 |          strcpy(vvv, aux);
1091 |          aux[0] = '\0';
1092 |          if (0 == strcmp(key, ccc)) {
1093 |             strcpy(resu, vvv);
1094 |             /* printf("SUI: val=%s\n", vvv); */
1095 |             break;
1096 |          }
1097 |       }
1098 |    }
1099 | }
1100 | 


--------------------------------------------------------------------------------