cpprisc16  June 16, 2020
cppis1.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 
3 /** \file cpprisc16/cppis1.cpp (March 14, 2017)
4  * \brief Additional Instructions Set 1 IS[1].
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 "cppis1.hpp"
14 
15 
16 namespace cpprisc16 {
17 
18  /* **********************************
19  * Functions for IS[1] instructions *
20  ************************************/
21  bool
22  is1_add(unsigned int result, unsigned int a, unsigned int b) {
23  assert(result < nb_registers);
24  assert(a < nb_registers);
25  assert(b < nb_registers);
26 
27  assert(sizeof(unsigned int) > sizeof(word16_t));
28 
29  const std::uint32_t sum = (static_cast<std::uint32_t>(registers[a])
30  + static_cast<std::uint32_t>(registers[b]));
31 
32  registers[result] = sum;
33  registers[0] = 0;
34 
35  ++nb_executed;
36 
37  return (sum >> 16) != 0;
38  }
39 
40 
41  void
42  is1_nor(unsigned int result, unsigned int a, unsigned int b) {
43  assert(result < nb_registers);
44  assert(a < nb_registers);
45  assert(b < nb_registers);
46 
47  registers[result] = ~(registers[a] | registers[b]);
48  registers[0] = 0;
49 
50  ++nb_executed;
51  }
52 
53 
54  bool
55  is1_sha(unsigned int result, unsigned int a, unsigned int b) {
56  assert(result < nb_registers);
57  assert(a < nb_registers);
58  assert(b < nb_registers);
59 
60  ++nb_executed;
61 
62  const bool left = (static_cast<std::int16_t>(registers[b]) >= 0);
63  const word16_t nb = (left
64  ? registers[b]
65  : -registers[b]);
66 
67  if (nb < 16) {
68  const bool overflow
69  = (left
70  ? registers[a] >> (16 - nb)
71  : static_cast<std::uint16_t>(registers[a] << (16 - nb))) != 0;
72  // lost piece != 0
73 
74  registers[result] = (left
75  ? registers[a] << nb
76  : static_cast<std::int16_t>(registers[a]) >> nb);
77  registers[0] = 0;
78 
79  return overflow;
80  }
81  else {
82  // Shift too big for C++ shift operator
83  const bool overflow = (registers[a] != 0);
84 
85  registers[result] = 0;
86 
87  return overflow;
88  }
89  }
90 
91 
92  bool
93  is1_shl(unsigned int result, unsigned int a, unsigned int b) {
94  assert(result < nb_registers);
95  assert(a < nb_registers);
96  assert(b < nb_registers);
97 
98  ++nb_executed;
99 
100  const bool left = (static_cast<std::int16_t>(registers[b]) >= 0);
101  const word16_t nb = (left
102  ? registers[b]
103  : -registers[b]);
104 
105  if (nb < 16) {
106  const bool overflow
107  = (left
108  ? registers[a] >> (16 - nb)
109  : static_cast<std::uint16_t>(registers[a] << (16 - nb))) != 0;
110  // lost piece != 0
111 
112  registers[result] = (left
113  ? registers[a] << nb
114  : registers[a] >> nb);
115  registers[0] = 0;
116 
117  return overflow;
118  }
119  else {
120  // Shift too big for C++ shift operator
121  const bool overflow = (registers[a] != 0);
122 
123  registers[result] = 0;
124 
125  return overflow;
126  }
127  }
128 
129 
130  void
131  is1_shifti(unsigned int result, unsigned int a, immed_t immed7) {
132  assert(result < nb_registers);
133  assert(a < nb_registers);
134  assert(immed7 <= 0x7F);
135 
136  // 6 5 43210
137  // immed7 is decomposed in x:M:immed5
138 
139  const bool arithmetic = immed7 & 0x20; // bit 5
140  const bool right = immed7 & 0x10; // bit 4 == sign of immed5
141 
142  if (right) { // negative value --> absolute value for first 5 bits
143  immed7 = -(immed7 | 0xFFF0);
144  }
145 
146  immed7 &= 0x1F; // keep only 5 first bits
147 
148  assert(immed7 < 16);
149 
150  if (immed7 < 16) {
151  registers[result]
152  = (right
153  ? (arithmetic
154  ? static_cast<std::int16_t>(registers[a]) >> immed7
155  : registers[a] >> immed7)
156  : registers[a] << immed7);
157 
158  registers[0] = 0;
159  }
160  else {
161  // Shift too big for C++ shift operator
162  registers[result] = 0;
163  }
164 
165  ++nb_executed;
166  }
167 
168 
169  bool
170  is1_sub(unsigned int result, unsigned int a, unsigned int b) {
171  assert(result < nb_registers);
172  assert(a < nb_registers);
173  assert(b < nb_registers);
174 
175  const bool overflow = (registers[a] < registers[b]);
176  const unsigned int diff = registers[a] - registers[b];
177 
178  registers[result] = diff;
179  registers[0] = 0;
180 
181  ++nb_executed;
182 
183  return overflow;
184  }
185 
186 
187  void
188  is1_xor(unsigned int result, unsigned int a, unsigned int b) {
189  assert(result < nb_registers);
190  assert(a < nb_registers);
191  assert(b < nb_registers);
192 
193  registers[result] = registers[a] ^ registers[b];
194  registers[0] = 0;
195 
196  ++nb_executed;
197  }
198 
199 } // namespace cpprisc16
bool is1_add(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] + R[b].
Definition: cppis1.cpp:22
void is1_nor(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] NOR R[b] (== ~(a | b))
Definition: cppis1.cpp:42
Additional Instructions Set 1 IS[1]: 8 new instructions is1_* and 1 instruction modified is1_add...
void is1_xor(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] XOR R[b] (== ~(a ^ b))
Definition: cppis1.cpp:188
std::uint16_t word16_t
Type for register and memory items.
Definition: cpprisc16.hpp:54
bool is1_sub(unsigned int result, unsigned int a, unsigned int b)
R[result] <– R[a] - R[b].
Definition: cppis1.cpp:170
std::uint16_t immed_t
Type for immediate value.
Definition: cpprisc16.hpp:48
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
uint64_t nb_executed
Number of instructions executed.
Definition: cpprisc16.cpp:41
bool is1_shl(unsigned int result, unsigned int a, unsigned int b)
(SHift Logic) R[result] <– (R[a] << R[b]) or (R[a] >> -R[b])
Definition: cppis1.cpp:93
bool is1_sha(unsigned int result, unsigned int a, unsigned int b)
(SHift Arithmetic) R[result] <– (R[a] << R[b]) or (R[a] >> -R[b])
Definition: cppis1.cpp:55
void is1_shifti(unsigned int result, unsigned int a, immed_t immed7)
(Shift Immediate) R[result] <– (R[a] << immed5) or (R[a] >> -immed5)
Definition: cppis1.cpp:131