cpprisc16  June 16, 2020
cpprisc16.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 
3 /** \file cpprisc16/cpprisc16.cpp (March 15, 2017)
4  * \brief Instructions set of RiSC16.
5  *
6  * Piece of cpprisc16.
7  * https://bitbucket.org/OPiMedia/cpprisc16
8  *
9  * GPLv3 --- Copyright (C) 2017 Olivier Pirson
10  * http://www.opimedia.be/
11  */
12 
13 #include "cpprisc16.hpp"
14 
15 #include <cstdlib>
16 
17 #include <algorithm>
18 #include <bitset>
19 #include <iomanip>
20 #include <ios>
21 #include <iostream>
22 
23 
24 namespace cpprisc16 {
25  /* ******************
26  * Global constants *
27  ********************/
28  const unsigned int nb_registers = 8;
29 
30  const unsigned int size_memory = 256;
31 
32 
33 
34  /* ******************
35  * Global variables *
36  ********************/
37  unsigned int after_last_memory_acceded = 0;
38 
40 
41  uint64_t nb_executed = 0;
42 
43  word16_t registers[8] = {0};
44 
45 
46 
47  /* ***********************************
48  * Functions for RiSC16 instructions *
49  *************************************/
50  void
51  i_add(unsigned int result, unsigned int a, unsigned int b) {
52  assert(result < nb_registers);
53  assert(a < nb_registers);
54  assert(b < nb_registers);
55 
56  registers[result] = registers[a] + registers[b];
57  registers[0] = 0;
58 
59  ++nb_executed;
60  }
61 
62 
63  void
64  i_addi(unsigned int result, unsigned int a, immed_t immed6) {
65  assert(result < nb_registers);
66  assert(a < nb_registers);
67  assert(immed6 <= 0x3F);
68 
69  registers[result] = registers[a] + immed6;
70  registers[0] = 0;
71 
72  ++nb_executed;
73  }
74 
75 
76  void
77  i_jalr(unsigned int result, unsigned int a) {
78  assert(result < nb_registers);
79  assert(a < nb_registers);
80 
81  std::cout << "i_jalr() and p_reset() are NOT implemented!";
82  println_all();
83 
84  ++nb_executed;
85 
86  exit(1);
87  }
88 
89 
90  void
91  i_lui(unsigned int result, immed_t immed10) {
92  assert(result < nb_registers);
93  assert(immed10 <= 0x3FF);
94 
95  registers[result] = (immed10 << 6);
96  registers[0] = 0;
97 
98  ++nb_executed;
99  }
100 
101 
102  void
103  i_lw(unsigned int result, unsigned int a, immed_t immed6) {
104  assert(result < nb_registers);
105  assert(a < nb_registers);
106  assert(immed6 <= 0x3F);
107 
108  const unsigned int i = registers[a] + immed6;
109 
110  assert(i < size_memory);
111 
112  registers[result] = memory[i];
113  after_last_memory_acceded = std::max(after_last_memory_acceded, i + 1);
114 
115  ++nb_executed;
116  }
117 
118 
119  void
120  i_nand(unsigned int result, unsigned int a, unsigned int b) {
121  assert(result < nb_registers);
122  assert(a < nb_registers);
123  assert(b < nb_registers);
124 
125  registers[result] = ~(registers[a] & registers[b]);
126  registers[0] = 0;
127 
128  ++nb_executed;
129  }
130 
131 
132  void
133  i_sw(unsigned int a, unsigned int result, immed_t immed6) {
134  assert(result < nb_registers);
135  assert(a < nb_registers);
136  assert(immed6 <= 0x3F);
137 
138  const unsigned int i = registers[result] + immed6;
139 
140  assert(i < size_memory);
141 
142  memory[i] = registers[a];
143  after_last_memory_acceded = std::max(after_last_memory_acceded, i + 1);
144 
145  ++nb_executed;
146  }
147 
148 
149 
150  /* ******************************************
151  * Functions for RiSC16 pseudo-instructions *
152  ********************************************/
153  void
154  p_halt(bool print) {
155  ++nb_executed;
156 
157  if (print) {
158  println_all();
159  }
160 
161  exit(EXIT_SUCCESS);
162  }
163 
164 
165  void
166  p_movi(unsigned int result, immed_t immed) {
167  assert(result < nb_registers);
168 
169  i_lui(result, immed >> 6);
170  i_addi(result, result, immed & 0x3F);
171  }
172 
173 
174  void
175  p_nop() {
176  i_add(0, 0, 0);
177  }
178 
179 
180  void
182  i_jalr(0, 0); // NOT implemented!
183  }
184 
185 
186 
187  /* *******************
188  * General functions *
189  *********************/
190  void
192  for (unsigned int i = 0; i < size_memory; ++i) {
193  memory[i] = 0;
194  }
195  after_last_memory_acceded = 0;
196  }
197 
198 
199  void
201  nb_executed = 0;
202  }
203 
204 
205  void
207  // registers[0] must be always 0
208  for (unsigned int i = 1; i < nb_registers; ++i) {
209  registers[i] = 0;
210  }
211  }
212 
213 
214  void
215  print_mem(unsigned int i) {
216  std::cout << "M[" << i << "] = ";
217  print_value16(memory[i]);
218  }
219  void
220  print_reg(unsigned int a) {
221  assert(a < nb_registers);
222 
223  std::cout << "R[" << a << "] = ";
224  print_value16(registers[a]);
225  }
226 
227 
228  void
229  print_reg2(unsigned int a2, unsigned int a1) {
230  assert(a2 < nb_registers);
231  assert(a1 < nb_registers);
232 
233  std::cout << "R[" << a2 << ':' << a1 << "] = ";
234  print_value32((static_cast<uint32_t>(registers[a2]) << 16)
235  | registers[a1]);
236  }
237 
238 
239  void
240  print_value16(std::uint16_t n) {
241  std::cout << "0x" << std::setw(4) << std::hex << n
242  << " = 0b" << std::bitset<16>(n)
243  << " = " << std::setw(5) << std::dec << n
244  << " = " << std::setw(6) << std::dec
245  << static_cast<std::int16_t>(n);
246  }
247 
248 
249  void
250  print_value32(std::uint32_t n) {
251  std::cout << "0x" << std::setw(8) << std::hex << n
252  << " = 0b" << std::bitset<32>(n)
253  << " = " << std::setw(9) << std::dec << n
254  << " = " << std::setw(10) << std::dec
255  << static_cast<std::int32_t>(n);
256  }
257 
258 
259  void
261  println_infos();
263  if (after_last_memory_acceded > 0) {
264  std::cout << std::endl;
265  }
266  println_memory();
267  }
268 
269 
270  void
272  std::cout << "# instructions executed = " << nb_executed << std::endl;
273  }
274 
275 
276  void
277  println_mem(unsigned int i) {
278  print_mem(i);
279  std::cout << std::endl;
280  }
281 
282 
283  void
284  println_memory(unsigned int size) {
285  for (unsigned int i = 0; i < (size == 0
287  : size); ++i) {
288  println_mem(i);
289  }
290  }
291 
292 
293  void
294  println_reg(unsigned int a) {
295  assert(a < nb_registers);
296 
297  print_reg(a);
298  std::cout << std::endl;
299  }
300 
301 
302  void
303  println_reg2(unsigned int a2, unsigned int a1) {
304  assert(a2 < nb_registers);
305  assert(a1 < nb_registers);
306 
307  print_reg2(a2, a1);
308  std::cout << std::endl;
309  }
310 
311 
312  void
314  for (unsigned int i = 0; i < nb_registers; ++i) {
315  println_reg(i);
316  }
317  }
318 
319 
320  void
321  println_value16(std::uint16_t n) {
322  print_value16(n);
323  std::cout << std::endl;
324  }
325 
326 
327  void
328  println_value32(std::uint32_t n) {
329  print_value32(n);
330  std::cout << std::endl;
331  }
332 
333 } // namespace cpprisc16
void p_movi(unsigned int result, immed_t immed)
(MOV Immediate) R[result] <– immed
Definition: cpprisc16.cpp:166
void i_jalr(unsigned int result, unsigned int a)
(Jump And Link using Register) In the real RiSC16: R[result] <– PC + 1 (where PC = Program Counter)...
Definition: cpprisc16.cpp:77
void println_memory(unsigned int size)
Print memory items.
Definition: cpprisc16.cpp:284
void clear_memory()
Reset to 0 all memory items and mark them as not used.
Definition: cpprisc16.cpp:191
void print_value32(std::uint32_t n)
Print to stdout the 32 bits value n: hexadecimal representation = binary = decimal = signed decimal (...
Definition: cpprisc16.cpp:250
void p_reset()
In the real RiSC16: R[result] <– PC + 1 (where PC = Program Counter), PC <– 0 (jump to 0) but impos...
Definition: cpprisc16.cpp:181
void println_infos()
Print to stdout the number of executed instructions.
Definition: cpprisc16.cpp:271
void println_value32(std::uint32_t n)
Print to stdout the 32 bits value n: hexadecimal representation = binary = decimal = signed decimal...
Definition: cpprisc16.cpp:328
word16_t memory[256]
Memory items.
Definition: cpprisc16.cpp:39
std::uint16_t word16_t
Type for register and memory items.
Definition: cpprisc16.hpp:54
void i_addi(unsigned int result, unsigned int a, immed_t immed6)
(ADD Immediate) R[result] <– R[a] + immed6
Definition: cpprisc16.cpp:64
void println_registers()
Print all registers items.
Definition: cpprisc16.cpp:313
void println_reg(unsigned int a)
Print the register R[a].
Definition: cpprisc16.cpp:294
std::uint16_t immed_t
Type for immediate value.
Definition: cpprisc16.hpp:48
void print_mem(unsigned int i)
Print ith memory item M[i] (without newline).
Definition: cpprisc16.cpp:215
void i_add(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] + R[b].
Definition: cpprisc16.cpp:51
const unsigned int size_memory
Size of the memory: 256 word16_t items.
Definition: cpprisc16.cpp:30
word16_t registers[8]
Registers.
Definition: cpprisc16.cpp:43
const unsigned int nb_registers
Number of registers: 8 word16_t items.
Definition: cpprisc16.cpp:28
unsigned int after_last_memory_acceded
Index following the last memory item used.
Definition: cpprisc16.cpp:37
void i_sw(unsigned int a, unsigned int result, immed_t immed6)
(Store Word) Memory[R[result] + immed6] <– R[a]
Definition: cpprisc16.cpp:133
void println_reg2(unsigned int a2, unsigned int a1)
Print the 32 bits value of R[a2]:R[a1].
Definition: cpprisc16.cpp:303
Instructions set of RiSC16: 8 instructions i_* and 4 pseudo-instructions p_*.
uint64_t nb_executed
Number of instructions executed.
Definition: cpprisc16.cpp:41
void println_mem(unsigned int i)
Print ith memory item M[i].
Definition: cpprisc16.cpp:277
void println_value16(std::uint16_t n)
Print to stdout the 16 bits value n: hexadecimal representation = binary = decimal = signed decimal...
Definition: cpprisc16.cpp:321
void print_reg(unsigned int a)
Print the register R[a] (without newline).
Definition: cpprisc16.cpp:220
void print_value16(std::uint16_t n)
Print to stdout the 16 bits value n: hexadecimal representation = binary = decimal = signed decimal (...
Definition: cpprisc16.cpp:240
void clear_registers()
Reset to 0 all registers.
Definition: cpprisc16.cpp:206
void p_nop()
Do nothing.
Definition: cpprisc16.cpp:175
void p_halt(bool print)
If print then call println_all()
Definition: cpprisc16.cpp:154
void print_reg2(unsigned int a2, unsigned int a1)
Print the 32 bits value of R[a2]:R[a1] (without newline).
Definition: cpprisc16.cpp:229
void println_all()
Print infos, registers and memory (if used).
Definition: cpprisc16.cpp:260
void clear_nb_executed()
Reset the number of executed instructions.
Definition: cpprisc16.cpp:200
void i_nand(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] NAND R[b] (== ~(a & b))
Definition: cpprisc16.cpp:120
void i_lw(unsigned int result, unsigned int a, immed_t immed6)
(Load Word) R[result] <– Memory[R[a] + immed6]
Definition: cpprisc16.cpp:103
void i_lui(unsigned int result, immed_t immed10)
(Load Upper Immediate) R[result] <– immed10 << 6
Definition: cpprisc16.cpp:91