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
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:221
Definition allocator.cpp:35
uint64_t int_reg_t
Definition common.hpp:140
constexpr int RegisterCountFlt
Definition common.hpp:157
constexpr int RegistersCount
Definition common.hpp:156
constexpr uint64_t dynamicMantissaMask
Definition common.hpp:173
void(BytecodeMachine::* InstructionGenBytecode)(RANDOMX_GEN_ARGS)
Definition bytecode_machine.hpp:106
InstructionType
Definition instruction.hpp:42
@ IMUL_M
Definition instruction.hpp:48
@ IROL_R
Definition instruction.hpp:58
@ IMULH_R
Definition instruction.hpp:49
@ NOP
Definition instruction.hpp:72
@ IXOR_R
Definition instruction.hpp:55
@ FADD_M
Definition instruction.hpp:62
@ ISWAP_R
Definition instruction.hpp:59
@ FMUL_R
Definition instruction.hpp:66
@ ISUB_M
Definition instruction.hpp:46
@ FSWAP_R
Definition instruction.hpp:60
@ IMUL_R
Definition instruction.hpp:47
@ IXOR_M
Definition instruction.hpp:56
@ FDIV_M
Definition instruction.hpp:67
@ INEG_R
Definition instruction.hpp:54
@ FSQRT_R
Definition instruction.hpp:68
@ IADD_RS
Definition instruction.hpp:43
@ ISUB_R
Definition instruction.hpp:45
@ CFROUND
Definition instruction.hpp:70
@ FSUB_M
Definition instruction.hpp:64
@ ISTORE
Definition instruction.hpp:71
@ IROR_R
Definition instruction.hpp:57
@ IMULH_M
Definition instruction.hpp:50
@ ISMULH_M
Definition instruction.hpp:52
@ IMUL_RCP
Definition instruction.hpp:53
@ ISMULH_R
Definition instruction.hpp:51
@ FSUB_R
Definition instruction.hpp:63
@ FSCAL_R
Definition instruction.hpp:65
@ IADD_M
Definition instruction.hpp:44
@ FADD_R
Definition instruction.hpp:61
@ CBRANCH
Definition instruction.hpp:69
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