cpprisc16  June 16, 2020
cpprisc16.hpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 
3 /** \file cpprisc16/cpprisc16.hpp (June 16, 2020)
4  * \brief Instructions set of RiSC16:
5  * 8 instructions i_* and 4 pseudo-instructions p_*.
6  *
7  * Piece of cpprisc16.
8  * https://bitbucket.org/OPiMedia/cpprisc16
9  *
10  * GPLv3 --- Copyright (C) 2017, 2019, 2020 Olivier Pirson
11  * http://www.opimedia.be/
12  */
13 
14 #ifndef CPPRISC16_CPPRISC16_CPPRISC16_HPP_
15 #define CPPRISC16_CPPRISC16_CPPRISC16_HPP_
16 
17 #include <cassert>
18 #include <cstdint>
19 
20 
21 
22 /* ******************************
23  * Macro for RiSC16 instruction *
24  ********************************/
25 
26 /** \brief (Branch if EQual)
27  * If R[a] == R[b]
28  * then jump to label.
29  */
30 #define i_beq(a, b, label) { \
31  assert(a < cpprisc16::nb_registers); \
32  assert(b < cpprisc16::nb_registers); \
33  \
34  ++cpprisc16::nb_executed; \
35  if (cpprisc16::registers[a] == cpprisc16::registers[b]) { goto label; } \
36  }
37 
38 
39 
40 namespace cpprisc16 {
41 
42  /* *******
43  * Types *
44  *********/
45  /** \brief
46  * Type for immediate value.
47  */
48  typedef std::uint16_t immed_t;
49 
50 
51  /** \brief
52  * Type for register and memory items.
53  */
54  typedef std::uint16_t word16_t;
55 
56 
57 
58  /* ******************
59  * Global constants *
60  ********************/
61  /** \brief
62  * Number of registers: 8 word16_t items.
63  */
64  extern const unsigned int nb_registers;
65 
66 
67  /** \brief
68  * Size of the memory: 256 word16_t items.
69  */
70  extern const unsigned int size_memory;
71 
72 
73 
74  /* ******************
75  * Global variables *
76  ********************/
77  /** \brief
78  * Index following the last memory item used.
79  */
80  extern unsigned int after_last_memory_acceded;
81 
82 
83  /** \brief
84  * Number of instructions executed.
85  */
86  extern uint64_t nb_executed;
87 
88 
89  /** \brief
90  * Memory items.
91  */
92  extern word16_t memory[256];
93 
94 
95  /** \brief
96  * Registers.
97  */
98  extern word16_t registers[8];
99 
100 
101 
102  /* ************************************
103  * Prototypes for RiSC16 instructions *
104  **************************************/
105 
106  /** \brief
107  * R[result] <-- R[a] + R[b]
108  *
109  * Count for 1 instruction.
110  */
111  void
112  i_add(unsigned int result, unsigned int a, unsigned int b);
113 
114 
115  /** \brief (ADD Immediate)
116  * R[result] <-- R[a] + immed6
117  *
118  * @param result
119  * @param a
120  * @param immed6 <= 0x3F (== 0b111111 == 63) (size of 6 bits)
121  *
122  * FIXME! In fact must be immediate 7-bit signed value (-64 to 63)
123  *
124  * Count for 1 instruction.
125  */
126  void
127  i_addi(unsigned int result, unsigned int a, immed_t immed6);
128 
129 
130  /** \brief (Jump And Link using Register)
131  * In the real RiSC16:
132  * R[result] <-- PC + 1 (where PC = Program Counter),
133  * PC <-- R[a] (jump to R[a])
134  * but impossible to implement that in this C++ library.
135  *
136  * Count for 1 instruction.
137  *
138  * @warning Not implemented!
139  *
140  * @param result
141  * @param a
142  */
143  void
144  i_jalr(unsigned int result, unsigned int a);
145 
146 
147  /** \brief (Load Upper Immediate)
148  * R[result] <-- immed10 << 6
149  *
150  * Count for 1 instruction.
151  *
152  * @param result
153  * @param immed10 <= 0x3FF (== 0b1111111111 == 1023) (size of 10 bits)
154  */
155  void
156  i_lui(unsigned int result, immed_t immed10);
157 
158 
159  /** \brief (Load Word)
160  * R[result] <-- Memory[R[a] + immed6]
161  *
162  * Count for 1 instruction.
163  *
164  * @param result
165  * @param a
166  * @param immed6 <= 0x3F (== 0b111111 == 63) (size of 6 bits)
167  *
168  * FIXME! In fact must be immediate 7-bit signed value (-64 to 63)
169  */
170  void
171  i_lw(unsigned int result, unsigned int a, immed_t immed6);
172 
173 
174  /** \brief
175  * R[result] <-- R[a] NAND R[b] (== ~(a & b))
176  *
177  * Count for 1 instruction.
178  */
179  void
180  i_nand(unsigned int result, unsigned int a, unsigned int b);
181 
182 
183  /** \brief (Store Word)
184  * Memory[R[result] + immed6] <-- R[a]
185  *
186  * Count for 1 instruction.
187  *
188  * @param a
189  * @param result
190  * @param immed6 <= 0x3F (== 0b111111 == 63) (size of 6 bits)
191  *
192  * FIXME! In fact must be immediate 7-bit signed value (-64 to 63)
193  */
194  void
195  i_sw(unsigned int a, unsigned int result, immed_t immed6);
196 
197 
198 
199  /* *******************************************
200  * Prototypes for RiSC16 pseudo-instructions *
201  *********************************************/
202  /** \brief
203  * If print
204  * then call println_all()
205  *
206  * Stop the program.
207  *
208  * Count for 1 instruction.
209  */
210  void
211  p_halt(bool print = true);
212 
213 
214  /** \brief (MOV Immediate)
215  * R[result] <-- immed
216  *
217  * Pseudo-instruction for
218  * i_lui(result, immed10);
219  * i_addi(result, result, immed6);
220  * with immed = immed10:immed6,
221  * immed10 = immed >> 6,
222  * immed6 = immed & 0x3F.
223  *
224  * Count for 2 instructions.
225  */
226  void
227  p_movi(unsigned int result, immed_t immed);
228 
229 
230  /** \brief
231  * Do nothing.
232  *
233  * Pseudo-instruction for
234  * i_add(0, 0, 0);
235  *
236  * Count for 1 instruction.
237  */
238  void
239  p_nop();
240 
241 
242  /** \brief
243  * In the real RiSC16:
244  * R[result] <-- PC + 1 (where PC = Program Counter),
245  * PC <-- 0 (jump to 0)
246  * but impossible to implement that in this C++ library.
247  *
248  * Pseudo-instruction for
249  * i_jalr(0, 0);
250  *
251  * Count for 1 instruction.
252  *
253  * @warning Not implemented!
254  */
255  void
256  p_reset();
257 
258 
259  /* ********************
260  * General prototypes *
261  **********************/
262  /** \brief
263  * Reset to 0 all memory items
264  * and mark them as not used.
265  */
266  void
267  clear_memory();
268 
269 
270  /** \brief
271  * Reset the number of executed instructions.
272  */
273  void
275 
276 
277  /** \brief
278  * Reset to 0 all registers.
279  */
280  void
281  clear_registers();
282 
283 
284  /** \brief
285  * Print ith memory item M[i]
286  * (without newline).
287  */
288  void
289  print_mem(unsigned int i);
290 
291 
292  /** \brief
293  * Print the register R[a]
294  * (without newline).
295  */
296  void
297  print_reg(unsigned int a);
298 
299 
300  /** \brief
301  * Print the 32 bits value of R[a2]:R[a1]
302  * (without newline).
303  */
304  void
305  print_reg2(unsigned int a2, unsigned int a1);
306 
307 
308  /** \brief
309  * Print to stdout the 16 bits value n:
310  * hexadecimal representation = binary = decimal = signed decimal
311  * (without newline).
312  */
313  void
314  print_value16(std::uint16_t n);
315 
316 
317  /** \brief
318  * Print to stdout the 32 bits value n:
319  * hexadecimal representation = binary = decimal = signed decimal
320  * (without newline).
321  */
322  void
323  print_value32(std::uint32_t n);
324 
325 
326  /** \brief
327  * Print infos,
328  * registers
329  * and memory (if used).
330  */
331  void
332  println_all();
333 
334 
335  /** \brief
336  * Print to stdout the number of executed instructions.
337  */
338  void
339  println_infos();
340 
341 
342  /** \brief
343  * Print ith memory item M[i].
344  */
345  void
346  println_mem(unsigned int i);
347 
348 
349  /** \brief
350  * Print memory items.
351  *
352  * If size == 0
353  * then print all items until last item used,
354  * else print size first items.
355  */
356  void
357  println_memory(unsigned int size = 0);
358 
359 
360  /** \brief
361  * Print the register R[a].
362  */
363  void
364  println_reg(unsigned int a);
365 
366 
367  /** \brief
368  * Print the 32 bits value of R[a2]:R[a1].
369  */
370  void
371  println_reg2(unsigned int a2, unsigned int a1);
372 
373 
374  /** \brief
375  * Print all registers items.
376  */
377  void
379 
380 
381  /** \brief
382  * Print to stdout the 16 bits value n:
383  * hexadecimal representation = binary = decimal = signed decimal
384  */
385  void
386  println_value16(std::uint16_t n);
387 
388 
389  /** \brief
390  * Print to stdout the 32 bits value n:
391  * hexadecimal representation = binary = decimal = signed decimal
392  */
393  void
394  println_value32(std::uint32_t n);
395 
396 } // namespace cpprisc16
397 
398 
399 #endif // CPPRISC16_CPPRISC16_CPPRISC16_HPP_
400 
401 
402 /** \mainpage
403  * cpprisc16
404  *
405  * C++ library to easily write and test "assembly" code for RiSC-16 (Ridiculously Simple Computer).
406  *
407  * (See <a href="https://www.ece.umd.edu/~blj/RiSC/">The RiSC-16 Architecture</a> by Bruce Jacob.)
408  *
409 \htmlonly
410 <ul>
411 <li>
412  Complete <strong>C++ sources</strong> on
413  <strong><a href="https://bitbucket.org/OPiMedia/cpprisc16/">Bitbucket</a></strong>
414  with a very simple example in this
415  <strong><a href="https://bitbucket.org/OPiMedia/cpprisc16/src/master/cpprisc16/">README</a></strong> file
416 </li>
417 <li>
418  This
419  <strong><a href="http://www.opimedia.be/DS/online-documentations/cpprisc16/html/">C++ HTML online documentation</a></strong>
420 </li>
421 </ul>
422 \endhtmlonly
423  *
424  * GPLv3 &mdash; Copyright (C) 2017, 2019, 2020 Olivier Pirson
425  * http://www.opimedia.be/
426  */
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
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