Monero
Loading...
Searching...
No Matches
bytecode_machine.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2019, tevador <tevador@gmail.com>
3
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of the copyright holder nor the
14 names of its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#pragma once
30
31#include "common.hpp"
32#include "intrin_portable.h"
33#include "instruction.hpp"
34#include "program.hpp"
35
36namespace randomx {
37
38 //register file in machine byte order
44 };
45
47 union {
50 };
51 union {
54 };
55 union {
58 };
60 union {
63 };
65 };
66
67#define OPCODE_CEIL_DECLARE(curr, prev) constexpr int ceil_ ## curr = ceil_ ## prev + RANDOMX_FREQ_ ## curr;
68 constexpr int ceil_NULL = 0;
99#undef OPCODE_CEIL_DECLARE
100
101#define RANDOMX_EXE_ARGS InstructionByteCode& ibc, int& pc, uint8_t* scratchpad, ProgramConfiguration& config
102#define RANDOMX_GEN_ARGS Instruction& instr, int i, InstructionByteCode& ibc
103
104 class BytecodeMachine;
105
107
109 public:
111 for (unsigned i = 0; i < RegistersCount; ++i) {
112 registerUsage[i] = -1;
113 }
114 nreg = &regFile;
115 }
116
118 beginCompilation(regFile);
119 for (unsigned i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) {
120 auto& instr = program(i);
121 auto& ibc = bytecode[i];
122 compileInstruction(instr, i, ibc);
123 }
124 }
125
127 for (int pc = 0; pc < RANDOMX_PROGRAM_SIZE; ++pc) {
128 auto& ibc = bytecode[pc];
129 executeInstruction(ibc, pc, scratchpad, config);
130 }
131 }
132
134#ifdef RANDOMX_GEN_TABLE
135 {
136 auto generator = genTable[instr.opcode];
137 (this->*generator)(instr, i, ibc);
138 }
139#else
140 ;
141#endif
142
144
146 *ibc.idst += (*ibc.isrc << ibc.shift) + ibc.imm;
147 }
148
150 *ibc.idst += load64(getScratchpadAddress(ibc, scratchpad));
151 }
152
154 *ibc.idst -= *ibc.isrc;
155 }
156
158 *ibc.idst -= load64(getScratchpadAddress(ibc, scratchpad));
159 }
160
162 *ibc.idst *= *ibc.isrc;
163 }
164
166 *ibc.idst *= load64(getScratchpadAddress(ibc, scratchpad));
167 }
168
170 *ibc.idst = mulh(*ibc.idst, *ibc.isrc);
171 }
172
174 *ibc.idst = mulh(*ibc.idst, load64(getScratchpadAddress(ibc, scratchpad)));
175 }
176
178 *ibc.idst = smulh(unsigned64ToSigned2sCompl(*ibc.idst), unsigned64ToSigned2sCompl(*ibc.isrc));
179 }
180
182 *ibc.idst = smulh(unsigned64ToSigned2sCompl(*ibc.idst), unsigned64ToSigned2sCompl(load64(getScratchpadAddress(ibc, scratchpad))));
183 }
184
186 *ibc.idst = ~(*ibc.idst) + 1; //two's complement negative
187 }
188
190 *ibc.idst ^= *ibc.isrc;
191 }
192
194 *ibc.idst ^= load64(getScratchpadAddress(ibc, scratchpad));
195 }
196
198 *ibc.idst = rotr(*ibc.idst, *ibc.isrc & 63);
199 }
200
202 *ibc.idst = rotl(*ibc.idst, *ibc.isrc & 63);
203 }
204
206 int_reg_t temp = *ibc.isrc;
207 *(int_reg_t*)ibc.isrc = *ibc.idst;
208 *ibc.idst = temp;
209 }
210
212 *ibc.fdst = rx_swap_vec_f128(*ibc.fdst);
213 }
214
216 *ibc.fdst = rx_add_vec_f128(*ibc.fdst, *ibc.fsrc);
217 }
218
221 *ibc.fdst = rx_add_vec_f128(*ibc.fdst, fsrc);
222 }
223
225 *ibc.fdst = rx_sub_vec_f128(*ibc.fdst, *ibc.fsrc);
226 }
227
230 *ibc.fdst = rx_sub_vec_f128(*ibc.fdst, fsrc);
231 }
232
234 const rx_vec_f128 mask = rx_set1_vec_f128(0x80F0000000000000);
235 *ibc.fdst = rx_xor_vec_f128(*ibc.fdst, mask);
236 }
237
239 *ibc.fdst = rx_mul_vec_f128(*ibc.fdst, *ibc.fsrc);
240 }
241
244 config,
246 );
247 *ibc.fdst = rx_div_vec_f128(*ibc.fdst, fsrc);
248 }
249
251 *ibc.fdst = rx_sqrt_vec_f128(*ibc.fdst);
252 }
253
255 *ibc.idst += ibc.imm;
256 if ((*ibc.idst & ibc.memMask) == 0) {
257 pc = ibc.target;
258 }
259 }
260
262 rx_set_rounding_mode(rotr(*ibc.isrc, ibc.imm) % 4);
263 }
264
266 store64(scratchpad + ((*ibc.idst + ibc.imm) & ibc.memMask), *ibc.isrc);
267 }
268 protected:
271 const rx_vec_f128 xexponentMask = rx_load_vec_f128((const double*)&config.eMask);
272 x = rx_and_vec_f128(x, xmantissaMask);
273 x = rx_or_vec_f128(x, xexponentMask);
274 return x;
275 }
276
277 private:
278 static const int_reg_t zero;
281
282 static void* getScratchpadAddress(InstructionByteCode& ibc, uint8_t* scratchpad) {
283 uint32_t addr = (*ibc.isrc + ibc.imm) & ibc.memMask;
284 return scratchpad + addr;
285 }
286
287#ifdef RANDOMX_GEN_TABLE
288 static InstructionGenBytecode genTable[256];
289
290 void gen_IADD_RS(RANDOMX_GEN_ARGS);
291 void gen_IADD_M(RANDOMX_GEN_ARGS);
292 void gen_ISUB_R(RANDOMX_GEN_ARGS);
293 void gen_ISUB_M(RANDOMX_GEN_ARGS);
294 void gen_IMUL_R(RANDOMX_GEN_ARGS);
295 void gen_IMUL_M(RANDOMX_GEN_ARGS);
296 void gen_IMULH_R(RANDOMX_GEN_ARGS);
297 void gen_IMULH_M(RANDOMX_GEN_ARGS);
298 void gen_ISMULH_R(RANDOMX_GEN_ARGS);
299 void gen_ISMULH_M(RANDOMX_GEN_ARGS);
300 void gen_IMUL_RCP(RANDOMX_GEN_ARGS);
301 void gen_INEG_R(RANDOMX_GEN_ARGS);
302 void gen_IXOR_R(RANDOMX_GEN_ARGS);
303 void gen_IXOR_M(RANDOMX_GEN_ARGS);
304 void gen_IROR_R(RANDOMX_GEN_ARGS);
305 void gen_IROL_R(RANDOMX_GEN_ARGS);
306 void gen_ISWAP_R(RANDOMX_GEN_ARGS);
307 void gen_FSWAP_R(RANDOMX_GEN_ARGS);
308 void gen_FADD_R(RANDOMX_GEN_ARGS);
309 void gen_FADD_M(RANDOMX_GEN_ARGS);
310 void gen_FSUB_R(RANDOMX_GEN_ARGS);
311 void gen_FSUB_M(RANDOMX_GEN_ARGS);
312 void gen_FSCAL_R(RANDOMX_GEN_ARGS);
313 void gen_FMUL_R(RANDOMX_GEN_ARGS);
314 void gen_FDIV_M(RANDOMX_GEN_ARGS);
315 void gen_FSQRT_R(RANDOMX_GEN_ARGS);
316 void gen_CBRANCH(RANDOMX_GEN_ARGS);
317 void gen_CFROUND(RANDOMX_GEN_ARGS);
318 void gen_ISTORE(RANDOMX_GEN_ARGS);
319 void gen_NOP(RANDOMX_GEN_ARGS);
320#endif
321 };
322}
#define RANDOMX_GEN_ARGS
Definition: bytecode_machine.hpp:102
#define OPCODE_CEIL_DECLARE(curr, prev)
Definition: bytecode_machine.hpp:67
#define RANDOMX_EXE_ARGS
Definition: bytecode_machine.hpp:101
Definition: bytecode_machine.hpp:108
static void exe_FDIV_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:242
static void exe_IMULH_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:169
static void exe_FMUL_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:238
static void exe_ISMULH_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:177
static void exe_ISUB_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:157
static void exe_IMULH_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:173
static void exe_FSWAP_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:211
static void exe_ISUB_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:153
static void exe_FSQRT_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:250
static void exe_IMUL_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:161
static rx_vec_f128 maskRegisterExponentMantissa(ProgramConfiguration &config, rx_vec_f128 x)
Definition: bytecode_machine.hpp:269
static void executeBytecode(InstructionByteCode bytecode[RANDOMX_PROGRAM_SIZE], uint8_t *scratchpad, ProgramConfiguration &config)
Definition: bytecode_machine.hpp:126
static void exe_FSCAL_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:233
void compileInstruction(RANDOMX_GEN_ARGS)
Definition: bytecode_machine.cpp:81
void beginCompilation(NativeRegisterFile &regFile)
Definition: bytecode_machine.hpp:110
static void exe_FSUB_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:224
static const int_reg_t zero
Definition: bytecode_machine.hpp:278
static void exe_IADD_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:149
static void exe_FADD_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:219
static void exe_IMUL_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:165
static void exe_IROL_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:201
static void exe_ISMULH_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:181
static void exe_IROR_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:197
NativeRegisterFile * nreg
Definition: bytecode_machine.hpp:280
static void exe_ISTORE(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:265
static void exe_IXOR_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:193
void compileProgram(Program &program, InstructionByteCode bytecode[RANDOMX_PROGRAM_SIZE], NativeRegisterFile &regFile)
Definition: bytecode_machine.hpp:117
static void exe_CFROUND(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:261
static void exe_FSUB_M(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:228
static void exe_INEG_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:185
static void * getScratchpadAddress(InstructionByteCode &ibc, uint8_t *scratchpad)
Definition: bytecode_machine.hpp:282
static void exe_FADD_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:215
static void executeInstruction(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.cpp:40
static void exe_ISWAP_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:205
int registerUsage[RegistersCount]
Definition: bytecode_machine.hpp:279
static void exe_IXOR_R(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:189
static void exe_IADD_RS(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:145
static void exe_CBRANCH(RANDOMX_EXE_ARGS)
Definition: bytecode_machine.hpp:254
Definition: program.hpp:44
#define RANDOMX_PROGRAM_SIZE
Definition: configuration.h:56
static FORCE_INLINE uint64_t load64(const void *src)
Definition: endian.h:50
static FORCE_INLINE void store64(void *dst, uint64_t w)
Definition: endian.h:86
int64_t smulh(int64_t a, int64_t b)
Definition: instructions_portable.cpp:125
uint64_t rotl(uint64_t a, unsigned int b)
Definition: instructions_portable.cpp:99
uint64_t rotr(uint64_t a, unsigned int b)
Definition: instructions_portable.cpp:92
void rx_set_rounding_mode(uint32_t mode)
Definition: instructions_portable.cpp:141
uint64_t mulh(uint64_t a, uint64_t b)
Definition: instructions_portable.cpp:108
FORCE_INLINE rx_vec_f128 rx_add_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:566
FORCE_INLINE rx_vec_f128 rx_set_vec_f128(uint64_t x1, uint64_t x0)
Definition: intrin_portable.h:614
FORCE_INLINE rx_vec_f128 rx_xor_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:628
FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:642
FORCE_INLINE rx_vec_f128 rx_set1_vec_f128(uint64_t x)
Definition: intrin_portable.h:621
FORCE_INLINE rx_vec_f128 rx_swap_vec_f128(rx_vec_f128 a)
Definition: intrin_portable.h:559
FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:635
FORCE_INLINE rx_vec_f128 rx_load_vec_f128(const double *pd)
Definition: intrin_portable.h:547
FORCE_INLINE rx_vec_f128 rx_sub_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:573
FORCE_INLINE rx_vec_f128 rx_mul_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:580
FORCE_INLINE rx_vec_f128 rx_div_vec_f128(rx_vec_f128 a, rx_vec_f128 b)
Definition: intrin_portable.h:587
FORCE_INLINE rx_vec_f128 rx_cvt_packed_int_vec_f128(const void *addr)
Definition: intrin_portable.h:709
FORCE_INLINE rx_vec_f128 rx_sqrt_vec_f128(rx_vec_f128 a)
Definition: intrin_portable.h:594
constexpr int64_t unsigned64ToSigned2sCompl(uint64_t x)
Definition: intrin_portable.h:38
Definition: cryptonote_config.h:211
Definition: allocator.cpp:35
uint64_t int_reg_t
Definition: common.hpp:133
constexpr int RegisterCountFlt
Definition: common.hpp:150
constexpr int RegistersCount
Definition: common.hpp:149
constexpr uint64_t dynamicMantissaMask
Definition: common.hpp:166
void(BytecodeMachine::* InstructionGenBytecode)(RANDOMX_GEN_ARGS)
Definition: bytecode_machine.hpp:106
InstructionType
Definition: instruction.hpp:42
constexpr int ceil_NULL
Definition: bytecode_machine.hpp:68
signed short int16_t
Definition: stdint.h:122
unsigned short uint16_t
Definition: stdint.h:125
signed __int64 int64_t
Definition: stdint.h:135
unsigned int uint32_t
Definition: stdint.h:126
unsigned char uint8_t
Definition: stdint.h:124
unsigned __int64 uint64_t
Definition: stdint.h:136
Definition: bytecode_machine.hpp:46
int64_t simm
Definition: bytecode_machine.hpp:57
int_reg_t * idst
Definition: bytecode_machine.hpp:48
const rx_vec_f128 * fsrc
Definition: bytecode_machine.hpp:53
InstructionType type
Definition: bytecode_machine.hpp:59
uint64_t imm
Definition: bytecode_machine.hpp:56
uint32_t memMask
Definition: bytecode_machine.hpp:64
const int_reg_t * isrc
Definition: bytecode_machine.hpp:52
int16_t target
Definition: bytecode_machine.hpp:61
uint16_t shift
Definition: bytecode_machine.hpp:62
rx_vec_f128 * fdst
Definition: bytecode_machine.hpp:49
Definition: bytecode_machine.hpp:39
rx_vec_f128 f[RegisterCountFlt]
Definition: bytecode_machine.hpp:41
rx_vec_f128 e[RegisterCountFlt]
Definition: bytecode_machine.hpp:42
rx_vec_f128 a[RegisterCountFlt]
Definition: bytecode_machine.hpp:43
int_reg_t r[RegistersCount]
Definition: bytecode_machine.hpp:40
Definition: program.hpp:39
Definition: intrin_portable.h:534