cpprisc16  June 16, 2020
cppextendedrisc16.hpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 
3 /** \file cpprisc16/cppextendedrisc16.hpp (March 15, 2017)
4  * \brief Extended instructions set:
5  * some extra operations x_* implemented with RiSC16.
6  *
7  * Piece of cpprisc16.
8  * https://bitbucket.org/OPiMedia/cpprisc16
9  *
10  * GPLv3 --- Copyright (C) 2017 Olivier Pirson
11  * http://www.opimedia.be/
12  */
13 
14 #ifndef CPPRISC16_CPPRISC16_CPPEXTENDEDRISC16_HPP_
15 #define CPPRISC16_CPPRISC16_CPPEXTENDEDRISC16_HPP_
16 
17 #include "cpprisc16.hpp"
18 
19 
20 /* *******
21  * Macro *
22  *********/
23 /** \brief
24  * Jump to label.
25  */
26 #define x_branch(label) { \
27  ++cpprisc16::nb_executed; \
28  goto label; \
29  }
30 
31 
32 
33 namespace cpprisc16 {
34 
35  /* ****************************************************
36  * Prototypes for RiSC16 extended pseudo-instructions *
37  ******************************************************/
38 
39  /** \brief
40  * R[a2]:R[a1] <-- R[a2]:R[a1] + R[b2]:R[b1]
41  *
42  * a2, a1, b2, b1, tmp1, tmp2, tmp3 must be different
43  */
44  void
45  x_add32(unsigned int a2, unsigned int a1, unsigned int b2, unsigned int b1,
46  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3);
47 
48 
49  /** \brief
50  * R[b]:R[a] <-- R[a] + R[b]
51  *
52  * a, b, tmp1, tmp2, tmp3 must be different
53  */
54  void
55  x_addc(unsigned int a, unsigned int b,
56  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3);
57 
58 
59  /** \brief
60  * R[result] <-- R[a] & R[b]
61  */
62  void
63  x_and_to(unsigned int result, unsigned int a, unsigned int b);
64 
65 
66  /** \brief
67  * R[a2]:R[a1] <-- R[a2]:R[a1] + 1
68  *
69  * a2, a1 must be different
70  */
71  void
72  x_inc32(unsigned int a2, unsigned int a1);
73 
74 
75  /** \brief
76  * R[result] <-- (positive value) if a < b,
77  * 0 else
78  */
79  void
80  x_is_lower_to(unsigned int result, unsigned int a, unsigned int b,
81  unsigned int tmp);
82 
83 
84  /** \brief
85  * R[a] <-- R[a] << 1 (== R[a]*2)
86  */
87  void
88  x_lshift(unsigned int a);
89 
90 
91  /** \brief
92  * R[result] <-- R[a] << 1 (== R[a]*2)
93  */
94  void
95  x_lshift_to(unsigned int result, unsigned int a);
96 
97 
98  /** \brief
99  * R[a2]:R[a1] <-- (R[a2]:R[a1]) << 1 (== (R[a2]:R[a1])*2)
100  *
101  * a1, a2, tmp must be different
102  */
103  void
104  x_lshift32(unsigned int a2, unsigned int a1,
105  unsigned int tmp);
106 
107 
108  /** \brief
109  * R[a] <-- R[a] << 8 (== R[a]*256)
110  */
111  void
112  x_lshift_8(unsigned int a);
113 
114 
115  /** \brief
116  * R[result] <-- R[a] << 8 (== R[a]*256)
117  */
118  void
119  x_lshift_8_to(unsigned int result, unsigned int a);
120 
121 
122  /** \brief
123  * R[a2]:R[a1] <-- (R[a2]:R[a1]) << 8 (== (R[a2]:R[a1])*256)
124  *
125  * a1, a2, tmp1, tmp2, tmp3 must be different
126  */
127  void
128  x_lshift32_8(unsigned int a2, unsigned int a1,
129  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3);
130 
131 
132  /** \brief
133  * R[a] <-- R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
134  *
135  * If (MSB of R[a]) == 1
136  * then the result is 0x8000,
137  * else the result is 0.
138  *
139  * @param a != tmp
140  * @param tmp
141  */
142  void
143  x_mask0x8000(unsigned int a,
144  unsigned int tmp);
145 
146 
147  /** \brief
148  * R[result] <-- R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
149  *
150  * If (MSB of R[a]) == 1
151  * then the result is 0x8000,
152  * else the result is 0.
153  *
154  * result, a must be different
155  */
156  void
157  x_mask0x8000_to(unsigned int result, unsigned int a);
158 
159 
160  /** \brief
161  * R[result] <-- R[a]
162  */
163  void
164  x_mov(unsigned int result, unsigned int a);
165 
166 
167  /** \brief
168  * R[b]:R[a] <-- R[a] * R[b]
169  * by standard algorithm:
170  * https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication
171  *
172  * a, b, tmp1, tmp2, tmp3, tmp4, tmp5 must be different
173  *
174  * Side effect: Use memory 0x0 to 0x3 (included) to save temporary work.
175  */
176  void
177  x_mul(unsigned int a, unsigned int b,
178  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3,
179  unsigned int tmp4, unsigned int tmp5);
180 
181 
182  /** \brief
183  * R[b]:R[a] <-- R[a] * R[b]
184  * by Karatsuba algorithm:
185  * https://en.wikipedia.org/wiki/Karatsuba_algorithm
186  *
187  * a, b, tmp1, tmp2, tmp3, tmp4, tmp5 must be different
188  *
189  * Side effect: Use memory 0x0 to 0x5 (included) to save temporary work.
190  */
191  void
192  x_mul_karatsuba(unsigned int a, unsigned int b,
193  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3,
194  unsigned int tmp4, unsigned int tmp5);
195 
196 
197  /** \brief
198  * R[result] <-- R[a] * R[b]
199  *
200  * result, a, b, tmp1, tmp2 must be different
201  *
202  * @param result
203  * @param a R[a] <= 0xFF (== 0b11111111 == 255)
204  * @param b R[b] <= 0xFF
205  * @param tmp1
206  * @param tmp2
207  */
208  void
209  x_mul8_to(unsigned int result, unsigned int a, unsigned int b,
210  unsigned int tmp1, unsigned int tmp2);
211 
212 
213  /** \brief
214  * R[a] <-- -R[a] (two's complement)
215  */
216  void
217  x_neg(unsigned int a);
218 
219 
220  /** \brief
221  * R[a] <-- ~R[a]
222  */
223  void
224  x_not(unsigned int a);
225 
226 
227  /** \brief
228  * R[result] <-- ~R[a]
229  */
230  void
231  x_not_to(unsigned int result, unsigned int a);
232 
233 
234  /** \brief
235  * R[result] <-- R[a] | R[b]
236  *
237  * @param result
238  * @param a != 0 and != b
239  * @param b != 0
240  */
241  void
242  x_or_to(unsigned int result, unsigned int a, unsigned int b);
243 
244 
245  /** \brief
246  * R[result] <-- R[a] >> 1 (== R[a]/2)
247  *
248  * result, a, tmp1, tmp2 must be different
249  *
250  * Side effect: change R[a], R[tmp1], R[tmp2]
251  */
252  void
253  x_rshift_to(unsigned int result, unsigned int a,
254  unsigned int tmp1, unsigned int tmp2);
255 
256 
257  /** \brief
258  * R[result] <-- R[a] >> 8 (== R[a]/256)
259  *
260  * result, a, tmp1, tmp2 must be different
261  *
262  * Side effect: change R[tmp1], R[tmp2]
263  */
264  void
265  x_rshift_8_to(unsigned int result, unsigned int a,
266  unsigned int tmp1, unsigned int tmp2);
267 
268 
269  /** \brief
270  * R[resulta] <-- R[a] >> 8 (== R[a]/256)
271  * R[resultb] <-- R[b] >> 8
272  *
273  * resulta, a, resultb, b, tmp1, tmp2, tmp3 must be different
274  *
275  * Side effect: change R[tmp1], R[tmp2], R[tmp3]
276  */
277  void
278  x_rshift_8_duo_to(unsigned int resulta, unsigned int a,
279  unsigned int resultb, unsigned int b,
280  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3);
281 
282 
283  /** \brief
284  * R[result] <-- R[a] >> 8 with extension of the sign
285  *
286  * result, a, tmp1, tmp2, tmp3 must be different
287  *
288  * Side effect: change R[tmp1], R[tmp2], R[tmp3]
289  */
290  void
291  x_rshift_8_signed_to(unsigned int result, unsigned int a,
292  unsigned int tmp1, unsigned int tmp2,
293  unsigned int tmp3);
294 
295 
296  /** \brief
297  * R[a] <-- 0
298  */
299  void
300  x_set0(unsigned int a);
301 
302 
303  /** \brief
304  * R[result] <-- 0x8000 (== 0b1000000000000000 == 32768)
305  */
306  void
307  x_set0x8000(unsigned int result);
308 
309 
310  /** \brief
311  * R[result2]:R[a] <-- R[a]*R[a]
312  *
313  * a, result2, tmp1, tmp2, tmp3, tmp4, tmp5 must be different
314  *
315  * Side effect: Use memory 0x0 to 0x1 (included) to save temporary work.
316  */
317  void
318  x_sqr(unsigned int a, unsigned int result2,
319  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3,
320  unsigned int tmp4, unsigned int tmp5);
321 
322 
323  /** \brief
324  * R[result] <-- R[a] * R[a]
325  *
326  * result, a, tmp1, tmp2, tmp3 must be different
327  *
328  * @param result
329  * @param a R[a] <= 0xFF (== 0b11111111 == 255)
330  * @param tmp1
331  * @param tmp2
332  * @param tmp3
333  */
334  void
335  x_sqr8_to(unsigned int result, unsigned int a,
336  unsigned int tmp1, unsigned int tmp2, unsigned int tmp3);
337 
338 
339  /** \brief
340  * R[a] <-- -R[a] + R[b]
341  */
342  void
343  x_sub_from(unsigned int a, unsigned int b);
344 
345 
346  /** \brief
347  * R[result] <-- R[a] - R[b]
348  */
349  void
350  x_sub_to(unsigned int result, unsigned int a, unsigned int b);
351 
352 
353  /** \brief
354  * R[a], R[b] <-- R[b], R[a]
355  */
356  void
357  x_swap(unsigned int a, unsigned int b, unsigned int tmp);
358 
359 } // namespace cpprisc16
360 
361 
362 #endif // CPPRISC16_CPPRISC16_CPPEXTENDEDRISC16_HPP_
void x_mask0x8000(unsigned int a, unsigned int tmp)
R[a] <– R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
void x_neg(unsigned int a)
R[a] <– -R[a] (two&#39;s complement)
void x_not_to(unsigned int result, unsigned int a)
R[result] <– ~R[a].
void x_sqr(unsigned int a, unsigned int result2, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[result2]:R[a] <– R[a]*R[a].
void x_lshift(unsigned int a)
R[a] <– R[a] << 1 (== R[a]*2)
void x_sqr8_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[result] <– R[a] * R[a].
void x_mul8_to(unsigned int result, unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] * R[b].
void x_set0x8000(unsigned int a)
R[result] <– 0x8000 (== 0b1000000000000000 == 32768)
void x_inc32(unsigned int a2, unsigned int a1)
R[a2]:R[a1] <– R[a2]:R[a1] + 1.
void x_not(unsigned int a)
R[a] <– ~R[a].
void x_mov(unsigned int result, unsigned int a)
R[result] <– R[a].
void x_mul_karatsuba(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[b]:R[a] <– R[a] * R[b] by Karatsuba algorithm: https://en.wikipedia.org/wiki/Karatsuba_algorithm.
void x_rshift_8_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] >> 8 (== R[a]/256)
void x_and_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] & R[b].
void x_add32(unsigned int a2, unsigned int a1, unsigned int b2, unsigned int b1, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[a2]:R[a1] <– R[a2]:R[a1] + R[b2]:R[b1].
void x_mul(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3, unsigned int tmp4, unsigned int tmp5)
R[b]:R[a] <– R[a] * R[b] by standard algorithm: https://en.wikipedia.org/wiki/Multiplication_algorit...
void x_addc(unsigned int a, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[b]:R[a] <– R[a] + R[b].
void x_lshift32(unsigned int a2, unsigned int a1, unsigned int tmp)
R[a2]:R[a1] <– (R[a2]:R[a1]) << 1 (== (R[a2]:R[a1])*2)
void x_rshift_8_duo_to(unsigned int result_a, unsigned int a, unsigned int result_b, unsigned int b, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[resulta] <– R[a] >> 8 (== R[a]/256) R[resultb] <– R[b] >> 8.
void x_sub_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] - R[b].
Instructions set of RiSC16: 8 instructions i_* and 4 pseudo-instructions p_*.
void x_swap(unsigned int a, unsigned int b, unsigned int tmp)
R[a], R[b] <– R[b], R[a].
void x_lshift32_8(unsigned int a2, unsigned int a1, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[a2]:R[a1] <– (R[a2]:R[a1]) << 8 (== (R[a2]:R[a1])*256)
void x_lshift_8(unsigned int a)
R[a] <– R[a] << 8 (== R[a]*256)
void x_rshift_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2)
R[result] <– R[a] >> 1 (== R[a]/2)
void x_set0(unsigned int result)
R[a] <– 0.
void x_lshift_to(unsigned int result, unsigned int a)
R[result] <– R[a] << 1 (== R[a]*2)
void x_is_lower_to(unsigned int result, unsigned int a, unsigned int b, unsigned int tmp)
R[result] <– (positive value) if a < b, 0 else.
void x_sub_from(unsigned int a, unsigned int b)
R[a] <– -R[a] + R[b].
void x_lshift_8_to(unsigned int result, unsigned int a)
R[result] <– R[a] << 8 (== R[a]*256)
void x_or_to(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] | R[b].
void x_mask0x8000_to(unsigned int result, unsigned int a)
R[result] <– R[a] & 0x8000 (== R[a] & 0b1000000000000000 == R[a] & 32768)
void x_rshift_8_signed_to(unsigned int result, unsigned int a, unsigned int tmp1, unsigned int tmp2, unsigned int tmp3)
R[result] <– R[a] >> 8 with extension of the sign.