aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/CMakeLists.txt9
-rw-r--r--src/crypto/CryptonightR_JIT.c102
-rw-r--r--src/crypto/CryptonightR_JIT.h18
-rw-r--r--src/crypto/CryptonightR_template.S1590
-rw-r--r--src/crypto/CryptonightR_template.h1039
-rw-r--r--src/crypto/chacha.h8
-rw-r--r--src/crypto/hash-ops.h2
-rw-r--r--src/crypto/hash.h8
-rw-r--r--src/crypto/slow-hash.c253
-rw-r--r--src/crypto/variant4_random_math.h441
10 files changed, 3424 insertions, 46 deletions
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 0c635e7cb..5ce43be22 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -45,6 +45,8 @@ set(crypto_sources
random.c
skein.c
slow-hash.c
+ CryptonightR_JIT.c
+ CryptonightR_template.S
tree-hash.c)
set(crypto_headers)
@@ -66,7 +68,9 @@ set(crypto_private_headers
oaes_lib.h
random.h
skein.h
- skein_port.h)
+ skein_port.h
+ CryptonightR_JIT.h
+ CryptonightR_template.h)
monero_private_headers(cncrypto
${crypto_private_headers})
@@ -101,4 +105,5 @@ if (ANDROID OR IOS)
endif()
endif()
-
+# cheat because cmake and ccache hate each other
+set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
diff --git a/src/crypto/CryptonightR_JIT.c b/src/crypto/CryptonightR_JIT.c
new file mode 100644
index 000000000..9add65296
--- /dev/null
+++ b/src/crypto/CryptonightR_JIT.c
@@ -0,0 +1,102 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "int-util.h"
+#include "hash-ops.h"
+#include "variant4_random_math.h"
+#include "CryptonightR_JIT.h"
+#include "CryptonightR_template.h"
+
+static const uint8_t prologue[] = {
+ 0x4C, 0x8B, 0xD7, // mov r10, rdi
+ 0x53, // push rbx
+ 0x55, // push rbp
+ 0x41, 0x57, // push r15
+ 0x4C, 0x8B, 0xDC, // mov r11, rsp
+ 0x41, 0x8B, 0x1A, // mov ebx, DWORD PTR [r10]
+ 0x41, 0x8B, 0x72, 0x04, // mov esi, DWORD PTR [r10+4]
+ 0x41, 0x8B, 0x7A, 0x08, // mov edi, DWORD PTR [r10+8]
+ 0x41, 0x8B, 0x6A, 0x0C, // mov ebp, DWORD PTR [r10+12]
+ 0x41, 0x8B, 0x62, 0x10, // mov esp, DWORD PTR [r10+16]
+ 0x45, 0x8B, 0x7A, 0x14, // mov r15d, DWORD PTR [r10+20]
+ 0x41, 0x8B, 0x42, 0x18, // mov eax, DWORD PTR [r10+24]
+ 0x41, 0x8B, 0x52, 0x1C, // mov edx, DWORD PTR [r10+28]
+ 0x45, 0x8B, 0x4A, 0x20, // mov r9d, DWORD PTR [r10+32]
+};
+
+static const uint8_t epilogue[] = {
+ 0x49, 0x8B, 0xE3, // mov rsp, r11
+ 0x41, 0x89, 0x1A, // mov DWORD PTR [r10], ebx
+ 0x41, 0x89, 0x72, 0x04, // mov DWORD PTR [r10+4], esi
+ 0x41, 0x89, 0x7A, 0x08, // mov DWORD PTR [r10+8], edi
+ 0x41, 0x89, 0x6A, 0x0C, // mov DWORD PTR [r10+12], ebp
+ 0x41, 0x5F, // pop r15
+ 0x5D, // pop rbp
+ 0x5B, // pop rbx
+ 0xC3, // ret
+};
+
+#define APPEND_CODE(src, size) \
+ do { \
+ if (JIT_code + (size) > JIT_code_end) \
+ return -1; \
+ memcpy(JIT_code, (src), (size)); \
+ JIT_code += (size); \
+ } while (0)
+
+int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size)
+{
+ uint8_t* JIT_code = (uint8_t*) buf;
+ const uint8_t* JIT_code_end = JIT_code + buf_size;
+
+ APPEND_CODE(prologue, sizeof(prologue));
+
+ uint32_t prev_rot_src = 0xFFFFFFFFU;
+
+ for (int i = 0;; ++i)
+ {
+ const struct V4_Instruction inst = code[i];
+ if (inst.opcode == RET)
+ break;
+
+ const uint8_t opcode = (inst.opcode == MUL) ? inst.opcode : (inst.opcode + 2);
+
+ const uint32_t a = inst.dst_index;
+ const uint32_t b = inst.src_index;
+ const uint8_t c = opcode | (inst.dst_index << V4_OPCODE_BITS) | (((inst.src_index == 8) ? inst.dst_index : inst.src_index) << (V4_OPCODE_BITS + V4_DST_INDEX_BITS));
+
+ switch (inst.opcode)
+ {
+ case ROR:
+ case ROL:
+ if (b != prev_rot_src)
+ {
+ prev_rot_src = b;
+ const uint8_t* p1 = (const uint8_t*) instructions_mov[c];
+ const uint8_t* p2 = (const uint8_t*) instructions_mov[c + 1];
+ APPEND_CODE(p1, p2 - p1);
+ }
+ break;
+ }
+
+ if (a == prev_rot_src)
+ prev_rot_src = 0xFFFFFFFFU;
+
+ const uint8_t* p1 = (const uint8_t*) instructions[c];
+ const uint8_t* p2 = (const uint8_t*) instructions[c + 1];
+ APPEND_CODE(p1, p2 - p1);
+
+ if (inst.opcode == ADD)
+ *(uint32_t*)(JIT_code - 4) = inst.C;
+ }
+
+ APPEND_CODE(epilogue, sizeof(epilogue));
+
+ __builtin___clear_cache((char*)buf, (char*)JIT_code);
+
+ return 0;
+}
diff --git a/src/crypto/CryptonightR_JIT.h b/src/crypto/CryptonightR_JIT.h
new file mode 100644
index 000000000..5f689b37b
--- /dev/null
+++ b/src/crypto/CryptonightR_JIT.h
@@ -0,0 +1,18 @@
+#ifndef CRYPTONIGHTR_JIT_H
+#define CRYPTONIGHTR_JIT_H
+
+// Minimalistic JIT code generator for random math sequence in CryptonightR
+//
+// Usage:
+// - Allocate writable and executable memory
+// - Call v4_generate_JIT_code with "buf" pointed to memory allocated on previous step
+// - Call the generated code instead of "v4_random_math(code, r)", omit the "code" parameter
+
+typedef void (*v4_random_math_JIT_func)(uint32_t* r) __attribute__((sysv_abi));
+
+// Given the random math sequence, generates machine code (x86-64) for it
+// Returns 0 if code was generated successfully
+// Returns -1 if provided buffer was too small
+int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size);
+
+#endif // CRYPTONIGHTR_JIT_H
diff --git a/src/crypto/CryptonightR_template.S b/src/crypto/CryptonightR_template.S
new file mode 100644
index 000000000..068de22ec
--- /dev/null
+++ b/src/crypto/CryptonightR_template.S
@@ -0,0 +1,1590 @@
+#ifdef __APPLE__
+# define ALIGN(x) .align 6
+#else
+# define ALIGN(x) .align 64
+#endif
+.intel_syntax noprefix
+#ifdef __APPLE__
+# define FN_PREFIX(fn) _ ## fn
+.text
+#else
+# define FN_PREFIX(fn) fn
+.section .text
+#endif
+
+#define PUBLIC .global
+
+PUBLIC FN_PREFIX(CryptonightR_instruction0)
+PUBLIC FN_PREFIX(CryptonightR_instruction1)
+PUBLIC FN_PREFIX(CryptonightR_instruction2)
+PUBLIC FN_PREFIX(CryptonightR_instruction3)
+PUBLIC FN_PREFIX(CryptonightR_instruction4)
+PUBLIC FN_PREFIX(CryptonightR_instruction5)
+PUBLIC FN_PREFIX(CryptonightR_instruction6)
+PUBLIC FN_PREFIX(CryptonightR_instruction7)
+PUBLIC FN_PREFIX(CryptonightR_instruction8)
+PUBLIC FN_PREFIX(CryptonightR_instruction9)
+PUBLIC FN_PREFIX(CryptonightR_instruction10)
+PUBLIC FN_PREFIX(CryptonightR_instruction11)
+PUBLIC FN_PREFIX(CryptonightR_instruction12)
+PUBLIC FN_PREFIX(CryptonightR_instruction13)
+PUBLIC FN_PREFIX(CryptonightR_instruction14)
+PUBLIC FN_PREFIX(CryptonightR_instruction15)
+PUBLIC FN_PREFIX(CryptonightR_instruction16)
+PUBLIC FN_PREFIX(CryptonightR_instruction17)
+PUBLIC FN_PREFIX(CryptonightR_instruction18)
+PUBLIC FN_PREFIX(CryptonightR_instruction19)
+PUBLIC FN_PREFIX(CryptonightR_instruction20)
+PUBLIC FN_PREFIX(CryptonightR_instruction21)
+PUBLIC FN_PREFIX(CryptonightR_instruction22)
+PUBLIC FN_PREFIX(CryptonightR_instruction23)
+PUBLIC FN_PREFIX(CryptonightR_instruction24)
+PUBLIC FN_PREFIX(CryptonightR_instruction25)
+PUBLIC FN_PREFIX(CryptonightR_instruction26)
+PUBLIC FN_PREFIX(CryptonightR_instruction27)
+PUBLIC FN_PREFIX(CryptonightR_instruction28)
+PUBLIC FN_PREFIX(CryptonightR_instruction29)
+PUBLIC FN_PREFIX(CryptonightR_instruction30)
+PUBLIC FN_PREFIX(CryptonightR_instruction31)
+PUBLIC FN_PREFIX(CryptonightR_instruction32)
+PUBLIC FN_PREFIX(CryptonightR_instruction33)
+PUBLIC FN_PREFIX(CryptonightR_instruction34)
+PUBLIC FN_PREFIX(CryptonightR_instruction35)
+PUBLIC FN_PREFIX(CryptonightR_instruction36)
+PUBLIC FN_PREFIX(CryptonightR_instruction37)
+PUBLIC FN_PREFIX(CryptonightR_instruction38)
+PUBLIC FN_PREFIX(CryptonightR_instruction39)
+PUBLIC FN_PREFIX(CryptonightR_instruction40)
+PUBLIC FN_PREFIX(CryptonightR_instruction41)
+PUBLIC FN_PREFIX(CryptonightR_instruction42)
+PUBLIC FN_PREFIX(CryptonightR_instruction43)
+PUBLIC FN_PREFIX(CryptonightR_instruction44)
+PUBLIC FN_PREFIX(CryptonightR_instruction45)
+PUBLIC FN_PREFIX(CryptonightR_instruction46)
+PUBLIC FN_PREFIX(CryptonightR_instruction47)
+PUBLIC FN_PREFIX(CryptonightR_instruction48)
+PUBLIC FN_PREFIX(CryptonightR_instruction49)
+PUBLIC FN_PREFIX(CryptonightR_instruction50)
+PUBLIC FN_PREFIX(CryptonightR_instruction51)
+PUBLIC FN_PREFIX(CryptonightR_instruction52)
+PUBLIC FN_PREFIX(CryptonightR_instruction53)
+PUBLIC FN_PREFIX(CryptonightR_instruction54)
+PUBLIC FN_PREFIX(CryptonightR_instruction55)
+PUBLIC FN_PREFIX(CryptonightR_instruction56)
+PUBLIC FN_PREFIX(CryptonightR_instruction57)
+PUBLIC FN_PREFIX(CryptonightR_instruction58)
+PUBLIC FN_PREFIX(CryptonightR_instruction59)
+PUBLIC FN_PREFIX(CryptonightR_instruction60)
+PUBLIC FN_PREFIX(CryptonightR_instruction61)
+PUBLIC FN_PREFIX(CryptonightR_instruction62)
+PUBLIC FN_PREFIX(CryptonightR_instruction63)
+PUBLIC FN_PREFIX(CryptonightR_instruction64)
+PUBLIC FN_PREFIX(CryptonightR_instruction65)
+PUBLIC FN_PREFIX(CryptonightR_instruction66)
+PUBLIC FN_PREFIX(CryptonightR_instruction67)
+PUBLIC FN_PREFIX(CryptonightR_instruction68)
+PUBLIC FN_PREFIX(CryptonightR_instruction69)
+PUBLIC FN_PREFIX(CryptonightR_instruction70)
+PUBLIC FN_PREFIX(CryptonightR_instruction71)
+PUBLIC FN_PREFIX(CryptonightR_instruction72)
+PUBLIC FN_PREFIX(CryptonightR_instruction73)
+PUBLIC FN_PREFIX(CryptonightR_instruction74)
+PUBLIC FN_PREFIX(CryptonightR_instruction75)
+PUBLIC FN_PREFIX(CryptonightR_instruction76)
+PUBLIC FN_PREFIX(CryptonightR_instruction77)
+PUBLIC FN_PREFIX(CryptonightR_instruction78)
+PUBLIC FN_PREFIX(CryptonightR_instruction79)
+PUBLIC FN_PREFIX(CryptonightR_instruction80)
+PUBLIC FN_PREFIX(CryptonightR_instruction81)
+PUBLIC FN_PREFIX(CryptonightR_instruction82)
+PUBLIC FN_PREFIX(CryptonightR_instruction83)
+PUBLIC FN_PREFIX(CryptonightR_instruction84)
+PUBLIC FN_PREFIX(CryptonightR_instruction85)
+PUBLIC FN_PREFIX(CryptonightR_instruction86)
+PUBLIC FN_PREFIX(CryptonightR_instruction87)
+PUBLIC FN_PREFIX(CryptonightR_instruction88)
+PUBLIC FN_PREFIX(CryptonightR_instruction89)
+PUBLIC FN_PREFIX(CryptonightR_instruction90)
+PUBLIC FN_PREFIX(CryptonightR_instruction91)
+PUBLIC FN_PREFIX(CryptonightR_instruction92)
+PUBLIC FN_PREFIX(CryptonightR_instruction93)
+PUBLIC FN_PREFIX(CryptonightR_instruction94)
+PUBLIC FN_PREFIX(CryptonightR_instruction95)
+PUBLIC FN_PREFIX(CryptonightR_instruction96)
+PUBLIC FN_PREFIX(CryptonightR_instruction97)
+PUBLIC FN_PREFIX(CryptonightR_instruction98)
+PUBLIC FN_PREFIX(CryptonightR_instruction99)
+PUBLIC FN_PREFIX(CryptonightR_instruction100)
+PUBLIC FN_PREFIX(CryptonightR_instruction101)
+PUBLIC FN_PREFIX(CryptonightR_instruction102)
+PUBLIC FN_PREFIX(CryptonightR_instruction103)
+PUBLIC FN_PREFIX(CryptonightR_instruction104)
+PUBLIC FN_PREFIX(CryptonightR_instruction105)
+PUBLIC FN_PREFIX(CryptonightR_instruction106)
+PUBLIC FN_PREFIX(CryptonightR_instruction107)
+PUBLIC FN_PREFIX(CryptonightR_instruction108)
+PUBLIC FN_PREFIX(CryptonightR_instruction109)
+PUBLIC FN_PREFIX(CryptonightR_instruction110)
+PUBLIC FN_PREFIX(CryptonightR_instruction111)
+PUBLIC FN_PREFIX(CryptonightR_instruction112)
+PUBLIC FN_PREFIX(CryptonightR_instruction113)
+PUBLIC FN_PREFIX(CryptonightR_instruction114)
+PUBLIC FN_PREFIX(CryptonightR_instruction115)
+PUBLIC FN_PREFIX(CryptonightR_instruction116)
+PUBLIC FN_PREFIX(CryptonightR_instruction117)
+PUBLIC FN_PREFIX(CryptonightR_instruction118)
+PUBLIC FN_PREFIX(CryptonightR_instruction119)
+PUBLIC FN_PREFIX(CryptonightR_instruction120)
+PUBLIC FN_PREFIX(CryptonightR_instruction121)
+PUBLIC FN_PREFIX(CryptonightR_instruction122)
+PUBLIC FN_PREFIX(CryptonightR_instruction123)
+PUBLIC FN_PREFIX(CryptonightR_instruction124)
+PUBLIC FN_PREFIX(CryptonightR_instruction125)
+PUBLIC FN_PREFIX(CryptonightR_instruction126)
+PUBLIC FN_PREFIX(CryptonightR_instruction127)
+PUBLIC FN_PREFIX(CryptonightR_instruction128)
+PUBLIC FN_PREFIX(CryptonightR_instruction129)
+PUBLIC FN_PREFIX(CryptonightR_instruction130)
+PUBLIC FN_PREFIX(CryptonightR_instruction131)
+PUBLIC FN_PREFIX(CryptonightR_instruction132)
+PUBLIC FN_PREFIX(CryptonightR_instruction133)
+PUBLIC FN_PREFIX(CryptonightR_instruction134)
+PUBLIC FN_PREFIX(CryptonightR_instruction135)
+PUBLIC FN_PREFIX(CryptonightR_instruction136)
+PUBLIC FN_PREFIX(CryptonightR_instruction137)
+PUBLIC FN_PREFIX(CryptonightR_instruction138)
+PUBLIC FN_PREFIX(CryptonightR_instruction139)
+PUBLIC FN_PREFIX(CryptonightR_instruction140)
+PUBLIC FN_PREFIX(CryptonightR_instruction141)
+PUBLIC FN_PREFIX(CryptonightR_instruction142)
+PUBLIC FN_PREFIX(CryptonightR_instruction143)
+PUBLIC FN_PREFIX(CryptonightR_instruction144)
+PUBLIC FN_PREFIX(CryptonightR_instruction145)
+PUBLIC FN_PREFIX(CryptonightR_instruction146)
+PUBLIC FN_PREFIX(CryptonightR_instruction147)
+PUBLIC FN_PREFIX(CryptonightR_instruction148)
+PUBLIC FN_PREFIX(CryptonightR_instruction149)
+PUBLIC FN_PREFIX(CryptonightR_instruction150)
+PUBLIC FN_PREFIX(CryptonightR_instruction151)
+PUBLIC FN_PREFIX(CryptonightR_instruction152)
+PUBLIC FN_PREFIX(CryptonightR_instruction153)
+PUBLIC FN_PREFIX(CryptonightR_instruction154)
+PUBLIC FN_PREFIX(CryptonightR_instruction155)
+PUBLIC FN_PREFIX(CryptonightR_instruction156)
+PUBLIC FN_PREFIX(CryptonightR_instruction157)
+PUBLIC FN_PREFIX(CryptonightR_instruction158)
+PUBLIC FN_PREFIX(CryptonightR_instruction159)
+PUBLIC FN_PREFIX(CryptonightR_instruction160)
+PUBLIC FN_PREFIX(CryptonightR_instruction161)
+PUBLIC FN_PREFIX(CryptonightR_instruction162)
+PUBLIC FN_PREFIX(CryptonightR_instruction163)
+PUBLIC FN_PREFIX(CryptonightR_instruction164)
+PUBLIC FN_PREFIX(CryptonightR_instruction165)
+PUBLIC FN_PREFIX(CryptonightR_instruction166)
+PUBLIC FN_PREFIX(CryptonightR_instruction167)
+PUBLIC FN_PREFIX(CryptonightR_instruction168)
+PUBLIC FN_PREFIX(CryptonightR_instruction169)
+PUBLIC FN_PREFIX(CryptonightR_instruction170)
+PUBLIC FN_PREFIX(CryptonightR_instruction171)
+PUBLIC FN_PREFIX(CryptonightR_instruction172)
+PUBLIC FN_PREFIX(CryptonightR_instruction173)
+PUBLIC FN_PREFIX(CryptonightR_instruction174)
+PUBLIC FN_PREFIX(CryptonightR_instruction175)
+PUBLIC FN_PREFIX(CryptonightR_instruction176)
+PUBLIC FN_PREFIX(CryptonightR_instruction177)
+PUBLIC FN_PREFIX(CryptonightR_instruction178)
+PUBLIC FN_PREFIX(CryptonightR_instruction179)
+PUBLIC FN_PREFIX(CryptonightR_instruction180)
+PUBLIC FN_PREFIX(CryptonightR_instruction181)
+PUBLIC FN_PREFIX(CryptonightR_instruction182)
+PUBLIC FN_PREFIX(CryptonightR_instruction183)
+PUBLIC FN_PREFIX(CryptonightR_instruction184)
+PUBLIC FN_PREFIX(CryptonightR_instruction185)
+PUBLIC FN_PREFIX(CryptonightR_instruction186)
+PUBLIC FN_PREFIX(CryptonightR_instruction187)
+PUBLIC FN_PREFIX(CryptonightR_instruction188)
+PUBLIC FN_PREFIX(CryptonightR_instruction189)
+PUBLIC FN_PREFIX(CryptonightR_instruction190)
+PUBLIC FN_PREFIX(CryptonightR_instruction191)
+PUBLIC FN_PREFIX(CryptonightR_instruction192)
+PUBLIC FN_PREFIX(CryptonightR_instruction193)
+PUBLIC FN_PREFIX(CryptonightR_instruction194)
+PUBLIC FN_PREFIX(CryptonightR_instruction195)
+PUBLIC FN_PREFIX(CryptonightR_instruction196)
+PUBLIC FN_PREFIX(CryptonightR_instruction197)
+PUBLIC FN_PREFIX(CryptonightR_instruction198)
+PUBLIC FN_PREFIX(CryptonightR_instruction199)
+PUBLIC FN_PREFIX(CryptonightR_instruction200)
+PUBLIC FN_PREFIX(CryptonightR_instruction201)
+PUBLIC FN_PREFIX(CryptonightR_instruction202)
+PUBLIC FN_PREFIX(CryptonightR_instruction203)
+PUBLIC FN_PREFIX(CryptonightR_instruction204)
+PUBLIC FN_PREFIX(CryptonightR_instruction205)
+PUBLIC FN_PREFIX(CryptonightR_instruction206)
+PUBLIC FN_PREFIX(CryptonightR_instruction207)
+PUBLIC FN_PREFIX(CryptonightR_instruction208)
+PUBLIC FN_PREFIX(CryptonightR_instruction209)
+PUBLIC FN_PREFIX(CryptonightR_instruction210)
+PUBLIC FN_PREFIX(CryptonightR_instruction211)
+PUBLIC FN_PREFIX(CryptonightR_instruction212)
+PUBLIC FN_PREFIX(CryptonightR_instruction213)
+PUBLIC FN_PREFIX(CryptonightR_instruction214)
+PUBLIC FN_PREFIX(CryptonightR_instruction215)
+PUBLIC FN_PREFIX(CryptonightR_instruction216)
+PUBLIC FN_PREFIX(CryptonightR_instruction217)
+PUBLIC FN_PREFIX(CryptonightR_instruction218)
+PUBLIC FN_PREFIX(CryptonightR_instruction219)
+PUBLIC FN_PREFIX(CryptonightR_instruction220)
+PUBLIC FN_PREFIX(CryptonightR_instruction221)
+PUBLIC FN_PREFIX(CryptonightR_instruction222)
+PUBLIC FN_PREFIX(CryptonightR_instruction223)
+PUBLIC FN_PREFIX(CryptonightR_instruction224)
+PUBLIC FN_PREFIX(CryptonightR_instruction225)
+PUBLIC FN_PREFIX(CryptonightR_instruction226)
+PUBLIC FN_PREFIX(CryptonightR_instruction227)
+PUBLIC FN_PREFIX(CryptonightR_instruction228)
+PUBLIC FN_PREFIX(CryptonightR_instruction229)
+PUBLIC FN_PREFIX(CryptonightR_instruction230)
+PUBLIC FN_PREFIX(CryptonightR_instruction231)
+PUBLIC FN_PREFIX(CryptonightR_instruction232)
+PUBLIC FN_PREFIX(CryptonightR_instruction233)
+PUBLIC FN_PREFIX(CryptonightR_instruction234)
+PUBLIC FN_PREFIX(CryptonightR_instruction235)
+PUBLIC FN_PREFIX(CryptonightR_instruction236)
+PUBLIC FN_PREFIX(CryptonightR_instruction237)
+PUBLIC FN_PREFIX(CryptonightR_instruction238)
+PUBLIC FN_PREFIX(CryptonightR_instruction239)
+PUBLIC FN_PREFIX(CryptonightR_instruction240)
+PUBLIC FN_PREFIX(CryptonightR_instruction241)
+PUBLIC FN_PREFIX(CryptonightR_instruction242)
+PUBLIC FN_PREFIX(CryptonightR_instruction243)
+PUBLIC FN_PREFIX(CryptonightR_instruction244)
+PUBLIC FN_PREFIX(CryptonightR_instruction245)
+PUBLIC FN_PREFIX(CryptonightR_instruction246)
+PUBLIC FN_PREFIX(CryptonightR_instruction247)
+PUBLIC FN_PREFIX(CryptonightR_instruction248)
+PUBLIC FN_PREFIX(CryptonightR_instruction249)
+PUBLIC FN_PREFIX(CryptonightR_instruction250)
+PUBLIC FN_PREFIX(CryptonightR_instruction251)
+PUBLIC FN_PREFIX(CryptonightR_instruction252)
+PUBLIC FN_PREFIX(CryptonightR_instruction253)
+PUBLIC FN_PREFIX(CryptonightR_instruction254)
+PUBLIC FN_PREFIX(CryptonightR_instruction255)
+PUBLIC FN_PREFIX(CryptonightR_instruction256)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov0)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov1)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov2)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov3)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov4)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov5)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov6)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov7)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov8)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov9)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov10)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov11)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov12)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov13)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov14)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov15)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov16)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov17)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov18)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov19)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov20)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov21)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov22)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov23)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov24)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov25)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov26)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov27)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov28)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov29)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov30)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov31)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov32)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov33)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov34)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov35)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov36)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov37)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov38)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov39)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov40)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov41)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov42)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov43)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov44)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov45)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov46)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov47)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov48)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov49)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov50)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov51)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov52)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov53)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov54)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov55)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov56)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov57)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov58)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov59)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov60)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov61)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov62)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov63)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov64)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov65)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov66)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov67)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov68)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov69)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov70)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov71)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov72)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov73)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov74)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov75)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov76)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov77)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov78)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov79)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov80)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov81)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov82)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov83)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov84)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov85)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov86)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov87)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov88)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov89)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov90)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov91)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov92)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov93)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov94)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov95)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov96)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov97)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov98)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov99)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov100)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov101)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov102)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov103)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov104)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov105)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov106)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov107)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov108)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov109)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov110)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov111)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov112)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov113)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov114)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov115)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov116)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov117)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov118)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov119)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov120)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov121)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov122)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov123)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov124)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov125)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov126)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov127)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov128)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov129)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov130)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov131)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov132)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov133)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov134)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov135)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov136)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov137)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov138)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov139)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov140)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov141)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov142)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov143)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov144)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov145)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov146)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov147)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov148)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov149)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov150)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov151)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov152)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov153)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov154)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov155)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov156)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov157)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov158)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov159)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov160)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov161)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov162)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov163)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov164)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov165)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov166)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov167)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov168)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov169)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov170)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov171)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov172)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov173)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov174)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov175)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov176)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov177)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov178)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov179)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov180)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov181)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov182)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov183)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov184)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov185)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov186)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov187)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov188)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov189)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov190)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov191)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov192)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov193)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov194)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov195)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov196)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov197)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov198)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov199)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov200)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov201)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov202)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov203)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov204)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov205)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov206)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov207)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov208)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov209)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov210)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov211)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov212)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov213)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov214)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov215)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov216)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov217)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov218)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov219)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov220)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov221)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov222)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov223)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov224)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov225)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov226)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov227)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov228)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov229)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov230)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov231)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov232)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov233)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov234)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov235)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov236)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov237)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov238)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov239)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov240)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov241)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov242)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov243)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov244)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov245)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov246)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov247)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov248)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov249)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov250)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov251)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov252)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov253)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov254)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov255)
+PUBLIC FN_PREFIX(CryptonightR_instruction_mov256)
+
+FN_PREFIX(CryptonightR_instruction0):
+ imul ebx, ebx
+FN_PREFIX(CryptonightR_instruction1):
+ imul ebx, ebx
+FN_PREFIX(CryptonightR_instruction2):
+ imul ebx, ebx
+FN_PREFIX(CryptonightR_instruction3):
+ add ebx, r9d
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction4):
+ sub ebx, r9d
+FN_PREFIX(CryptonightR_instruction5):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction6):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction7):
+ xor ebx, r9d
+FN_PREFIX(CryptonightR_instruction8):
+ imul esi, ebx
+FN_PREFIX(CryptonightR_instruction9):
+ imul esi, ebx
+FN_PREFIX(CryptonightR_instruction10):
+ imul esi, ebx
+FN_PREFIX(CryptonightR_instruction11):
+ add esi, ebx
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction12):
+ sub esi, ebx
+FN_PREFIX(CryptonightR_instruction13):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction14):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction15):
+ xor esi, ebx
+FN_PREFIX(CryptonightR_instruction16):
+ imul edi, ebx
+FN_PREFIX(CryptonightR_instruction17):
+ imul edi, ebx
+FN_PREFIX(CryptonightR_instruction18):
+ imul edi, ebx
+FN_PREFIX(CryptonightR_instruction19):
+ add edi, ebx
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction20):
+ sub edi, ebx
+FN_PREFIX(CryptonightR_instruction21):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction22):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction23):
+ xor edi, ebx
+FN_PREFIX(CryptonightR_instruction24):
+ imul ebp, ebx
+FN_PREFIX(CryptonightR_instruction25):
+ imul ebp, ebx
+FN_PREFIX(CryptonightR_instruction26):
+ imul ebp, ebx
+FN_PREFIX(CryptonightR_instruction27):
+ add ebp, ebx
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction28):
+ sub ebp, ebx
+FN_PREFIX(CryptonightR_instruction29):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction30):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction31):
+ xor ebp, ebx
+FN_PREFIX(CryptonightR_instruction32):
+ imul ebx, esi
+FN_PREFIX(CryptonightR_instruction33):
+ imul ebx, esi
+FN_PREFIX(CryptonightR_instruction34):
+ imul ebx, esi
+FN_PREFIX(CryptonightR_instruction35):
+ add ebx, esi
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction36):
+ sub ebx, esi
+FN_PREFIX(CryptonightR_instruction37):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction38):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction39):
+ xor ebx, esi
+FN_PREFIX(CryptonightR_instruction40):
+ imul esi, esi
+FN_PREFIX(CryptonightR_instruction41):
+ imul esi, esi
+FN_PREFIX(CryptonightR_instruction42):
+ imul esi, esi
+FN_PREFIX(CryptonightR_instruction43):
+ add esi, r9d
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction44):
+ sub esi, r9d
+FN_PREFIX(CryptonightR_instruction45):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction46):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction47):
+ xor esi, r9d
+FN_PREFIX(CryptonightR_instruction48):
+ imul edi, esi
+FN_PREFIX(CryptonightR_instruction49):
+ imul edi, esi
+FN_PREFIX(CryptonightR_instruction50):
+ imul edi, esi
+FN_PREFIX(CryptonightR_instruction51):
+ add edi, esi
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction52):
+ sub edi, esi
+FN_PREFIX(CryptonightR_instruction53):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction54):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction55):
+ xor edi, esi
+FN_PREFIX(CryptonightR_instruction56):
+ imul ebp, esi
+FN_PREFIX(CryptonightR_instruction57):
+ imul ebp, esi
+FN_PREFIX(CryptonightR_instruction58):
+ imul ebp, esi
+FN_PREFIX(CryptonightR_instruction59):
+ add ebp, esi
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction60):
+ sub ebp, esi
+FN_PREFIX(CryptonightR_instruction61):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction62):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction63):
+ xor ebp, esi
+FN_PREFIX(CryptonightR_instruction64):
+ imul ebx, edi
+FN_PREFIX(CryptonightR_instruction65):
+ imul ebx, edi
+FN_PREFIX(CryptonightR_instruction66):
+ imul ebx, edi
+FN_PREFIX(CryptonightR_instruction67):
+ add ebx, edi
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction68):
+ sub ebx, edi
+FN_PREFIX(CryptonightR_instruction69):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction70):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction71):
+ xor ebx, edi
+FN_PREFIX(CryptonightR_instruction72):
+ imul esi, edi
+FN_PREFIX(CryptonightR_instruction73):
+ imul esi, edi
+FN_PREFIX(CryptonightR_instruction74):
+ imul esi, edi
+FN_PREFIX(CryptonightR_instruction75):
+ add esi, edi
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction76):
+ sub esi, edi
+FN_PREFIX(CryptonightR_instruction77):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction78):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction79):
+ xor esi, edi
+FN_PREFIX(CryptonightR_instruction80):
+ imul edi, edi
+FN_PREFIX(CryptonightR_instruction81):
+ imul edi, edi
+FN_PREFIX(CryptonightR_instruction82):
+ imul edi, edi
+FN_PREFIX(CryptonightR_instruction83):
+ add edi, r9d
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction84):
+ sub edi, r9d
+FN_PREFIX(CryptonightR_instruction85):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction86):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction87):
+ xor edi, r9d
+FN_PREFIX(CryptonightR_instruction88):
+ imul ebp, edi
+FN_PREFIX(CryptonightR_instruction89):
+ imul ebp, edi
+FN_PREFIX(CryptonightR_instruction90):
+ imul ebp, edi
+FN_PREFIX(CryptonightR_instruction91):
+ add ebp, edi
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction92):
+ sub ebp, edi
+FN_PREFIX(CryptonightR_instruction93):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction94):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction95):
+ xor ebp, edi
+FN_PREFIX(CryptonightR_instruction96):
+ imul ebx, ebp
+FN_PREFIX(CryptonightR_instruction97):
+ imul ebx, ebp
+FN_PREFIX(CryptonightR_instruction98):
+ imul ebx, ebp
+FN_PREFIX(CryptonightR_instruction99):
+ add ebx, ebp
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction100):
+ sub ebx, ebp
+FN_PREFIX(CryptonightR_instruction101):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction102):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction103):
+ xor ebx, ebp
+FN_PREFIX(CryptonightR_instruction104):
+ imul esi, ebp
+FN_PREFIX(CryptonightR_instruction105):
+ imul esi, ebp
+FN_PREFIX(CryptonightR_instruction106):
+ imul esi, ebp
+FN_PREFIX(CryptonightR_instruction107):
+ add esi, ebp
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction108):
+ sub esi, ebp
+FN_PREFIX(CryptonightR_instruction109):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction110):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction111):
+ xor esi, ebp
+FN_PREFIX(CryptonightR_instruction112):
+ imul edi, ebp
+FN_PREFIX(CryptonightR_instruction113):
+ imul edi, ebp
+FN_PREFIX(CryptonightR_instruction114):
+ imul edi, ebp
+FN_PREFIX(CryptonightR_instruction115):
+ add edi, ebp
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction116):
+ sub edi, ebp
+FN_PREFIX(CryptonightR_instruction117):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction118):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction119):
+ xor edi, ebp
+FN_PREFIX(CryptonightR_instruction120):
+ imul ebp, ebp
+FN_PREFIX(CryptonightR_instruction121):
+ imul ebp, ebp
+FN_PREFIX(CryptonightR_instruction122):
+ imul ebp, ebp
+FN_PREFIX(CryptonightR_instruction123):
+ add ebp, r9d
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction124):
+ sub ebp, r9d
+FN_PREFIX(CryptonightR_instruction125):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction126):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction127):
+ xor ebp, r9d
+FN_PREFIX(CryptonightR_instruction128):
+ imul ebx, esp
+FN_PREFIX(CryptonightR_instruction129):
+ imul ebx, esp
+FN_PREFIX(CryptonightR_instruction130):
+ imul ebx, esp
+FN_PREFIX(CryptonightR_instruction131):
+ add ebx, esp
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction132):
+ sub ebx, esp
+FN_PREFIX(CryptonightR_instruction133):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction134):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction135):
+ xor ebx, esp
+FN_PREFIX(CryptonightR_instruction136):
+ imul esi, esp
+FN_PREFIX(CryptonightR_instruction137):
+ imul esi, esp
+FN_PREFIX(CryptonightR_instruction138):
+ imul esi, esp
+FN_PREFIX(CryptonightR_instruction139):
+ add esi, esp
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction140):
+ sub esi, esp
+FN_PREFIX(CryptonightR_instruction141):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction142):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction143):
+ xor esi, esp
+FN_PREFIX(CryptonightR_instruction144):
+ imul edi, esp
+FN_PREFIX(CryptonightR_instruction145):
+ imul edi, esp
+FN_PREFIX(CryptonightR_instruction146):
+ imul edi, esp
+FN_PREFIX(CryptonightR_instruction147):
+ add edi, esp
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction148):
+ sub edi, esp
+FN_PREFIX(CryptonightR_instruction149):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction150):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction151):
+ xor edi, esp
+FN_PREFIX(CryptonightR_instruction152):
+ imul ebp, esp
+FN_PREFIX(CryptonightR_instruction153):
+ imul ebp, esp
+FN_PREFIX(CryptonightR_instruction154):
+ imul ebp, esp
+FN_PREFIX(CryptonightR_instruction155):
+ add ebp, esp
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction156):
+ sub ebp, esp
+FN_PREFIX(CryptonightR_instruction157):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction158):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction159):
+ xor ebp, esp
+FN_PREFIX(CryptonightR_instruction160):
+ imul ebx, r15d
+FN_PREFIX(CryptonightR_instruction161):
+ imul ebx, r15d
+FN_PREFIX(CryptonightR_instruction162):
+ imul ebx, r15d
+FN_PREFIX(CryptonightR_instruction163):
+ add ebx, r15d
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction164):
+ sub ebx, r15d
+FN_PREFIX(CryptonightR_instruction165):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction166):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction167):
+ xor ebx, r15d
+FN_PREFIX(CryptonightR_instruction168):
+ imul esi, r15d
+FN_PREFIX(CryptonightR_instruction169):
+ imul esi, r15d
+FN_PREFIX(CryptonightR_instruction170):
+ imul esi, r15d
+FN_PREFIX(CryptonightR_instruction171):
+ add esi, r15d
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction172):
+ sub esi, r15d
+FN_PREFIX(CryptonightR_instruction173):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction174):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction175):
+ xor esi, r15d
+FN_PREFIX(CryptonightR_instruction176):
+ imul edi, r15d
+FN_PREFIX(CryptonightR_instruction177):
+ imul edi, r15d
+FN_PREFIX(CryptonightR_instruction178):
+ imul edi, r15d
+FN_PREFIX(CryptonightR_instruction179):
+ add edi, r15d
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction180):
+ sub edi, r15d
+FN_PREFIX(CryptonightR_instruction181):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction182):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction183):
+ xor edi, r15d
+FN_PREFIX(CryptonightR_instruction184):
+ imul ebp, r15d
+FN_PREFIX(CryptonightR_instruction185):
+ imul ebp, r15d
+FN_PREFIX(CryptonightR_instruction186):
+ imul ebp, r15d
+FN_PREFIX(CryptonightR_instruction187):
+ add ebp, r15d
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction188):
+ sub ebp, r15d
+FN_PREFIX(CryptonightR_instruction189):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction190):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction191):
+ xor ebp, r15d
+FN_PREFIX(CryptonightR_instruction192):
+ imul ebx, eax
+FN_PREFIX(CryptonightR_instruction193):
+ imul ebx, eax
+FN_PREFIX(CryptonightR_instruction194):
+ imul ebx, eax
+FN_PREFIX(CryptonightR_instruction195):
+ add ebx, eax
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction196):
+ sub ebx, eax
+FN_PREFIX(CryptonightR_instruction197):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction198):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction199):
+ xor ebx, eax
+FN_PREFIX(CryptonightR_instruction200):
+ imul esi, eax
+FN_PREFIX(CryptonightR_instruction201):
+ imul esi, eax
+FN_PREFIX(CryptonightR_instruction202):
+ imul esi, eax
+FN_PREFIX(CryptonightR_instruction203):
+ add esi, eax
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction204):
+ sub esi, eax
+FN_PREFIX(CryptonightR_instruction205):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction206):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction207):
+ xor esi, eax
+FN_PREFIX(CryptonightR_instruction208):
+ imul edi, eax
+FN_PREFIX(CryptonightR_instruction209):
+ imul edi, eax
+FN_PREFIX(CryptonightR_instruction210):
+ imul edi, eax
+FN_PREFIX(CryptonightR_instruction211):
+ add edi, eax
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction212):
+ sub edi, eax
+FN_PREFIX(CryptonightR_instruction213):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction214):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction215):
+ xor edi, eax
+FN_PREFIX(CryptonightR_instruction216):
+ imul ebp, eax
+FN_PREFIX(CryptonightR_instruction217):
+ imul ebp, eax
+FN_PREFIX(CryptonightR_instruction218):
+ imul ebp, eax
+FN_PREFIX(CryptonightR_instruction219):
+ add ebp, eax
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction220):
+ sub ebp, eax
+FN_PREFIX(CryptonightR_instruction221):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction222):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction223):
+ xor ebp, eax
+FN_PREFIX(CryptonightR_instruction224):
+ imul ebx, edx
+FN_PREFIX(CryptonightR_instruction225):
+ imul ebx, edx
+FN_PREFIX(CryptonightR_instruction226):
+ imul ebx, edx
+FN_PREFIX(CryptonightR_instruction227):
+ add ebx, edx
+ add ebx, 2147483647
+FN_PREFIX(CryptonightR_instruction228):
+ sub ebx, edx
+FN_PREFIX(CryptonightR_instruction229):
+ ror ebx, cl
+FN_PREFIX(CryptonightR_instruction230):
+ rol ebx, cl
+FN_PREFIX(CryptonightR_instruction231):
+ xor ebx, edx
+FN_PREFIX(CryptonightR_instruction232):
+ imul esi, edx
+FN_PREFIX(CryptonightR_instruction233):
+ imul esi, edx
+FN_PREFIX(CryptonightR_instruction234):
+ imul esi, edx
+FN_PREFIX(CryptonightR_instruction235):
+ add esi, edx
+ add esi, 2147483647
+FN_PREFIX(CryptonightR_instruction236):
+ sub esi, edx
+FN_PREFIX(CryptonightR_instruction237):
+ ror esi, cl
+FN_PREFIX(CryptonightR_instruction238):
+ rol esi, cl
+FN_PREFIX(CryptonightR_instruction239):
+ xor esi, edx
+FN_PREFIX(CryptonightR_instruction240):
+ imul edi, edx
+FN_PREFIX(CryptonightR_instruction241):
+ imul edi, edx
+FN_PREFIX(CryptonightR_instruction242):
+ imul edi, edx
+FN_PREFIX(CryptonightR_instruction243):
+ add edi, edx
+ add edi, 2147483647
+FN_PREFIX(CryptonightR_instruction244):
+ sub edi, edx
+FN_PREFIX(CryptonightR_instruction245):
+ ror edi, cl
+FN_PREFIX(CryptonightR_instruction246):
+ rol edi, cl
+FN_PREFIX(CryptonightR_instruction247):
+ xor edi, edx
+FN_PREFIX(CryptonightR_instruction248):
+ imul ebp, edx
+FN_PREFIX(CryptonightR_instruction249):
+ imul ebp, edx
+FN_PREFIX(CryptonightR_instruction250):
+ imul ebp, edx
+FN_PREFIX(CryptonightR_instruction251):
+ add ebp, edx
+ add ebp, 2147483647
+FN_PREFIX(CryptonightR_instruction252):
+ sub ebp, edx
+FN_PREFIX(CryptonightR_instruction253):
+ ror ebp, cl
+FN_PREFIX(CryptonightR_instruction254):
+ rol ebp, cl
+FN_PREFIX(CryptonightR_instruction255):
+ xor ebp, edx
+FN_PREFIX(CryptonightR_instruction256):
+ imul ebx, ebx
+FN_PREFIX(CryptonightR_instruction_mov0):
+
+FN_PREFIX(CryptonightR_instruction_mov1):
+
+FN_PREFIX(CryptonightR_instruction_mov2):
+
+FN_PREFIX(CryptonightR_instruction_mov3):
+
+FN_PREFIX(CryptonightR_instruction_mov4):
+
+FN_PREFIX(CryptonightR_instruction_mov5):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov6):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov7):
+
+FN_PREFIX(CryptonightR_instruction_mov8):
+
+FN_PREFIX(CryptonightR_instruction_mov9):
+
+FN_PREFIX(CryptonightR_instruction_mov10):
+
+FN_PREFIX(CryptonightR_instruction_mov11):
+
+FN_PREFIX(CryptonightR_instruction_mov12):
+
+FN_PREFIX(CryptonightR_instruction_mov13):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov14):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov15):
+
+FN_PREFIX(CryptonightR_instruction_mov16):
+
+FN_PREFIX(CryptonightR_instruction_mov17):
+
+FN_PREFIX(CryptonightR_instruction_mov18):
+
+FN_PREFIX(CryptonightR_instruction_mov19):
+
+FN_PREFIX(CryptonightR_instruction_mov20):
+
+FN_PREFIX(CryptonightR_instruction_mov21):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov22):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov23):
+
+FN_PREFIX(CryptonightR_instruction_mov24):
+
+FN_PREFIX(CryptonightR_instruction_mov25):
+
+FN_PREFIX(CryptonightR_instruction_mov26):
+
+FN_PREFIX(CryptonightR_instruction_mov27):
+
+FN_PREFIX(CryptonightR_instruction_mov28):
+
+FN_PREFIX(CryptonightR_instruction_mov29):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov30):
+ mov ecx, ebx
+FN_PREFIX(CryptonightR_instruction_mov31):
+
+FN_PREFIX(CryptonightR_instruction_mov32):
+
+FN_PREFIX(CryptonightR_instruction_mov33):
+
+FN_PREFIX(CryptonightR_instruction_mov34):
+
+FN_PREFIX(CryptonightR_instruction_mov35):
+
+FN_PREFIX(CryptonightR_instruction_mov36):
+
+FN_PREFIX(CryptonightR_instruction_mov37):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov38):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov39):
+
+FN_PREFIX(CryptonightR_instruction_mov40):
+
+FN_PREFIX(CryptonightR_instruction_mov41):
+
+FN_PREFIX(CryptonightR_instruction_mov42):
+
+FN_PREFIX(CryptonightR_instruction_mov43):
+
+FN_PREFIX(CryptonightR_instruction_mov44):
+
+FN_PREFIX(CryptonightR_instruction_mov45):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov46):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov47):
+
+FN_PREFIX(CryptonightR_instruction_mov48):
+
+FN_PREFIX(CryptonightR_instruction_mov49):
+
+FN_PREFIX(CryptonightR_instruction_mov50):
+
+FN_PREFIX(CryptonightR_instruction_mov51):
+
+FN_PREFIX(CryptonightR_instruction_mov52):
+
+FN_PREFIX(CryptonightR_instruction_mov53):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov54):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov55):
+
+FN_PREFIX(CryptonightR_instruction_mov56):
+
+FN_PREFIX(CryptonightR_instruction_mov57):
+
+FN_PREFIX(CryptonightR_instruction_mov58):
+
+FN_PREFIX(CryptonightR_instruction_mov59):
+
+FN_PREFIX(CryptonightR_instruction_mov60):
+
+FN_PREFIX(CryptonightR_instruction_mov61):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov62):
+ mov ecx, esi
+FN_PREFIX(CryptonightR_instruction_mov63):
+
+FN_PREFIX(CryptonightR_instruction_mov64):
+
+FN_PREFIX(CryptonightR_instruction_mov65):
+
+FN_PREFIX(CryptonightR_instruction_mov66):
+
+FN_PREFIX(CryptonightR_instruction_mov67):
+
+FN_PREFIX(CryptonightR_instruction_mov68):
+
+FN_PREFIX(CryptonightR_instruction_mov69):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov70):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov71):
+
+FN_PREFIX(CryptonightR_instruction_mov72):
+
+FN_PREFIX(CryptonightR_instruction_mov73):
+
+FN_PREFIX(CryptonightR_instruction_mov74):
+
+FN_PREFIX(CryptonightR_instruction_mov75):
+
+FN_PREFIX(CryptonightR_instruction_mov76):
+
+FN_PREFIX(CryptonightR_instruction_mov77):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov78):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov79):
+
+FN_PREFIX(CryptonightR_instruction_mov80):
+
+FN_PREFIX(CryptonightR_instruction_mov81):
+
+FN_PREFIX(CryptonightR_instruction_mov82):
+
+FN_PREFIX(CryptonightR_instruction_mov83):
+
+FN_PREFIX(CryptonightR_instruction_mov84):
+
+FN_PREFIX(CryptonightR_instruction_mov85):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov86):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov87):
+
+FN_PREFIX(CryptonightR_instruction_mov88):
+
+FN_PREFIX(CryptonightR_instruction_mov89):
+
+FN_PREFIX(CryptonightR_instruction_mov90):
+
+FN_PREFIX(CryptonightR_instruction_mov91):
+
+FN_PREFIX(CryptonightR_instruction_mov92):
+
+FN_PREFIX(CryptonightR_instruction_mov93):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov94):
+ mov ecx, edi
+FN_PREFIX(CryptonightR_instruction_mov95):
+
+FN_PREFIX(CryptonightR_instruction_mov96):
+
+FN_PREFIX(CryptonightR_instruction_mov97):
+
+FN_PREFIX(CryptonightR_instruction_mov98):
+
+FN_PREFIX(CryptonightR_instruction_mov99):
+
+FN_PREFIX(CryptonightR_instruction_mov100):
+
+FN_PREFIX(CryptonightR_instruction_mov101):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov102):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov103):
+
+FN_PREFIX(CryptonightR_instruction_mov104):
+
+FN_PREFIX(CryptonightR_instruction_mov105):
+
+FN_PREFIX(CryptonightR_instruction_mov106):
+
+FN_PREFIX(CryptonightR_instruction_mov107):
+
+FN_PREFIX(CryptonightR_instruction_mov108):
+
+FN_PREFIX(CryptonightR_instruction_mov109):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov110):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov111):
+
+FN_PREFIX(CryptonightR_instruction_mov112):
+
+FN_PREFIX(CryptonightR_instruction_mov113):
+
+FN_PREFIX(CryptonightR_instruction_mov114):
+
+FN_PREFIX(CryptonightR_instruction_mov115):
+
+FN_PREFIX(CryptonightR_instruction_mov116):
+
+FN_PREFIX(CryptonightR_instruction_mov117):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov118):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov119):
+
+FN_PREFIX(CryptonightR_instruction_mov120):
+
+FN_PREFIX(CryptonightR_instruction_mov121):
+
+FN_PREFIX(CryptonightR_instruction_mov122):
+
+FN_PREFIX(CryptonightR_instruction_mov123):
+
+FN_PREFIX(CryptonightR_instruction_mov124):
+
+FN_PREFIX(CryptonightR_instruction_mov125):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov126):
+ mov ecx, ebp
+FN_PREFIX(CryptonightR_instruction_mov127):
+
+FN_PREFIX(CryptonightR_instruction_mov128):
+
+FN_PREFIX(CryptonightR_instruction_mov129):
+
+FN_PREFIX(CryptonightR_instruction_mov130):
+
+FN_PREFIX(CryptonightR_instruction_mov131):
+
+FN_PREFIX(CryptonightR_instruction_mov132):
+
+FN_PREFIX(CryptonightR_instruction_mov133):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov134):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov135):
+
+FN_PREFIX(CryptonightR_instruction_mov136):
+
+FN_PREFIX(CryptonightR_instruction_mov137):
+
+FN_PREFIX(CryptonightR_instruction_mov138):
+
+FN_PREFIX(CryptonightR_instruction_mov139):
+
+FN_PREFIX(CryptonightR_instruction_mov140):
+
+FN_PREFIX(CryptonightR_instruction_mov141):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov142):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov143):
+
+FN_PREFIX(CryptonightR_instruction_mov144):
+
+FN_PREFIX(CryptonightR_instruction_mov145):
+
+FN_PREFIX(CryptonightR_instruction_mov146):
+
+FN_PREFIX(CryptonightR_instruction_mov147):
+
+FN_PREFIX(CryptonightR_instruction_mov148):
+
+FN_PREFIX(CryptonightR_instruction_mov149):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov150):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov151):
+
+FN_PREFIX(CryptonightR_instruction_mov152):
+
+FN_PREFIX(CryptonightR_instruction_mov153):
+
+FN_PREFIX(CryptonightR_instruction_mov154):
+
+FN_PREFIX(CryptonightR_instruction_mov155):
+
+FN_PREFIX(CryptonightR_instruction_mov156):
+
+FN_PREFIX(CryptonightR_instruction_mov157):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov158):
+ mov ecx, esp
+FN_PREFIX(CryptonightR_instruction_mov159):
+
+FN_PREFIX(CryptonightR_instruction_mov160):
+
+FN_PREFIX(CryptonightR_instruction_mov161):
+
+FN_PREFIX(CryptonightR_instruction_mov162):
+
+FN_PREFIX(CryptonightR_instruction_mov163):
+
+FN_PREFIX(CryptonightR_instruction_mov164):
+
+FN_PREFIX(CryptonightR_instruction_mov165):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov166):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov167):
+
+FN_PREFIX(CryptonightR_instruction_mov168):
+
+FN_PREFIX(CryptonightR_instruction_mov169):
+
+FN_PREFIX(CryptonightR_instruction_mov170):
+
+FN_PREFIX(CryptonightR_instruction_mov171):
+
+FN_PREFIX(CryptonightR_instruction_mov172):
+
+FN_PREFIX(CryptonightR_instruction_mov173):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov174):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov175):
+
+FN_PREFIX(CryptonightR_instruction_mov176):
+
+FN_PREFIX(CryptonightR_instruction_mov177):
+
+FN_PREFIX(CryptonightR_instruction_mov178):
+
+FN_PREFIX(CryptonightR_instruction_mov179):
+
+FN_PREFIX(CryptonightR_instruction_mov180):
+
+FN_PREFIX(CryptonightR_instruction_mov181):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov182):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov183):
+
+FN_PREFIX(CryptonightR_instruction_mov184):
+
+FN_PREFIX(CryptonightR_instruction_mov185):
+
+FN_PREFIX(CryptonightR_instruction_mov186):
+
+FN_PREFIX(CryptonightR_instruction_mov187):
+
+FN_PREFIX(CryptonightR_instruction_mov188):
+
+FN_PREFIX(CryptonightR_instruction_mov189):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov190):
+ mov ecx, r15d
+FN_PREFIX(CryptonightR_instruction_mov191):
+
+FN_PREFIX(CryptonightR_instruction_mov192):
+
+FN_PREFIX(CryptonightR_instruction_mov193):
+
+FN_PREFIX(CryptonightR_instruction_mov194):
+
+FN_PREFIX(CryptonightR_instruction_mov195):
+
+FN_PREFIX(CryptonightR_instruction_mov196):
+
+FN_PREFIX(CryptonightR_instruction_mov197):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov198):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov199):
+
+FN_PREFIX(CryptonightR_instruction_mov200):
+
+FN_PREFIX(CryptonightR_instruction_mov201):
+
+FN_PREFIX(CryptonightR_instruction_mov202):
+
+FN_PREFIX(CryptonightR_instruction_mov203):
+
+FN_PREFIX(CryptonightR_instruction_mov204):
+
+FN_PREFIX(CryptonightR_instruction_mov205):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov206):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov207):
+
+FN_PREFIX(CryptonightR_instruction_mov208):
+
+FN_PREFIX(CryptonightR_instruction_mov209):
+
+FN_PREFIX(CryptonightR_instruction_mov210):
+
+FN_PREFIX(CryptonightR_instruction_mov211):
+
+FN_PREFIX(CryptonightR_instruction_mov212):
+
+FN_PREFIX(CryptonightR_instruction_mov213):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov214):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov215):
+
+FN_PREFIX(CryptonightR_instruction_mov216):
+
+FN_PREFIX(CryptonightR_instruction_mov217):
+
+FN_PREFIX(CryptonightR_instruction_mov218):
+
+FN_PREFIX(CryptonightR_instruction_mov219):
+
+FN_PREFIX(CryptonightR_instruction_mov220):
+
+FN_PREFIX(CryptonightR_instruction_mov221):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov222):
+ mov ecx, eax
+FN_PREFIX(CryptonightR_instruction_mov223):
+
+FN_PREFIX(CryptonightR_instruction_mov224):
+
+FN_PREFIX(CryptonightR_instruction_mov225):
+
+FN_PREFIX(CryptonightR_instruction_mov226):
+
+FN_PREFIX(CryptonightR_instruction_mov227):
+
+FN_PREFIX(CryptonightR_instruction_mov228):
+
+FN_PREFIX(CryptonightR_instruction_mov229):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov230):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov231):
+
+FN_PREFIX(CryptonightR_instruction_mov232):
+
+FN_PREFIX(CryptonightR_instruction_mov233):
+
+FN_PREFIX(CryptonightR_instruction_mov234):
+
+FN_PREFIX(CryptonightR_instruction_mov235):
+
+FN_PREFIX(CryptonightR_instruction_mov236):
+
+FN_PREFIX(CryptonightR_instruction_mov237):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov238):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov239):
+
+FN_PREFIX(CryptonightR_instruction_mov240):
+
+FN_PREFIX(CryptonightR_instruction_mov241):
+
+FN_PREFIX(CryptonightR_instruction_mov242):
+
+FN_PREFIX(CryptonightR_instruction_mov243):
+
+FN_PREFIX(CryptonightR_instruction_mov244):
+
+FN_PREFIX(CryptonightR_instruction_mov245):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov246):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov247):
+
+FN_PREFIX(CryptonightR_instruction_mov248):
+
+FN_PREFIX(CryptonightR_instruction_mov249):
+
+FN_PREFIX(CryptonightR_instruction_mov250):
+
+FN_PREFIX(CryptonightR_instruction_mov251):
+
+FN_PREFIX(CryptonightR_instruction_mov252):
+
+FN_PREFIX(CryptonightR_instruction_mov253):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov254):
+ mov ecx, edx
+FN_PREFIX(CryptonightR_instruction_mov255):
+
+FN_PREFIX(CryptonightR_instruction_mov256):
diff --git a/src/crypto/CryptonightR_template.h b/src/crypto/CryptonightR_template.h
new file mode 100644
index 000000000..57eb92ebe
--- /dev/null
+++ b/src/crypto/CryptonightR_template.h
@@ -0,0 +1,1039 @@
+#ifndef CRYPTONIGHTR_TEMPLATE_H
+#define CRYPTONIGHTR_TEMPLATE_H
+
+void CryptonightR_instruction0(void);
+void CryptonightR_instruction1(void);
+void CryptonightR_instruction2(void);
+void CryptonightR_instruction3(void);
+void CryptonightR_instruction4(void);
+void CryptonightR_instruction5(void);
+void CryptonightR_instruction6(void);
+void CryptonightR_instruction7(void);
+void CryptonightR_instruction8(void);
+void CryptonightR_instruction9(void);
+void CryptonightR_instruction10(void);
+void CryptonightR_instruction11(void);
+void CryptonightR_instruction12(void);
+void CryptonightR_instruction13(void);
+void CryptonightR_instruction14(void);
+void CryptonightR_instruction15(void);
+void CryptonightR_instruction16(void);
+void CryptonightR_instruction17(void);
+void CryptonightR_instruction18(void);
+void CryptonightR_instruction19(void);
+void CryptonightR_instruction20(void);
+void CryptonightR_instruction21(void);
+void CryptonightR_instruction22(void);
+void CryptonightR_instruction23(void);
+void CryptonightR_instruction24(void);
+void CryptonightR_instruction25(void);
+void CryptonightR_instruction26(void);
+void CryptonightR_instruction27(void);
+void CryptonightR_instruction28(void);
+void CryptonightR_instruction29(void);
+void CryptonightR_instruction30(void);
+void CryptonightR_instruction31(void);
+void CryptonightR_instruction32(void);
+void CryptonightR_instruction33(void);
+void CryptonightR_instruction34(void);
+void CryptonightR_instruction35(void);
+void CryptonightR_instruction36(void);
+void CryptonightR_instruction37(void);
+void CryptonightR_instruction38(void);
+void CryptonightR_instruction39(void);
+void CryptonightR_instruction40(void);
+void CryptonightR_instruction41(void);
+void CryptonightR_instruction42(void);
+void CryptonightR_instruction43(void);
+void CryptonightR_instruction44(void);
+void CryptonightR_instruction45(void);
+void CryptonightR_instruction46(void);
+void CryptonightR_instruction47(void);
+void CryptonightR_instruction48(void);
+void CryptonightR_instruction49(void);
+void CryptonightR_instruction50(void);
+void CryptonightR_instruction51(void);
+void CryptonightR_instruction52(void);
+void CryptonightR_instruction53(void);
+void CryptonightR_instruction54(void);
+void CryptonightR_instruction55(void);
+void CryptonightR_instruction56(void);
+void CryptonightR_instruction57(void);
+void CryptonightR_instruction58(void);
+void CryptonightR_instruction59(void);
+void CryptonightR_instruction60(void);
+void CryptonightR_instruction61(void);
+void CryptonightR_instruction62(void);
+void CryptonightR_instruction63(void);
+void CryptonightR_instruction64(void);
+void CryptonightR_instruction65(void);
+void CryptonightR_instruction66(void);
+void CryptonightR_instruction67(void);
+void CryptonightR_instruction68(void);
+void CryptonightR_instruction69(void);
+void CryptonightR_instruction70(void);
+void CryptonightR_instruction71(void);
+void CryptonightR_instruction72(void);
+void CryptonightR_instruction73(void);
+void CryptonightR_instruction74(void);
+void CryptonightR_instruction75(void);
+void CryptonightR_instruction76(void);
+void CryptonightR_instruction77(void);
+void CryptonightR_instruction78(void);
+void CryptonightR_instruction79(void);
+void CryptonightR_instruction80(void);
+void CryptonightR_instruction81(void);
+void CryptonightR_instruction82(void);
+void CryptonightR_instruction83(void);
+void CryptonightR_instruction84(void);
+void CryptonightR_instruction85(void);
+void CryptonightR_instruction86(void);
+void CryptonightR_instruction87(void);
+void CryptonightR_instruction88(void);
+void CryptonightR_instruction89(void);
+void CryptonightR_instruction90(void);
+void CryptonightR_instruction91(void);
+void CryptonightR_instruction92(void);
+void CryptonightR_instruction93(void);
+void CryptonightR_instruction94(void);
+void CryptonightR_instruction95(void);
+void CryptonightR_instruction96(void);
+void CryptonightR_instruction97(void);
+void CryptonightR_instruction98(void);
+void CryptonightR_instruction99(void);
+void CryptonightR_instruction100(void);
+void CryptonightR_instruction101(void);
+void CryptonightR_instruction102(void);
+void CryptonightR_instruction103(void);
+void CryptonightR_instruction104(void);
+void CryptonightR_instruction105(void);
+void CryptonightR_instruction106(void);
+void CryptonightR_instruction107(void);
+void CryptonightR_instruction108(void);
+void CryptonightR_instruction109(void);
+void CryptonightR_instruction110(void);
+void CryptonightR_instruction111(void);
+void CryptonightR_instruction112(void);
+void CryptonightR_instruction113(void);
+void CryptonightR_instruction114(void);
+void CryptonightR_instruction115(void);
+void CryptonightR_instruction116(void);
+void CryptonightR_instruction117(void);
+void CryptonightR_instruction118(void);
+void CryptonightR_instruction119(void);
+void CryptonightR_instruction120(void);
+void CryptonightR_instruction121(void);
+void CryptonightR_instruction122(void);
+void CryptonightR_instruction123(void);
+void CryptonightR_instruction124(void);
+void CryptonightR_instruction125(void);
+void CryptonightR_instruction126(void);
+void CryptonightR_instruction127(void);
+void CryptonightR_instruction128(void);
+void CryptonightR_instruction129(void);
+void CryptonightR_instruction130(void);
+void CryptonightR_instruction131(void);
+void CryptonightR_instruction132(void);
+void CryptonightR_instruction133(void);
+void CryptonightR_instruction134(void);
+void CryptonightR_instruction135(void);
+void CryptonightR_instruction136(void);
+void CryptonightR_instruction137(void);
+void CryptonightR_instruction138(void);
+void CryptonightR_instruction139(void);
+void CryptonightR_instruction140(void);
+void CryptonightR_instruction141(void);
+void CryptonightR_instruction142(void);
+void CryptonightR_instruction143(void);
+void CryptonightR_instruction144(void);
+void CryptonightR_instruction145(void);
+void CryptonightR_instruction146(void);
+void CryptonightR_instruction147(void);
+void CryptonightR_instruction148(void);
+void CryptonightR_instruction149(void);
+void CryptonightR_instruction150(void);
+void CryptonightR_instruction151(void);
+void CryptonightR_instruction152(void);
+void CryptonightR_instruction153(void);
+void CryptonightR_instruction154(void);
+void CryptonightR_instruction155(void);
+void CryptonightR_instruction156(void);
+void CryptonightR_instruction157(void);
+void CryptonightR_instruction158(void);
+void CryptonightR_instruction159(void);
+void CryptonightR_instruction160(void);
+void CryptonightR_instruction161(void);
+void CryptonightR_instruction162(void);
+void CryptonightR_instruction163(void);
+void CryptonightR_instruction164(void);
+void CryptonightR_instruction165(void);
+void CryptonightR_instruction166(void);
+void CryptonightR_instruction167(void);
+void CryptonightR_instruction168(void);
+void CryptonightR_instruction169(void);
+void CryptonightR_instruction170(void);
+void CryptonightR_instruction171(void);
+void CryptonightR_instruction172(void);
+void CryptonightR_instruction173(void);
+void CryptonightR_instruction174(void);
+void CryptonightR_instruction175(void);
+void CryptonightR_instruction176(void);
+void CryptonightR_instruction177(void);
+void CryptonightR_instruction178(void);
+void CryptonightR_instruction179(void);
+void CryptonightR_instruction180(void);
+void CryptonightR_instruction181(void);
+void CryptonightR_instruction182(void);
+void CryptonightR_instruction183(void);
+void CryptonightR_instruction184(void);
+void CryptonightR_instruction185(void);
+void CryptonightR_instruction186(void);
+void CryptonightR_instruction187(void);
+void CryptonightR_instruction188(void);
+void CryptonightR_instruction189(void);
+void CryptonightR_instruction190(void);
+void CryptonightR_instruction191(void);
+void CryptonightR_instruction192(void);
+void CryptonightR_instruction193(void);
+void CryptonightR_instruction194(void);
+void CryptonightR_instruction195(void);
+void CryptonightR_instruction196(void);
+void CryptonightR_instruction197(void);
+void CryptonightR_instruction198(void);
+void CryptonightR_instruction199(void);
+void CryptonightR_instruction200(void);
+void CryptonightR_instruction201(void);
+void CryptonightR_instruction202(void);
+void CryptonightR_instruction203(void);
+void CryptonightR_instruction204(void);
+void CryptonightR_instruction205(void);
+void CryptonightR_instruction206(void);
+void CryptonightR_instruction207(void);
+void CryptonightR_instruction208(void);
+void CryptonightR_instruction209(void);
+void CryptonightR_instruction210(void);
+void CryptonightR_instruction211(void);
+void CryptonightR_instruction212(void);
+void CryptonightR_instruction213(void);
+void CryptonightR_instruction214(void);
+void CryptonightR_instruction215(void);
+void CryptonightR_instruction216(void);
+void CryptonightR_instruction217(void);
+void CryptonightR_instruction218(void);
+void CryptonightR_instruction219(void);
+void CryptonightR_instruction220(void);
+void CryptonightR_instruction221(void);
+void CryptonightR_instruction222(void);
+void CryptonightR_instruction223(void);
+void CryptonightR_instruction224(void);
+void CryptonightR_instruction225(void);
+void CryptonightR_instruction226(void);
+void CryptonightR_instruction227(void);
+void CryptonightR_instruction228(void);
+void CryptonightR_instruction229(void);
+void CryptonightR_instruction230(void);
+void CryptonightR_instruction231(void);
+void CryptonightR_instruction232(void);
+void CryptonightR_instruction233(void);
+void CryptonightR_instruction234(void);
+void CryptonightR_instruction235(void);
+void CryptonightR_instruction236(void);
+void CryptonightR_instruction237(void);
+void CryptonightR_instruction238(void);
+void CryptonightR_instruction239(void);
+void CryptonightR_instruction240(void);
+void CryptonightR_instruction241(void);
+void CryptonightR_instruction242(void);
+void CryptonightR_instruction243(void);
+void CryptonightR_instruction244(void);
+void CryptonightR_instruction245(void);
+void CryptonightR_instruction246(void);
+void CryptonightR_instruction247(void);
+void CryptonightR_instruction248(void);
+void CryptonightR_instruction249(void);
+void CryptonightR_instruction250(void);
+void CryptonightR_instruction251(void);
+void CryptonightR_instruction252(void);
+void CryptonightR_instruction253(void);
+void CryptonightR_instruction254(void);
+void CryptonightR_instruction255(void);
+void CryptonightR_instruction256(void);
+void CryptonightR_instruction_mov0(void);
+void CryptonightR_instruction_mov1(void);
+void CryptonightR_instruction_mov2(void);
+void CryptonightR_instruction_mov3(void);
+void CryptonightR_instruction_mov4(void);
+void CryptonightR_instruction_mov5(void);
+void CryptonightR_instruction_mov6(void);
+void CryptonightR_instruction_mov7(void);
+void CryptonightR_instruction_mov8(void);
+void CryptonightR_instruction_mov9(void);
+void CryptonightR_instruction_mov10(void);
+void CryptonightR_instruction_mov11(void);
+void CryptonightR_instruction_mov12(void);
+void CryptonightR_instruction_mov13(void);
+void CryptonightR_instruction_mov14(void);
+void CryptonightR_instruction_mov15(void);
+void CryptonightR_instruction_mov16(void);
+void CryptonightR_instruction_mov17(void);
+void CryptonightR_instruction_mov18(void);
+void CryptonightR_instruction_mov19(void);
+void CryptonightR_instruction_mov20(void);
+void CryptonightR_instruction_mov21(void);
+void CryptonightR_instruction_mov22(void);
+void CryptonightR_instruction_mov23(void);
+void CryptonightR_instruction_mov24(void);
+void CryptonightR_instruction_mov25(void);
+void CryptonightR_instruction_mov26(void);
+void CryptonightR_instruction_mov27(void);
+void CryptonightR_instruction_mov28(void);
+void CryptonightR_instruction_mov29(void);
+void CryptonightR_instruction_mov30(void);
+void CryptonightR_instruction_mov31(void);
+void CryptonightR_instruction_mov32(void);
+void CryptonightR_instruction_mov33(void);
+void CryptonightR_instruction_mov34(void);
+void CryptonightR_instruction_mov35(void);
+void CryptonightR_instruction_mov36(void);
+void CryptonightR_instruction_mov37(void);
+void CryptonightR_instruction_mov38(void);
+void CryptonightR_instruction_mov39(void);
+void CryptonightR_instruction_mov40(void);
+void CryptonightR_instruction_mov41(void);
+void CryptonightR_instruction_mov42(void);
+void CryptonightR_instruction_mov43(void);
+void CryptonightR_instruction_mov44(void);
+void CryptonightR_instruction_mov45(void);
+void CryptonightR_instruction_mov46(void);
+void CryptonightR_instruction_mov47(void);
+void CryptonightR_instruction_mov48(void);
+void CryptonightR_instruction_mov49(void);
+void CryptonightR_instruction_mov50(void);
+void CryptonightR_instruction_mov51(void);
+void CryptonightR_instruction_mov52(void);
+void CryptonightR_instruction_mov53(void);
+void CryptonightR_instruction_mov54(void);
+void CryptonightR_instruction_mov55(void);
+void CryptonightR_instruction_mov56(void);
+void CryptonightR_instruction_mov57(void);
+void CryptonightR_instruction_mov58(void);
+void CryptonightR_instruction_mov59(void);
+void CryptonightR_instruction_mov60(void);
+void CryptonightR_instruction_mov61(void);
+void CryptonightR_instruction_mov62(void);
+void CryptonightR_instruction_mov63(void);
+void CryptonightR_instruction_mov64(void);
+void CryptonightR_instruction_mov65(void);
+void CryptonightR_instruction_mov66(void);
+void CryptonightR_instruction_mov67(void);
+void CryptonightR_instruction_mov68(void);
+void CryptonightR_instruction_mov69(void);
+void CryptonightR_instruction_mov70(void);
+void CryptonightR_instruction_mov71(void);
+void CryptonightR_instruction_mov72(void);
+void CryptonightR_instruction_mov73(void);
+void CryptonightR_instruction_mov74(void);
+void CryptonightR_instruction_mov75(void);
+void CryptonightR_instruction_mov76(void);
+void CryptonightR_instruction_mov77(void);
+void CryptonightR_instruction_mov78(void);
+void CryptonightR_instruction_mov79(void);
+void CryptonightR_instruction_mov80(void);
+void CryptonightR_instruction_mov81(void);
+void CryptonightR_instruction_mov82(void);
+void CryptonightR_instruction_mov83(void);
+void CryptonightR_instruction_mov84(void);
+void CryptonightR_instruction_mov85(void);
+void CryptonightR_instruction_mov86(void);
+void CryptonightR_instruction_mov87(void);
+void CryptonightR_instruction_mov88(void);
+void CryptonightR_instruction_mov89(void);
+void CryptonightR_instruction_mov90(void);
+void CryptonightR_instruction_mov91(void);
+void CryptonightR_instruction_mov92(void);
+void CryptonightR_instruction_mov93(void);
+void CryptonightR_instruction_mov94(void);
+void CryptonightR_instruction_mov95(void);
+void CryptonightR_instruction_mov96(void);
+void CryptonightR_instruction_mov97(void);
+void CryptonightR_instruction_mov98(void);
+void CryptonightR_instruction_mov99(void);
+void CryptonightR_instruction_mov100(void);
+void CryptonightR_instruction_mov101(void);
+void CryptonightR_instruction_mov102(void);
+void CryptonightR_instruction_mov103(void);
+void CryptonightR_instruction_mov104(void);
+void CryptonightR_instruction_mov105(void);
+void CryptonightR_instruction_mov106(void);
+void CryptonightR_instruction_mov107(void);
+void CryptonightR_instruction_mov108(void);
+void CryptonightR_instruction_mov109(void);
+void CryptonightR_instruction_mov110(void);
+void CryptonightR_instruction_mov111(void);
+void CryptonightR_instruction_mov112(void);
+void CryptonightR_instruction_mov113(void);
+void CryptonightR_instruction_mov114(void);
+void CryptonightR_instruction_mov115(void);
+void CryptonightR_instruction_mov116(void);
+void CryptonightR_instruction_mov117(void);
+void CryptonightR_instruction_mov118(void);
+void CryptonightR_instruction_mov119(void);
+void CryptonightR_instruction_mov120(void);
+void CryptonightR_instruction_mov121(void);
+void CryptonightR_instruction_mov122(void);
+void CryptonightR_instruction_mov123(void);
+void CryptonightR_instruction_mov124(void);
+void CryptonightR_instruction_mov125(void);
+void CryptonightR_instruction_mov126(void);
+void CryptonightR_instruction_mov127(void);
+void CryptonightR_instruction_mov128(void);
+void CryptonightR_instruction_mov129(void);
+void CryptonightR_instruction_mov130(void);
+void CryptonightR_instruction_mov131(void);
+void CryptonightR_instruction_mov132(void);
+void CryptonightR_instruction_mov133(void);
+void CryptonightR_instruction_mov134(void);
+void CryptonightR_instruction_mov135(void);
+void CryptonightR_instruction_mov136(void);
+void CryptonightR_instruction_mov137(void);
+void CryptonightR_instruction_mov138(void);
+void CryptonightR_instruction_mov139(void);
+void CryptonightR_instruction_mov140(void);
+void CryptonightR_instruction_mov141(void);
+void CryptonightR_instruction_mov142(void);
+void CryptonightR_instruction_mov143(void);
+void CryptonightR_instruction_mov144(void);
+void CryptonightR_instruction_mov145(void);
+void CryptonightR_instruction_mov146(void);
+void CryptonightR_instruction_mov147(void);
+void CryptonightR_instruction_mov148(void);
+void CryptonightR_instruction_mov149(void);
+void CryptonightR_instruction_mov150(void);
+void CryptonightR_instruction_mov151(void);
+void CryptonightR_instruction_mov152(void);
+void CryptonightR_instruction_mov153(void);
+void CryptonightR_instruction_mov154(void);
+void CryptonightR_instruction_mov155(void);
+void CryptonightR_instruction_mov156(void);
+void CryptonightR_instruction_mov157(void);
+void CryptonightR_instruction_mov158(void);
+void CryptonightR_instruction_mov159(void);
+void CryptonightR_instruction_mov160(void);
+void CryptonightR_instruction_mov161(void);
+void CryptonightR_instruction_mov162(void);
+void CryptonightR_instruction_mov163(void);
+void CryptonightR_instruction_mov164(void);
+void CryptonightR_instruction_mov165(void);
+void CryptonightR_instruction_mov166(void);
+void CryptonightR_instruction_mov167(void);
+void CryptonightR_instruction_mov168(void);
+void CryptonightR_instruction_mov169(void);
+void CryptonightR_instruction_mov170(void);
+void CryptonightR_instruction_mov171(void);
+void CryptonightR_instruction_mov172(void);
+void CryptonightR_instruction_mov173(void);
+void CryptonightR_instruction_mov174(void);
+void CryptonightR_instruction_mov175(void);
+void CryptonightR_instruction_mov176(void);
+void CryptonightR_instruction_mov177(void);
+void CryptonightR_instruction_mov178(void);
+void CryptonightR_instruction_mov179(void);
+void CryptonightR_instruction_mov180(void);
+void CryptonightR_instruction_mov181(void);
+void CryptonightR_instruction_mov182(void);
+void CryptonightR_instruction_mov183(void);
+void CryptonightR_instruction_mov184(void);
+void CryptonightR_instruction_mov185(void);
+void CryptonightR_instruction_mov186(void);
+void CryptonightR_instruction_mov187(void);
+void CryptonightR_instruction_mov188(void);
+void CryptonightR_instruction_mov189(void);
+void CryptonightR_instruction_mov190(void);
+void CryptonightR_instruction_mov191(void);
+void CryptonightR_instruction_mov192(void);
+void CryptonightR_instruction_mov193(void);
+void CryptonightR_instruction_mov194(void);
+void CryptonightR_instruction_mov195(void);
+void CryptonightR_instruction_mov196(void);
+void CryptonightR_instruction_mov197(void);
+void CryptonightR_instruction_mov198(void);
+void CryptonightR_instruction_mov199(void);
+void CryptonightR_instruction_mov200(void);
+void CryptonightR_instruction_mov201(void);
+void CryptonightR_instruction_mov202(void);
+void CryptonightR_instruction_mov203(void);
+void CryptonightR_instruction_mov204(void);
+void CryptonightR_instruction_mov205(void);
+void CryptonightR_instruction_mov206(void);
+void CryptonightR_instruction_mov207(void);
+void CryptonightR_instruction_mov208(void);
+void CryptonightR_instruction_mov209(void);
+void CryptonightR_instruction_mov210(void);
+void CryptonightR_instruction_mov211(void);
+void CryptonightR_instruction_mov212(void);
+void CryptonightR_instruction_mov213(void);
+void CryptonightR_instruction_mov214(void);
+void CryptonightR_instruction_mov215(void);
+void CryptonightR_instruction_mov216(void);
+void CryptonightR_instruction_mov217(void);
+void CryptonightR_instruction_mov218(void);
+void CryptonightR_instruction_mov219(void);
+void CryptonightR_instruction_mov220(void);
+void CryptonightR_instruction_mov221(void);
+void CryptonightR_instruction_mov222(void);
+void CryptonightR_instruction_mov223(void);
+void CryptonightR_instruction_mov224(void);
+void CryptonightR_instruction_mov225(void);
+void CryptonightR_instruction_mov226(void);
+void CryptonightR_instruction_mov227(void);
+void CryptonightR_instruction_mov228(void);
+void CryptonightR_instruction_mov229(void);
+void CryptonightR_instruction_mov230(void);
+void CryptonightR_instruction_mov231(void);
+void CryptonightR_instruction_mov232(void);
+void CryptonightR_instruction_mov233(void);
+void CryptonightR_instruction_mov234(void);
+void CryptonightR_instruction_mov235(void);
+void CryptonightR_instruction_mov236(void);
+void CryptonightR_instruction_mov237(void);
+void CryptonightR_instruction_mov238(void);
+void CryptonightR_instruction_mov239(void);
+void CryptonightR_instruction_mov240(void);
+void CryptonightR_instruction_mov241(void);
+void CryptonightR_instruction_mov242(void);
+void CryptonightR_instruction_mov243(void);
+void CryptonightR_instruction_mov244(void);
+void CryptonightR_instruction_mov245(void);
+void CryptonightR_instruction_mov246(void);
+void CryptonightR_instruction_mov247(void);
+void CryptonightR_instruction_mov248(void);
+void CryptonightR_instruction_mov249(void);
+void CryptonightR_instruction_mov250(void);
+void CryptonightR_instruction_mov251(void);
+void CryptonightR_instruction_mov252(void);
+void CryptonightR_instruction_mov253(void);
+void CryptonightR_instruction_mov254(void);
+void CryptonightR_instruction_mov255(void);
+void CryptonightR_instruction_mov256(void);
+
+const void* instructions[257] = {
+ CryptonightR_instruction0,
+ CryptonightR_instruction1,
+ CryptonightR_instruction2,
+ CryptonightR_instruction3,
+ CryptonightR_instruction4,
+ CryptonightR_instruction5,
+ CryptonightR_instruction6,
+ CryptonightR_instruction7,
+ CryptonightR_instruction8,
+ CryptonightR_instruction9,
+ CryptonightR_instruction10,
+ CryptonightR_instruction11,
+ CryptonightR_instruction12,
+ CryptonightR_instruction13,
+ CryptonightR_instruction14,
+ CryptonightR_instruction15,
+ CryptonightR_instruction16,
+ CryptonightR_instruction17,
+ CryptonightR_instruction18,
+ CryptonightR_instruction19,
+ CryptonightR_instruction20,
+ CryptonightR_instruction21,
+ CryptonightR_instruction22,
+ CryptonightR_instruction23,
+ CryptonightR_instruction24,
+ CryptonightR_instruction25,
+ CryptonightR_instruction26,
+ CryptonightR_instruction27,
+ CryptonightR_instruction28,
+ CryptonightR_instruction29,
+ CryptonightR_instruction30,
+ CryptonightR_instruction31,
+ CryptonightR_instruction32,
+ CryptonightR_instruction33,
+ CryptonightR_instruction34,
+ CryptonightR_instruction35,
+ CryptonightR_instruction36,
+ CryptonightR_instruction37,
+ CryptonightR_instruction38,
+ CryptonightR_instruction39,
+ CryptonightR_instruction40,
+ CryptonightR_instruction41,
+ CryptonightR_instruction42,
+ CryptonightR_instruction43,
+ CryptonightR_instruction44,
+ CryptonightR_instruction45,
+ CryptonightR_instruction46,
+ CryptonightR_instruction47,
+ CryptonightR_instruction48,
+ CryptonightR_instruction49,
+ CryptonightR_instruction50,
+ CryptonightR_instruction51,
+ CryptonightR_instruction52,
+ CryptonightR_instruction53,
+ CryptonightR_instruction54,
+ CryptonightR_instruction55,
+ CryptonightR_instruction56,
+ CryptonightR_instruction57,
+ CryptonightR_instruction58,
+ CryptonightR_instruction59,
+ CryptonightR_instruction60,
+ CryptonightR_instruction61,
+ CryptonightR_instruction62,
+ CryptonightR_instruction63,
+ CryptonightR_instruction64,
+ CryptonightR_instruction65,
+ CryptonightR_instruction66,
+ CryptonightR_instruction67,
+ CryptonightR_instruction68,
+ CryptonightR_instruction69,
+ CryptonightR_instruction70,
+ CryptonightR_instruction71,
+ CryptonightR_instruction72,
+ CryptonightR_instruction73,
+ CryptonightR_instruction74,
+ CryptonightR_instruction75,
+ CryptonightR_instruction76,
+ CryptonightR_instruction77,
+ CryptonightR_instruction78,
+ CryptonightR_instruction79,
+ CryptonightR_instruction80,
+ CryptonightR_instruction81,
+ CryptonightR_instruction82,
+ CryptonightR_instruction83,
+ CryptonightR_instruction84,
+ CryptonightR_instruction85,
+ CryptonightR_instruction86,
+ CryptonightR_instruction87,
+ CryptonightR_instruction88,
+ CryptonightR_instruction89,
+ CryptonightR_instruction90,
+ CryptonightR_instruction91,
+ CryptonightR_instruction92,
+ CryptonightR_instruction93,
+ CryptonightR_instruction94,
+ CryptonightR_instruction95,
+ CryptonightR_instruction96,
+ CryptonightR_instruction97,
+ CryptonightR_instruction98,
+ CryptonightR_instruction99,
+ CryptonightR_instruction100,
+ CryptonightR_instruction101,
+ CryptonightR_instruction102,
+ CryptonightR_instruction103,
+ CryptonightR_instruction104,
+ CryptonightR_instruction105,
+ CryptonightR_instruction106,
+ CryptonightR_instruction107,
+ CryptonightR_instruction108,
+ CryptonightR_instruction109,
+ CryptonightR_instruction110,
+ CryptonightR_instruction111,
+ CryptonightR_instruction112,
+ CryptonightR_instruction113,
+ CryptonightR_instruction114,
+ CryptonightR_instruction115,
+ CryptonightR_instruction116,
+ CryptonightR_instruction117,
+ CryptonightR_instruction118,
+ CryptonightR_instruction119,
+ CryptonightR_instruction120,
+ CryptonightR_instruction121,
+ CryptonightR_instruction122,
+ CryptonightR_instruction123,
+ CryptonightR_instruction124,
+ CryptonightR_instruction125,
+ CryptonightR_instruction126,
+ CryptonightR_instruction127,
+ CryptonightR_instruction128,
+ CryptonightR_instruction129,
+ CryptonightR_instruction130,
+ CryptonightR_instruction131,
+ CryptonightR_instruction132,
+ CryptonightR_instruction133,
+ CryptonightR_instruction134,
+ CryptonightR_instruction135,
+ CryptonightR_instruction136,
+ CryptonightR_instruction137,
+ CryptonightR_instruction138,
+ CryptonightR_instruction139,
+ CryptonightR_instruction140,
+ CryptonightR_instruction141,
+ CryptonightR_instruction142,
+ CryptonightR_instruction143,
+ CryptonightR_instruction144,
+ CryptonightR_instruction145,
+ CryptonightR_instruction146,
+ CryptonightR_instruction147,
+ CryptonightR_instruction148,
+ CryptonightR_instruction149,
+ CryptonightR_instruction150,
+ CryptonightR_instruction151,
+ CryptonightR_instruction152,
+ CryptonightR_instruction153,
+ CryptonightR_instruction154,
+ CryptonightR_instruction155,
+ CryptonightR_instruction156,
+ CryptonightR_instruction157,
+ CryptonightR_instruction158,
+ CryptonightR_instruction159,
+ CryptonightR_instruction160,
+ CryptonightR_instruction161,
+ CryptonightR_instruction162,
+ CryptonightR_instruction163,
+ CryptonightR_instruction164,
+ CryptonightR_instruction165,
+ CryptonightR_instruction166,
+ CryptonightR_instruction167,
+ CryptonightR_instruction168,
+ CryptonightR_instruction169,
+ CryptonightR_instruction170,
+ CryptonightR_instruction171,
+ CryptonightR_instruction172,
+ CryptonightR_instruction173,
+ CryptonightR_instruction174,
+ CryptonightR_instruction175,
+ CryptonightR_instruction176,
+ CryptonightR_instruction177,
+ CryptonightR_instruction178,
+ CryptonightR_instruction179,
+ CryptonightR_instruction180,
+ CryptonightR_instruction181,
+ CryptonightR_instruction182,
+ CryptonightR_instruction183,
+ CryptonightR_instruction184,
+ CryptonightR_instruction185,
+ CryptonightR_instruction186,
+ CryptonightR_instruction187,
+ CryptonightR_instruction188,
+ CryptonightR_instruction189,
+ CryptonightR_instruction190,
+ CryptonightR_instruction191,
+ CryptonightR_instruction192,
+ CryptonightR_instruction193,
+ CryptonightR_instruction194,
+ CryptonightR_instruction195,
+ CryptonightR_instruction196,
+ CryptonightR_instruction197,
+ CryptonightR_instruction198,
+ CryptonightR_instruction199,
+ CryptonightR_instruction200,
+ CryptonightR_instruction201,
+ CryptonightR_instruction202,
+ CryptonightR_instruction203,
+ CryptonightR_instruction204,
+ CryptonightR_instruction205,
+ CryptonightR_instruction206,
+ CryptonightR_instruction207,
+ CryptonightR_instruction208,
+ CryptonightR_instruction209,
+ CryptonightR_instruction210,
+ CryptonightR_instruction211,
+ CryptonightR_instruction212,
+ CryptonightR_instruction213,
+ CryptonightR_instruction214,
+ CryptonightR_instruction215,
+ CryptonightR_instruction216,
+ CryptonightR_instruction217,
+ CryptonightR_instruction218,
+ CryptonightR_instruction219,
+ CryptonightR_instruction220,
+ CryptonightR_instruction221,
+ CryptonightR_instruction222,
+ CryptonightR_instruction223,
+ CryptonightR_instruction224,
+ CryptonightR_instruction225,
+ CryptonightR_instruction226,
+ CryptonightR_instruction227,
+ CryptonightR_instruction228,
+ CryptonightR_instruction229,
+ CryptonightR_instruction230,
+ CryptonightR_instruction231,
+ CryptonightR_instruction232,
+ CryptonightR_instruction233,
+ CryptonightR_instruction234,
+ CryptonightR_instruction235,
+ CryptonightR_instruction236,
+ CryptonightR_instruction237,
+ CryptonightR_instruction238,
+ CryptonightR_instruction239,
+ CryptonightR_instruction240,
+ CryptonightR_instruction241,
+ CryptonightR_instruction242,
+ CryptonightR_instruction243,
+ CryptonightR_instruction244,
+ CryptonightR_instruction245,
+ CryptonightR_instruction246,
+ CryptonightR_instruction247,
+ CryptonightR_instruction248,
+ CryptonightR_instruction249,
+ CryptonightR_instruction250,
+ CryptonightR_instruction251,
+ CryptonightR_instruction252,
+ CryptonightR_instruction253,
+ CryptonightR_instruction254,
+ CryptonightR_instruction255,
+ CryptonightR_instruction256,
+};
+
+const void* instructions_mov[257] = {
+ CryptonightR_instruction_mov0,
+ CryptonightR_instruction_mov1,
+ CryptonightR_instruction_mov2,
+ CryptonightR_instruction_mov3,
+ CryptonightR_instruction_mov4,
+ CryptonightR_instruction_mov5,
+ CryptonightR_instruction_mov6,
+ CryptonightR_instruction_mov7,
+ CryptonightR_instruction_mov8,
+ CryptonightR_instruction_mov9,
+ CryptonightR_instruction_mov10,
+ CryptonightR_instruction_mov11,
+ CryptonightR_instruction_mov12,
+ CryptonightR_instruction_mov13,
+ CryptonightR_instruction_mov14,
+ CryptonightR_instruction_mov15,
+ CryptonightR_instruction_mov16,
+ CryptonightR_instruction_mov17,
+ CryptonightR_instruction_mov18,
+ CryptonightR_instruction_mov19,
+ CryptonightR_instruction_mov20,
+ CryptonightR_instruction_mov21,
+ CryptonightR_instruction_mov22,
+ CryptonightR_instruction_mov23,
+ CryptonightR_instruction_mov24,
+ CryptonightR_instruction_mov25,
+ CryptonightR_instruction_mov26,
+ CryptonightR_instruction_mov27,
+ CryptonightR_instruction_mov28,
+ CryptonightR_instruction_mov29,
+ CryptonightR_instruction_mov30,
+ CryptonightR_instruction_mov31,
+ CryptonightR_instruction_mov32,
+ CryptonightR_instruction_mov33,
+ CryptonightR_instruction_mov34,
+ CryptonightR_instruction_mov35,
+ CryptonightR_instruction_mov36,
+ CryptonightR_instruction_mov37,
+ CryptonightR_instruction_mov38,
+ CryptonightR_instruction_mov39,
+ CryptonightR_instruction_mov40,
+ CryptonightR_instruction_mov41,
+ CryptonightR_instruction_mov42,
+ CryptonightR_instruction_mov43,
+ CryptonightR_instruction_mov44,
+ CryptonightR_instruction_mov45,
+ CryptonightR_instruction_mov46,
+ CryptonightR_instruction_mov47,
+ CryptonightR_instruction_mov48,
+ CryptonightR_instruction_mov49,
+ CryptonightR_instruction_mov50,
+ CryptonightR_instruction_mov51,
+ CryptonightR_instruction_mov52,
+ CryptonightR_instruction_mov53,
+ CryptonightR_instruction_mov54,
+ CryptonightR_instruction_mov55,
+ CryptonightR_instruction_mov56,
+ CryptonightR_instruction_mov57,
+ CryptonightR_instruction_mov58,
+ CryptonightR_instruction_mov59,
+ CryptonightR_instruction_mov60,
+ CryptonightR_instruction_mov61,
+ CryptonightR_instruction_mov62,
+ CryptonightR_instruction_mov63,
+ CryptonightR_instruction_mov64,
+ CryptonightR_instruction_mov65,
+ CryptonightR_instruction_mov66,
+ CryptonightR_instruction_mov67,
+ CryptonightR_instruction_mov68,
+ CryptonightR_instruction_mov69,
+ CryptonightR_instruction_mov70,
+ CryptonightR_instruction_mov71,
+ CryptonightR_instruction_mov72,
+ CryptonightR_instruction_mov73,
+ CryptonightR_instruction_mov74,
+ CryptonightR_instruction_mov75,
+ CryptonightR_instruction_mov76,
+ CryptonightR_instruction_mov77,
+ CryptonightR_instruction_mov78,
+ CryptonightR_instruction_mov79,
+ CryptonightR_instruction_mov80,
+ CryptonightR_instruction_mov81,
+ CryptonightR_instruction_mov82,
+ CryptonightR_instruction_mov83,
+ CryptonightR_instruction_mov84,
+ CryptonightR_instruction_mov85,
+ CryptonightR_instruction_mov86,
+ CryptonightR_instruction_mov87,
+ CryptonightR_instruction_mov88,
+ CryptonightR_instruction_mov89,
+ CryptonightR_instruction_mov90,
+ CryptonightR_instruction_mov91,
+ CryptonightR_instruction_mov92,
+ CryptonightR_instruction_mov93,
+ CryptonightR_instruction_mov94,
+ CryptonightR_instruction_mov95,
+ CryptonightR_instruction_mov96,
+ CryptonightR_instruction_mov97,
+ CryptonightR_instruction_mov98,
+ CryptonightR_instruction_mov99,
+ CryptonightR_instruction_mov100,
+ CryptonightR_instruction_mov101,
+ CryptonightR_instruction_mov102,
+ CryptonightR_instruction_mov103,
+ CryptonightR_instruction_mov104,
+ CryptonightR_instruction_mov105,
+ CryptonightR_instruction_mov106,
+ CryptonightR_instruction_mov107,
+ CryptonightR_instruction_mov108,
+ CryptonightR_instruction_mov109,
+ CryptonightR_instruction_mov110,
+ CryptonightR_instruction_mov111,
+ CryptonightR_instruction_mov112,
+ CryptonightR_instruction_mov113,
+ CryptonightR_instruction_mov114,
+ CryptonightR_instruction_mov115,
+ CryptonightR_instruction_mov116,
+ CryptonightR_instruction_mov117,
+ CryptonightR_instruction_mov118,
+ CryptonightR_instruction_mov119,
+ CryptonightR_instruction_mov120,
+ CryptonightR_instruction_mov121,
+ CryptonightR_instruction_mov122,
+ CryptonightR_instruction_mov123,
+ CryptonightR_instruction_mov124,
+ CryptonightR_instruction_mov125,
+ CryptonightR_instruction_mov126,
+ CryptonightR_instruction_mov127,
+ CryptonightR_instruction_mov128,
+ CryptonightR_instruction_mov129,
+ CryptonightR_instruction_mov130,
+ CryptonightR_instruction_mov131,
+ CryptonightR_instruction_mov132,
+ CryptonightR_instruction_mov133,
+ CryptonightR_instruction_mov134,
+ CryptonightR_instruction_mov135,
+ CryptonightR_instruction_mov136,
+ CryptonightR_instruction_mov137,
+ CryptonightR_instruction_mov138,
+ CryptonightR_instruction_mov139,
+ CryptonightR_instruction_mov140,
+ CryptonightR_instruction_mov141,
+ CryptonightR_instruction_mov142,
+ CryptonightR_instruction_mov143,
+ CryptonightR_instruction_mov144,
+ CryptonightR_instruction_mov145,
+ CryptonightR_instruction_mov146,
+ CryptonightR_instruction_mov147,
+ CryptonightR_instruction_mov148,
+ CryptonightR_instruction_mov149,
+ CryptonightR_instruction_mov150,
+ CryptonightR_instruction_mov151,
+ CryptonightR_instruction_mov152,
+ CryptonightR_instruction_mov153,
+ CryptonightR_instruction_mov154,
+ CryptonightR_instruction_mov155,
+ CryptonightR_instruction_mov156,
+ CryptonightR_instruction_mov157,
+ CryptonightR_instruction_mov158,
+ CryptonightR_instruction_mov159,
+ CryptonightR_instruction_mov160,
+ CryptonightR_instruction_mov161,
+ CryptonightR_instruction_mov162,
+ CryptonightR_instruction_mov163,
+ CryptonightR_instruction_mov164,
+ CryptonightR_instruction_mov165,
+ CryptonightR_instruction_mov166,
+ CryptonightR_instruction_mov167,
+ CryptonightR_instruction_mov168,
+ CryptonightR_instruction_mov169,
+ CryptonightR_instruction_mov170,
+ CryptonightR_instruction_mov171,
+ CryptonightR_instruction_mov172,
+ CryptonightR_instruction_mov173,
+ CryptonightR_instruction_mov174,
+ CryptonightR_instruction_mov175,
+ CryptonightR_instruction_mov176,
+ CryptonightR_instruction_mov177,
+ CryptonightR_instruction_mov178,
+ CryptonightR_instruction_mov179,
+ CryptonightR_instruction_mov180,
+ CryptonightR_instruction_mov181,
+ CryptonightR_instruction_mov182,
+ CryptonightR_instruction_mov183,
+ CryptonightR_instruction_mov184,
+ CryptonightR_instruction_mov185,
+ CryptonightR_instruction_mov186,
+ CryptonightR_instruction_mov187,
+ CryptonightR_instruction_mov188,
+ CryptonightR_instruction_mov189,
+ CryptonightR_instruction_mov190,
+ CryptonightR_instruction_mov191,
+ CryptonightR_instruction_mov192,
+ CryptonightR_instruction_mov193,
+ CryptonightR_instruction_mov194,
+ CryptonightR_instruction_mov195,
+ CryptonightR_instruction_mov196,
+ CryptonightR_instruction_mov197,
+ CryptonightR_instruction_mov198,
+ CryptonightR_instruction_mov199,
+ CryptonightR_instruction_mov200,
+ CryptonightR_instruction_mov201,
+ CryptonightR_instruction_mov202,
+ CryptonightR_instruction_mov203,
+ CryptonightR_instruction_mov204,
+ CryptonightR_instruction_mov205,
+ CryptonightR_instruction_mov206,
+ CryptonightR_instruction_mov207,
+ CryptonightR_instruction_mov208,
+ CryptonightR_instruction_mov209,
+ CryptonightR_instruction_mov210,
+ CryptonightR_instruction_mov211,
+ CryptonightR_instruction_mov212,
+ CryptonightR_instruction_mov213,
+ CryptonightR_instruction_mov214,
+ CryptonightR_instruction_mov215,
+ CryptonightR_instruction_mov216,
+ CryptonightR_instruction_mov217,
+ CryptonightR_instruction_mov218,
+ CryptonightR_instruction_mov219,
+ CryptonightR_instruction_mov220,
+ CryptonightR_instruction_mov221,
+ CryptonightR_instruction_mov222,
+ CryptonightR_instruction_mov223,
+ CryptonightR_instruction_mov224,
+ CryptonightR_instruction_mov225,
+ CryptonightR_instruction_mov226,
+ CryptonightR_instruction_mov227,
+ CryptonightR_instruction_mov228,
+ CryptonightR_instruction_mov229,
+ CryptonightR_instruction_mov230,
+ CryptonightR_instruction_mov231,
+ CryptonightR_instruction_mov232,
+ CryptonightR_instruction_mov233,
+ CryptonightR_instruction_mov234,
+ CryptonightR_instruction_mov235,
+ CryptonightR_instruction_mov236,
+ CryptonightR_instruction_mov237,
+ CryptonightR_instruction_mov238,
+ CryptonightR_instruction_mov239,
+ CryptonightR_instruction_mov240,
+ CryptonightR_instruction_mov241,
+ CryptonightR_instruction_mov242,
+ CryptonightR_instruction_mov243,
+ CryptonightR_instruction_mov244,
+ CryptonightR_instruction_mov245,
+ CryptonightR_instruction_mov246,
+ CryptonightR_instruction_mov247,
+ CryptonightR_instruction_mov248,
+ CryptonightR_instruction_mov249,
+ CryptonightR_instruction_mov250,
+ CryptonightR_instruction_mov251,
+ CryptonightR_instruction_mov252,
+ CryptonightR_instruction_mov253,
+ CryptonightR_instruction_mov254,
+ CryptonightR_instruction_mov255,
+ CryptonightR_instruction_mov256,
+};
+
+#endif // CRYPTONIGHTR_TEMPLATE_H
diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h
index 6e85ad0e9..0610f7051 100644
--- a/src/crypto/chacha.h
+++ b/src/crypto/chacha.h
@@ -73,18 +73,18 @@ namespace crypto {
inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) {
static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key");
epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
- crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/);
+ crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/);
for (uint64_t n = 1; n < kdf_rounds; ++n)
- crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/);
+ crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/);
memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key));
}
inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) {
static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key");
epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
- crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/);
+ crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/, 0/*height*/);
for (uint64_t n = 1; n < kdf_rounds; ++n)
- crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/);
+ crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/);
memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key));
}
diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h
index 77b52e2d4..ba7ece0f5 100644
--- a/src/crypto/hash-ops.h
+++ b/src/crypto/hash-ops.h
@@ -79,7 +79,7 @@ enum {
};
void cn_fast_hash(const void *data, size_t length, char *hash);
-void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed);
+void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height);
void hash_extra_blake(const void *data, size_t length, char *hash);
void hash_extra_groestl(const void *data, size_t length, char *hash);
diff --git a/src/crypto/hash.h b/src/crypto/hash.h
index 995e2294e..165fe6bb0 100644
--- a/src/crypto/hash.h
+++ b/src/crypto/hash.h
@@ -71,12 +71,12 @@ namespace crypto {
return h;
}
- inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) {
- cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/);
+ inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
+ cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height);
}
- inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0) {
- cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/);
+ inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
+ cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height);
}
inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) {
diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c
index ae0bd4e98..2a8ddb59c 100644
--- a/src/crypto/slow-hash.c
+++ b/src/crypto/slow-hash.c
@@ -39,6 +39,11 @@
#include "hash-ops.h"
#include "oaes_lib.h"
#include "variant2_int_sqrt.h"
+#include "variant4_random_math.h"
+#include "CryptonightR_JIT.h"
+
+#include <errno.h>
+#include <string.h>
#define MEMORY (1 << 21) // 2MB scratchpad
#define ITER (1 << 20)
@@ -50,6 +55,16 @@
extern void aesb_single_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
+static void local_abort(const char *msg)
+{
+ fprintf(stderr, "%s\n", msg);
+#ifdef NDEBUG
+ _exit(1);
+#else
+ abort();
+#endif
+}
+
#define VARIANT1_1(p) \
do if (variant == 1) \
{ \
@@ -116,48 +131,74 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
#define VARIANT2_SHUFFLE_ADD_SSE2(base_ptr, offset) \
do if (variant >= 2) \
{ \
- const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \
+ __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
+ if (variant >= 4) \
+ { \
+ chunk1 = _mm_xor_si128(chunk1, chunk2); \
+ _c = _mm_xor_si128(_c, chunk3); \
+ _c = _mm_xor_si128(_c, chunk1); \
+ } \
} while (0)
#define VARIANT2_SHUFFLE_ADD_NEON(base_ptr, offset) \
do if (variant >= 2) \
{ \
- const uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \
+ uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \
const uint64x2_t chunk2 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x20))); \
const uint64x2_t chunk3 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
+ if (variant >= 4) \
+ { \
+ chunk1 = veorq_u64(chunk1, chunk2); \
+ _c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk3)); \
+ _c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk1)); \
+ } \
} while (0)
-#define VARIANT2_PORTABLE_SHUFFLE_ADD(base_ptr, offset) \
+#define VARIANT2_PORTABLE_SHUFFLE_ADD(out, a_, base_ptr, offset) \
do if (variant >= 2) \
{ \
uint64_t* chunk1 = U64((base_ptr) + ((offset) ^ 0x10)); \
uint64_t* chunk2 = U64((base_ptr) + ((offset) ^ 0x20)); \
uint64_t* chunk3 = U64((base_ptr) + ((offset) ^ 0x30)); \
\
- const uint64_t chunk1_old[2] = { chunk1[0], chunk1[1] }; \
+ uint64_t chunk1_old[2] = { SWAP64LE(chunk1[0]), SWAP64LE(chunk1[1]) }; \
+ const uint64_t chunk2_old[2] = { SWAP64LE(chunk2[0]), SWAP64LE(chunk2[1]) }; \
+ const uint64_t chunk3_old[2] = { SWAP64LE(chunk3[0]), SWAP64LE(chunk3[1]) }; \
\
uint64_t b1[2]; \
memcpy_swap64le(b1, b + 16, 2); \
- chunk1[0] = SWAP64LE(SWAP64LE(chunk3[0]) + b1[0]); \
- chunk1[1] = SWAP64LE(SWAP64LE(chunk3[1]) + b1[1]); \
+ chunk1[0] = SWAP64LE(chunk3_old[0] + b1[0]); \
+ chunk1[1] = SWAP64LE(chunk3_old[1] + b1[1]); \
\
uint64_t a0[2]; \
- memcpy_swap64le(a0, a, 2); \
- chunk3[0] = SWAP64LE(SWAP64LE(chunk2[0]) + a0[0]); \
- chunk3[1] = SWAP64LE(SWAP64LE(chunk2[1]) + a0[1]); \
+ memcpy_swap64le(a0, a_, 2); \
+ chunk3[0] = SWAP64LE(chunk2_old[0] + a0[0]); \
+ chunk3[1] = SWAP64LE(chunk2_old[1] + a0[1]); \
\
uint64_t b0[2]; \
memcpy_swap64le(b0, b, 2); \
- chunk2[0] = SWAP64LE(SWAP64LE(chunk1_old[0]) + b0[0]); \
+ chunk2[0] = SWAP64LE(chunk1_old[0] + b0[0]); \
chunk2[1] = SWAP64LE(SWAP64LE(chunk1_old[1]) + b0[1]); \
+ if (variant >= 4) \
+ { \
+ uint64_t out_copy[2]; \
+ memcpy_swap64le(out_copy, out, 2); \
+ chunk1_old[0] ^= chunk2_old[0]; \
+ chunk1_old[1] ^= chunk2_old[1]; \
+ out_copy[0] ^= chunk3_old[0]; \
+ out_copy[1] ^= chunk3_old[1]; \
+ out_copy[0] ^= chunk1_old[0]; \
+ out_copy[1] ^= chunk1_old[1]; \
+ memcpy_swap64le(out, out_copy, 2); \
+ } \
} while (0)
#define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr) \
@@ -172,7 +213,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
const uint64_t sqrt_input = SWAP64LE(((uint64_t*)(ptr))[0]) + division_result
#define VARIANT2_INTEGER_MATH_SSE2(b, ptr) \
- do if (variant >= 2) \
+ do if ((variant == 2) || (variant == 3)) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2(); \
@@ -182,7 +223,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
#if defined DBL_MANT_DIG && (DBL_MANT_DIG >= 50)
// double precision floating point type has enough bits of precision on current platform
#define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \
- do if (variant >= 2) \
+ do if ((variant == 2) || (variant == 3)) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_FP64(); \
@@ -192,7 +233,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
// double precision floating point type is not good enough on current platform
// fall back to the reference code (integer only)
#define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \
- do if (variant >= 2) \
+ do if ((variant == 2) || (variant == 3)) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_REF(); \
@@ -200,13 +241,13 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
#endif
#define VARIANT2_2_PORTABLE() \
- if (variant >= 2) { \
+ if (variant == 2 || variant == 3) { \
xor_blocks(long_state + (j ^ 0x10), d); \
xor_blocks(d, long_state + (j ^ 0x20)); \
}
#define VARIANT2_2() \
- do if (variant >= 2) \
+ do if (variant == 2 || variant == 3) \
{ \
*U64(hp_state + (j ^ 0x10)) ^= SWAP64LE(hi); \
*(U64(hp_state + (j ^ 0x10)) + 1) ^= SWAP64LE(lo); \
@@ -214,6 +255,68 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
lo ^= SWAP64LE(*(U64(hp_state + (j ^ 0x20)) + 1)); \
} while (0)
+#define V4_REG_LOAD(dst, src) \
+ do { \
+ memcpy((dst), (src), sizeof(v4_reg)); \
+ if (sizeof(v4_reg) == sizeof(uint32_t)) \
+ *(dst) = SWAP32LE(*(dst)); \
+ else \
+ *(dst) = SWAP64LE(*(dst)); \
+ } while (0)
+
+#define VARIANT4_RANDOM_MATH_INIT() \
+ v4_reg r[9]; \
+ struct V4_Instruction code[NUM_INSTRUCTIONS_MAX + 1]; \
+ int jit = use_v4_jit(); \
+ do if (variant >= 4) \
+ { \
+ for (int i = 0; i < 4; ++i) \
+ V4_REG_LOAD(r + i, (uint8_t*)(state.hs.w + 12) + sizeof(v4_reg) * i); \
+ v4_random_math_init(code, height); \
+ if (jit) \
+ { \
+ int ret = v4_generate_JIT_code(code, hp_jitfunc, 4096); \
+ if (ret < 0) \
+ local_abort("Error generating CryptonightR code"); \
+ } \
+ } while (0)
+
+#define VARIANT4_RANDOM_MATH(a, b, r, _b, _b1) \
+ do if (variant >= 4) \
+ { \
+ uint64_t t[2]; \
+ memcpy(t, b, sizeof(uint64_t)); \
+ \
+ if (sizeof(v4_reg) == sizeof(uint32_t)) \
+ t[0] ^= SWAP64LE((r[0] + r[1]) | ((uint64_t)(r[2] + r[3]) << 32)); \
+ else \
+ t[0] ^= SWAP64LE((r[0] + r[1]) ^ (r[2] + r[3])); \
+ \
+ memcpy(b, t, sizeof(uint64_t)); \
+ \
+ V4_REG_LOAD(r + 4, a); \
+ V4_REG_LOAD(r + 5, (uint64_t*)(a) + 1); \
+ V4_REG_LOAD(r + 6, _b); \
+ V4_REG_LOAD(r + 7, _b1); \
+ V4_REG_LOAD(r + 8, (uint64_t*)(_b1) + 1); \
+ \
+ if (jit) \
+ (*hp_jitfunc)(r); \
+ else \
+ v4_random_math(code, r); \
+ \
+ memcpy(t, a, sizeof(uint64_t) * 2); \
+ \
+ if (sizeof(v4_reg) == sizeof(uint32_t)) { \
+ t[0] ^= SWAP64LE(r[2] | ((uint64_t)(r[3]) << 32)); \
+ t[1] ^= SWAP64LE(r[0] | ((uint64_t)(r[1]) << 32)); \
+ } else { \
+ t[0] ^= SWAP64LE(r[2] ^ r[3]); \
+ t[1] ^= SWAP64LE(r[0] ^ r[1]); \
+ } \
+ memcpy(a, t, sizeof(uint64_t) * 2); \
+ } while (0)
+
#if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64)))
// Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI
@@ -298,6 +401,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex
p = U64(&hp_state[j]); \
b[0] = p[0]; b[1] = p[1]; \
VARIANT2_INTEGER_MATH_SSE2(b, c); \
+ VARIANT4_RANDOM_MATH(a, b, r, &_b, &_b1); \
__mul(); \
VARIANT2_2(); \
VARIANT2_SHUFFLE_ADD_SSE2(hp_state, j); \
@@ -329,6 +433,9 @@ union cn_slow_hash_state
THREADV uint8_t *hp_state = NULL;
THREADV int hp_allocated = 0;
+THREADV v4_random_math_JIT_func hp_jitfunc = NULL;
+THREADV uint8_t *hp_jitfunc_memory = NULL;
+THREADV int hp_jitfunc_allocated = 0;
#if defined(_MSC_VER)
#define cpuid(info,x) __cpuidex(info,x,0)
@@ -387,6 +494,31 @@ STATIC INLINE int force_software_aes(void)
return use;
}
+volatile int use_v4_jit_flag = -1;
+
+STATIC INLINE int use_v4_jit(void)
+{
+#if defined(__x86_64__)
+
+ if (use_v4_jit_flag != -1)
+ return use_v4_jit_flag;
+
+ const char *env = getenv("MONERO_USE_CNV4_JIT");
+ if (!env) {
+ use_v4_jit_flag = 0;
+ }
+ else if (!strcmp(env, "0") || !strcmp(env, "no")) {
+ use_v4_jit_flag = 0;
+ }
+ else {
+ use_v4_jit_flag = 1;
+ }
+ return use_v4_jit_flag;
+#else
+ return 0;
+#endif
+}
+
STATIC INLINE int check_aes_hw(void)
{
int cpuid_results[4];
@@ -638,6 +770,33 @@ void slow_hash_allocate_state(void)
hp_allocated = 0;
hp_state = (uint8_t *) malloc(MEMORY);
}
+
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ hp_jitfunc_memory = (uint8_t *) VirtualAlloc(hp_jitfunc_memory, 4096 + 4095,
+ MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+#else
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(__DragonFly__) || defined(__NetBSD__)
+ hp_jitfunc_memory = mmap(0, 4096 + 4095, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, 0, 0);
+#else
+ hp_jitfunc_memory = mmap(0, 4096 + 4095, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+#endif
+ if(hp_jitfunc_memory == MAP_FAILED)
+ hp_jitfunc_memory = NULL;
+#endif
+ hp_jitfunc_allocated = 1;
+ if (hp_jitfunc_memory == NULL)
+ {
+ hp_jitfunc_allocated = 0;
+ hp_jitfunc_memory = malloc(4096 + 4095);
+ }
+ hp_jitfunc = (v4_random_math_JIT_func)((size_t)(hp_jitfunc_memory + 4095) & ~4095);
+#if !(defined(_MSC_VER) || defined(__MINGW32__))
+ mprotect(hp_jitfunc, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
+#endif
}
/**
@@ -660,8 +819,22 @@ void slow_hash_free_state(void)
#endif
}
+ if(!hp_jitfunc_allocated)
+ free(hp_jitfunc_memory);
+ else
+ {
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ VirtualFree(hp_jitfunc_memory, 0, MEM_RELEASE);
+#else
+ munmap(hp_jitfunc_memory, 4096 + 4095);
+#endif
+ }
+
hp_state = NULL;
hp_allocated = 0;
+ hp_jitfunc = NULL;
+ hp_jitfunc_memory = NULL;
+ hp_jitfunc_allocated = 0;
}
/**
@@ -694,7 +867,7 @@ void slow_hash_free_state(void)
* @param length the length in bytes of the data
* @param hash a pointer to a buffer in which the final 256 bit hash will be stored
*/
-void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
+void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
{
RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */
@@ -730,6 +903,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
VARIANT1_INIT64();
VARIANT2_INIT64();
+ VARIANT4_RANDOM_MATH_INIT();
/* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill
* the 2MB large random access buffer.
@@ -901,6 +1075,7 @@ union cn_slow_hash_state
p = U64(&hp_state[j]); \
b[0] = p[0]; b[1] = p[1]; \
VARIANT2_PORTABLE_INTEGER_MATH(b, c); \
+ VARIANT4_RANDOM_MATH(a, b, r, &_b, &_b1); \
__mul(); \
VARIANT2_2(); \
VARIANT2_SHUFFLE_ADD_NEON(hp_state, j); \
@@ -1063,7 +1238,7 @@ STATIC INLINE void aligned_free(void *ptr)
}
#endif /* FORCE_USE_HEAP */
-void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
+void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
{
RDATA_ALIGN16 uint8_t expandedKey[240];
@@ -1100,6 +1275,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
VARIANT1_INIT64();
VARIANT2_INIT64();
+ VARIANT4_RANDOM_MATH_INIT();
/* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill
* the 2MB large random access buffer.
@@ -1278,10 +1454,11 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b)
U64(a)[1] ^= U64(b)[1];
}
-void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
+void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
{
uint8_t text[INIT_SIZE_BYTE];
uint8_t a[AES_BLOCK_SIZE];
+ uint8_t a1[AES_BLOCK_SIZE];
uint8_t b[AES_BLOCK_SIZE * 2];
uint8_t c[AES_BLOCK_SIZE];
uint8_t c1[AES_BLOCK_SIZE];
@@ -1317,6 +1494,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
VARIANT1_INIT64();
VARIANT2_INIT64();
+ VARIANT4_RANDOM_MATH_INIT();
// use aligned data
memcpy(expandedKey, aes_ctx->key->exp_data, aes_ctx->key->exp_data_len);
@@ -1340,10 +1518,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
// Iteration 1
j = state_index(a);
p = &long_state[j];
- aesb_single_round(p, p, a);
- copy_block(c1, p);
+ aesb_single_round(p, c1, a);
- VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j);
+ VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j);
+ copy_block(p, c1);
xor_blocks(p, b);
VARIANT1_1(p);
@@ -1352,13 +1530,15 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
p = &long_state[j];
copy_block(c, p);
+ copy_block(a1, a);
VARIANT2_PORTABLE_INTEGER_MATH(c, c1);
+ VARIANT4_RANDOM_MATH(a1, c, r, b, b + AES_BLOCK_SIZE);
mul(c1, c, d);
VARIANT2_2_PORTABLE();
- VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j);
- sum_half_blocks(a, d);
- swap_blocks(a, c);
- xor_blocks(a, c);
+ VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j);
+ sum_half_blocks(a1, d);
+ swap_blocks(a1, c);
+ xor_blocks(a1, c);
VARIANT1_2(U64(c) + 1);
copy_block(p, c);
@@ -1366,6 +1546,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
copy_block(b + AES_BLOCK_SIZE, b);
}
copy_block(b, c1);
+ copy_block(a, a1);
}
memcpy(text, state.init, INIT_SIZE_BYTE);
@@ -1476,7 +1657,7 @@ union cn_slow_hash_state {
};
#pragma pack(pop)
-void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) {
+void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) {
#ifndef FORCE_USE_HEAP
uint8_t long_state[MEMORY];
#else
@@ -1486,6 +1667,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
union cn_slow_hash_state state;
uint8_t text[INIT_SIZE_BYTE];
uint8_t a[AES_BLOCK_SIZE];
+ uint8_t a1[AES_BLOCK_SIZE];
uint8_t b[AES_BLOCK_SIZE * 2];
uint8_t c1[AES_BLOCK_SIZE];
uint8_t c2[AES_BLOCK_SIZE];
@@ -1505,6 +1687,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
VARIANT1_PORTABLE_INIT();
VARIANT2_PORTABLE_INIT();
+ VARIANT4_RANDOM_MATH_INIT();
oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE);
for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
@@ -1528,7 +1711,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
j = e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
copy_block(c1, &long_state[j]);
aesb_single_round(c1, c1, a);
- VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j);
+ VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j);
copy_block(&long_state[j], c1);
xor_blocks(&long_state[j], b);
assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
@@ -1536,22 +1719,22 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
/* Iteration 2 */
j = e2i(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
copy_block(c2, &long_state[j]);
+ copy_block(a1, a);
VARIANT2_PORTABLE_INTEGER_MATH(c2, c1);
+ VARIANT4_RANDOM_MATH(a1, c2, r, b, b + AES_BLOCK_SIZE);
mul(c1, c2, d);
VARIANT2_2_PORTABLE();
- VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j);
- swap_blocks(a, c1);
- sum_half_blocks(c1, d);
- swap_blocks(c1, c2);
- xor_blocks(c1, c2);
+ VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j);
+ sum_half_blocks(a1, d);
+ swap_blocks(a1, c2);
+ xor_blocks(a1, c2);
VARIANT1_2(c2 + 8);
copy_block(&long_state[j], c2);
- assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
if (variant >= 2) {
copy_block(b + AES_BLOCK_SIZE, b);
}
- copy_block(b, a);
- copy_block(a, c1);
+ copy_block(b, c1);
+ copy_block(a, a1);
}
memcpy(text, state.init, INIT_SIZE_BYTE);
diff --git a/src/crypto/variant4_random_math.h b/src/crypto/variant4_random_math.h
new file mode 100644
index 000000000..f3e41a001
--- /dev/null
+++ b/src/crypto/variant4_random_math.h
@@ -0,0 +1,441 @@
+#ifndef VARIANT4_RANDOM_MATH_H
+#define VARIANT4_RANDOM_MATH_H
+
+// Register size can be configured to either 32 bit (uint32_t) or 64 bit (uint64_t)
+typedef uint32_t v4_reg;
+
+enum V4_Settings
+{
+ // Generate code with minimal theoretical latency = 45 cycles, which is equivalent to 15 multiplications
+ TOTAL_LATENCY = 15 * 3,
+
+ // Always generate at least 60 instructions
+ NUM_INSTRUCTIONS_MIN = 60,
+
+ // Never generate more than 70 instructions (final RET instruction doesn't count here)
+ NUM_INSTRUCTIONS_MAX = 70,
+
+ // Available ALUs for MUL
+ // Modern CPUs typically have only 1 ALU which can do multiplications
+ ALU_COUNT_MUL = 1,
+
+ // Total available ALUs
+ // Modern CPUs have 4 ALUs, but we use only 3 because random math executes together with other main loop code
+ ALU_COUNT = 3,
+};
+
+enum V4_InstructionList
+{
+ MUL, // a*b
+ ADD, // a+b + C, C is an unsigned 32-bit constant
+ SUB, // a-b
+ ROR, // rotate right "a" by "b & 31" bits
+ ROL, // rotate left "a" by "b & 31" bits
+ XOR, // a^b
+ RET, // finish execution
+ V4_INSTRUCTION_COUNT = RET,
+};
+
+// V4_InstructionDefinition is used to generate code from random data
+// Every random sequence of bytes is a valid code
+//
+// There are 9 registers in total:
+// - 4 variable registers
+// - 5 constant registers initialized from loop variables
+// This is why dst_index is 2 bits
+enum V4_InstructionDefinition
+{
+ V4_OPCODE_BITS = 3,
+ V4_DST_INDEX_BITS = 2,
+ V4_SRC_INDEX_BITS = 3,
+};
+
+struct V4_Instruction
+{
+ uint8_t opcode;
+ uint8_t dst_index;
+ uint8_t src_index;
+ uint32_t C;
+};
+
+#ifndef FORCEINLINE
+#if defined(__GNUC__)
+#define FORCEINLINE __attribute__((always_inline)) inline
+#elif defined(_MSC_VER)
+#define FORCEINLINE __forceinline
+#else
+#define FORCEINLINE inline
+#endif
+#endif
+
+#ifndef UNREACHABLE_CODE
+#if defined(__GNUC__)
+#define UNREACHABLE_CODE __builtin_unreachable()
+#elif defined(_MSC_VER)
+#define UNREACHABLE_CODE __assume(false)
+#else
+#define UNREACHABLE_CODE
+#endif
+#endif
+
+// Random math interpreter's loop is fully unrolled and inlined to achieve 100% branch prediction on CPU:
+// every switch-case will point to the same destination on every iteration of Cryptonight main loop
+//
+// This is about as fast as it can get without using low-level machine code generation
+static FORCEINLINE void v4_random_math(const struct V4_Instruction* code, v4_reg* r)
+{
+ enum
+ {
+ REG_BITS = sizeof(v4_reg) * 8,
+ };
+
+#define V4_EXEC(i) \
+ { \
+ const struct V4_Instruction* op = code + i; \
+ const v4_reg src = r[op->src_index]; \
+ v4_reg* dst = r + op->dst_index; \
+ switch (op->opcode) \
+ { \
+ case MUL: \
+ *dst *= src; \
+ break; \
+ case ADD: \
+ *dst += src + op->C; \
+ break; \
+ case SUB: \
+ *dst -= src; \
+ break; \
+ case ROR: \
+ { \
+ const uint32_t shift = src % REG_BITS; \
+ *dst = (*dst >> shift) | (*dst << ((REG_BITS - shift) % REG_BITS)); \
+ } \
+ break; \
+ case ROL: \
+ { \
+ const uint32_t shift = src % REG_BITS; \
+ *dst = (*dst << shift) | (*dst >> ((REG_BITS - shift) % REG_BITS)); \
+ } \
+ break; \
+ case XOR: \
+ *dst ^= src; \
+ break; \
+ case RET: \
+ return; \
+ default: \
+ UNREACHABLE_CODE; \
+ break; \
+ } \
+ }
+
+#define V4_EXEC_10(j) \
+ V4_EXEC(j + 0) \
+ V4_EXEC(j + 1) \
+ V4_EXEC(j + 2) \
+ V4_EXEC(j + 3) \
+ V4_EXEC(j + 4) \
+ V4_EXEC(j + 5) \
+ V4_EXEC(j + 6) \
+ V4_EXEC(j + 7) \
+ V4_EXEC(j + 8) \
+ V4_EXEC(j + 9)
+
+ // Generated program can have 60 + a few more (usually 2-3) instructions to achieve required latency
+ // I've checked all block heights < 10,000,000 and here is the distribution of program sizes:
+ //
+ // 60 27960
+ // 61 105054
+ // 62 2452759
+ // 63 5115997
+ // 64 1022269
+ // 65 1109635
+ // 66 153145
+ // 67 8550
+ // 68 4529
+ // 69 102
+
+ // Unroll 70 instructions here
+ V4_EXEC_10(0); // instructions 0-9
+ V4_EXEC_10(10); // instructions 10-19
+ V4_EXEC_10(20); // instructions 20-29
+ V4_EXEC_10(30); // instructions 30-39
+ V4_EXEC_10(40); // instructions 40-49
+ V4_EXEC_10(50); // instructions 50-59
+ V4_EXEC_10(60); // instructions 60-69
+
+#undef V4_EXEC_10
+#undef V4_EXEC
+}
+
+// If we don't have enough data available, generate more
+static FORCEINLINE void check_data(size_t* data_index, const size_t bytes_needed, int8_t* data, const size_t data_size)
+{
+ if (*data_index + bytes_needed > data_size)
+ {
+ hash_extra_blake(data, data_size, (char*) data);
+ *data_index = 0;
+ }
+}
+
+// Generates as many random math operations as possible with given latency and ALU restrictions
+// "code" array must have space for NUM_INSTRUCTIONS_MAX+1 instructions
+static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_t height)
+{
+ // MUL is 3 cycles, 3-way addition and rotations are 2 cycles, SUB/XOR are 1 cycle
+ // These latencies match real-life instruction latencies for Intel CPUs starting from Sandy Bridge and up to Skylake/Coffee lake
+ //
+ // AMD Ryzen has the same latencies except 1-cycle ROR/ROL, so it'll be a bit faster than Intel Sandy Bridge and newer processors
+ // Surprisingly, Intel Nehalem also has 1-cycle ROR/ROL, so it'll also be faster than Intel Sandy Bridge and newer processors
+ // AMD Bulldozer has 4 cycles latency for MUL (slower than Intel) and 1 cycle for ROR/ROL (faster than Intel), so average performance will be the same
+ // Source: https://www.agner.org/optimize/instruction_tables.pdf
+ const int op_latency[V4_INSTRUCTION_COUNT] = { 3, 2, 1, 2, 2, 1 };
+
+ // Instruction latencies for theoretical ASIC implementation
+ const int asic_op_latency[V4_INSTRUCTION_COUNT] = { 3, 1, 1, 1, 1, 1 };
+
+ // Available ALUs for each instruction
+ const int op_ALUs[V4_INSTRUCTION_COUNT] = { ALU_COUNT_MUL, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT };
+
+ int8_t data[32];
+ memset(data, 0, sizeof(data));
+ uint64_t tmp = SWAP64LE(height);
+ memcpy(data, &tmp, sizeof(uint64_t));
+ data[20] = -38; // change seed
+
+ // Set data_index past the last byte in data
+ // to trigger full data update with blake hash
+ // before we start using it
+ size_t data_index = sizeof(data);
+
+ int code_size;
+
+ // There is a small chance (1.8%) that register R8 won't be used in the generated program
+ // So we keep track of it and try again if it's not used
+ bool r8_used;
+ do {
+ int latency[9];
+ int asic_latency[9];
+
+ // Tracks previous instruction and value of the source operand for registers R0-R3 throughout code execution
+ // byte 0: current value of the destination register
+ // byte 1: instruction opcode
+ // byte 2: current value of the source register
+ //
+ // Registers R4-R8 are constant and are treated as having the same value because when we do
+ // the same operation twice with two constant source registers, it can be optimized into a single operation
+ uint32_t inst_data[9] = { 0, 1, 2, 3, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF };
+
+ bool alu_busy[TOTAL_LATENCY + 1][ALU_COUNT];
+ bool is_rotation[V4_INSTRUCTION_COUNT];
+ bool rotated[4];
+ int rotate_count = 0;
+
+ memset(latency, 0, sizeof(latency));
+ memset(asic_latency, 0, sizeof(asic_latency));
+ memset(alu_busy, 0, sizeof(alu_busy));
+ memset(is_rotation, 0, sizeof(is_rotation));
+ memset(rotated, 0, sizeof(rotated));
+ is_rotation[ROR] = true;
+ is_rotation[ROL] = true;
+
+ int num_retries = 0;
+ code_size = 0;
+
+ int total_iterations = 0;
+ r8_used = false;
+
+ // Generate random code to achieve minimal required latency for our abstract CPU
+ // Try to get this latency for all 4 registers
+ while (((latency[0] < TOTAL_LATENCY) || (latency[1] < TOTAL_LATENCY) || (latency[2] < TOTAL_LATENCY) || (latency[3] < TOTAL_LATENCY)) && (num_retries < 64))
+ {
+ // Fail-safe to guarantee loop termination
+ ++total_iterations;
+ if (total_iterations > 256)
+ break;
+
+ check_data(&data_index, 1, data, sizeof(data));
+
+ const uint8_t c = ((uint8_t*)data)[data_index++];
+
+ // MUL = opcodes 0-2
+ // ADD = opcode 3
+ // SUB = opcode 4
+ // ROR/ROL = opcode 5, shift direction is selected randomly
+ // XOR = opcodes 6-7
+ uint8_t opcode = c & ((1 << V4_OPCODE_BITS) - 1);
+ if (opcode == 5)
+ {
+ check_data(&data_index, 1, data, sizeof(data));
+ opcode = (data[data_index++] >= 0) ? ROR : ROL;
+ }
+ else if (opcode >= 6)
+ {
+ opcode = XOR;
+ }
+ else
+ {
+ opcode = (opcode <= 2) ? MUL : (opcode - 2);
+ }
+
+ uint8_t dst_index = (c >> V4_OPCODE_BITS) & ((1 << V4_DST_INDEX_BITS) - 1);
+ uint8_t src_index = (c >> (V4_OPCODE_BITS + V4_DST_INDEX_BITS)) & ((1 << V4_SRC_INDEX_BITS) - 1);
+
+ const int a = dst_index;
+ int b = src_index;
+
+ // Don't do ADD/SUB/XOR with the same register
+ if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b))
+ {
+ // Use register R8 as source instead
+ b = 8;
+ src_index = 8;
+ }
+
+ // Don't do rotation with the same destination twice because it's equal to a single rotation
+ if (is_rotation[opcode] && rotated[a])
+ {
+ continue;
+ }
+
+ // Don't do the same instruction (except MUL) with the same source value twice because all other cases can be optimized:
+ // 2xADD(a, b, C) = ADD(a, b*2, C1+C2), same for SUB and rotations
+ // 2xXOR(a, b) = NOP
+ if ((opcode != MUL) && ((inst_data[a] & 0xFFFF00) == (opcode << 8) + ((inst_data[b] & 255) << 16)))
+ {
+ continue;
+ }
+
+ // Find which ALU is available (and when) for this instruction
+ int next_latency = (latency[a] > latency[b]) ? latency[a] : latency[b];
+ int alu_index = -1;
+ while (next_latency < TOTAL_LATENCY)
+ {
+ for (int i = op_ALUs[opcode] - 1; i >= 0; --i)
+ {
+ if (!alu_busy[next_latency][i])
+ {
+ // ADD is implemented as two 1-cycle instructions on a real CPU, so do an additional availability check
+ if ((opcode == ADD) && alu_busy[next_latency + 1][i])
+ {
+ continue;
+ }
+
+ // Rotation can only start when previous rotation is finished, so do an additional availability check
+ if (is_rotation[opcode] && (next_latency < rotate_count * op_latency[opcode]))
+ {
+ continue;
+ }
+
+ alu_index = i;
+ break;
+ }
+ }
+ if (alu_index >= 0)
+ {
+ break;
+ }
+ ++next_latency;
+ }
+
+ // Don't generate instructions that leave some register unchanged for more than 7 cycles
+ if (next_latency > latency[a] + 7)
+ {
+ continue;
+ }
+
+ next_latency += op_latency[opcode];
+
+ if (next_latency <= TOTAL_LATENCY)
+ {
+ if (is_rotation[opcode])
+ {
+ ++rotate_count;
+ }
+
+ // Mark ALU as busy only for the first cycle when it starts executing the instruction because ALUs are fully pipelined
+ alu_busy[next_latency - op_latency[opcode]][alu_index] = true;
+ latency[a] = next_latency;
+
+ // ASIC is supposed to have enough ALUs to run as many independent instructions per cycle as possible, so latency calculation for ASIC is simple
+ asic_latency[a] = ((asic_latency[a] > asic_latency[b]) ? asic_latency[a] : asic_latency[b]) + asic_op_latency[opcode];
+
+ rotated[a] = is_rotation[opcode];
+
+ inst_data[a] = code_size + (opcode << 8) + ((inst_data[b] & 255) << 16);
+
+ code[code_size].opcode = opcode;
+ code[code_size].dst_index = dst_index;
+ code[code_size].src_index = src_index;
+ code[code_size].C = 0;
+
+ if (src_index == 8)
+ {
+ r8_used = true;
+ }
+
+ if (opcode == ADD)
+ {
+ // ADD instruction is implemented as two 1-cycle instructions on a real CPU, so mark ALU as busy for the next cycle too
+ alu_busy[next_latency - op_latency[opcode] + 1][alu_index] = true;
+
+ // ADD instruction requires 4 more random bytes for 32-bit constant "C" in "a = a + b + C"
+ check_data(&data_index, sizeof(uint32_t), data, sizeof(data));
+ uint32_t t;
+ memcpy(&t, data + data_index, sizeof(uint32_t));
+ code[code_size].C = SWAP32LE(t);
+ data_index += sizeof(uint32_t);
+ }
+
+ ++code_size;
+ if (code_size >= NUM_INSTRUCTIONS_MIN)
+ {
+ break;
+ }
+ }
+ else
+ {
+ ++num_retries;
+ }
+ }
+
+ // ASIC has more execution resources and can extract as much parallelism from the code as possible
+ // We need to add a few more MUL and ROR instructions to achieve minimal required latency for ASIC
+ // Get this latency for at least 1 of the 4 registers
+ const int prev_code_size = code_size;
+ while ((code_size < NUM_INSTRUCTIONS_MAX) && (asic_latency[0] < TOTAL_LATENCY) && (asic_latency[1] < TOTAL_LATENCY) && (asic_latency[2] < TOTAL_LATENCY) && (asic_latency[3] < TOTAL_LATENCY))
+ {
+ int min_idx = 0;
+ int max_idx = 0;
+ for (int i = 1; i < 4; ++i)
+ {
+ if (asic_latency[i] < asic_latency[min_idx]) min_idx = i;
+ if (asic_latency[i] > asic_latency[max_idx]) max_idx = i;
+ }
+
+ const uint8_t pattern[3] = { ROR, MUL, MUL };
+ const uint8_t opcode = pattern[(code_size - prev_code_size) % 3];
+ latency[min_idx] = latency[max_idx] + op_latency[opcode];
+ asic_latency[min_idx] = asic_latency[max_idx] + asic_op_latency[opcode];
+
+ code[code_size].opcode = opcode;
+ code[code_size].dst_index = min_idx;
+ code[code_size].src_index = max_idx;
+ code[code_size].C = 0;
+ ++code_size;
+ }
+
+ // There is ~98.15% chance that loop condition is false, so this loop will execute only 1 iteration most of the time
+ // It never does more than 4 iterations for all block heights < 10,000,000
+ } while (!r8_used || (code_size < NUM_INSTRUCTIONS_MIN) || (code_size > NUM_INSTRUCTIONS_MAX));
+
+ // It's guaranteed that NUM_INSTRUCTIONS_MIN <= code_size <= NUM_INSTRUCTIONS_MAX here
+ // Add final instruction to stop the interpreter
+ code[code_size].opcode = RET;
+ code[code_size].dst_index = 0;
+ code[code_size].src_index = 0;
+ code[code_size].C = 0;
+
+ return code_size;
+}
+
+#endif