Monero
instruction.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2018-2019, tevador <tevador@gmail.com>
3 
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the copyright holder nor the
14  names of its contributors may be used to endorse or promote products
15  derived from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #pragma once
30 
31 #include <cstdint>
32 #include <iostream>
33 #include <type_traits>
34 #include "blake2/endian.h"
35 
36 namespace randomx {
37 
38  class Instruction;
39 
40  typedef void(Instruction::*InstructionFormatter)(std::ostream&) const;
41 
42  enum class InstructionType : uint16_t {
43  IADD_RS = 0,
44  IADD_M = 1,
45  ISUB_R = 2,
46  ISUB_M = 3,
47  IMUL_R = 4,
48  IMUL_M = 5,
49  IMULH_R = 6,
50  IMULH_M = 7,
51  ISMULH_R = 8,
52  ISMULH_M = 9,
53  IMUL_RCP = 10,
54  INEG_R = 11,
55  IXOR_R = 12,
56  IXOR_M = 13,
57  IROR_R = 14,
58  IROL_R = 15,
59  ISWAP_R = 16,
60  FSWAP_R = 17,
61  FADD_R = 18,
62  FADD_M = 19,
63  FSUB_R = 20,
64  FSUB_M = 21,
65  FSCAL_R = 22,
66  FMUL_R = 23,
67  FDIV_M = 24,
68  FSQRT_R = 25,
69  CBRANCH = 26,
70  CFROUND = 27,
71  ISTORE = 28,
72  NOP = 29,
73  };
74 
75  class Instruction {
76  public:
77  uint32_t getImm32() const {
78  return load32(&imm32);
79  }
80  void setImm32(uint32_t val) {
81  return store32(&imm32, val);
82  }
83  const char* getName() const {
84  return names[opcode];
85  }
86  friend std::ostream& operator<<(std::ostream& os, const Instruction& i) {
87  i.print(os);
88  return os;
89  }
90  int getModMem() const {
91  return mod % 4; //bits 0-1
92  }
93  int getModShift() const {
94  return (mod >> 2) % 4; //bits 2-3
95  }
96  int getModCond() const {
97  return mod >> 4; //bits 4-7
98  }
99  void setMod(uint8_t val) {
100  mod = val;
101  }
102 
108  private:
109  void print(std::ostream&) const;
110  static const char* names[256];
112  void genAddressReg(std::ostream& os, int) const;
113  void genAddressImm(std::ostream& os) const;
114  void genAddressRegDst(std::ostream&, int) const;
115  void h_IADD_RS(std::ostream&) const;
116  void h_IADD_M(std::ostream&) const;
117  void h_ISUB_R(std::ostream&) const;
118  void h_ISUB_M(std::ostream&) const;
119  void h_IMUL_R(std::ostream&) const;
120  void h_IMUL_M(std::ostream&) const;
121  void h_IMULH_R(std::ostream&) const;
122  void h_IMULH_M(std::ostream&) const;
123  void h_ISMULH_R(std::ostream&) const;
124  void h_ISMULH_M(std::ostream&) const;
125  void h_IMUL_RCP(std::ostream&) const;
126  void h_INEG_R(std::ostream&) const;
127  void h_IXOR_R(std::ostream&) const;
128  void h_IXOR_M(std::ostream&) const;
129  void h_IROR_R(std::ostream&) const;
130  void h_IROL_R(std::ostream&) const;
131  void h_ISWAP_R(std::ostream&) const;
132  void h_FSWAP_R(std::ostream&) const;
133  void h_FADD_R(std::ostream&) const;
134  void h_FADD_M(std::ostream&) const;
135  void h_FSUB_R(std::ostream&) const;
136  void h_FSUB_M(std::ostream&) const;
137  void h_FSCAL_R(std::ostream&) const;
138  void h_FMUL_R(std::ostream&) const;
139  void h_FDIV_M(std::ostream&) const;
140  void h_FSQRT_R(std::ostream&) const;
141  void h_CBRANCH(std::ostream&) const;
142  void h_CFROUND(std::ostream&) const;
143  void h_ISTORE(std::ostream&) const;
144  void h_NOP(std::ostream&) const;
145  };
146 
147  static_assert(sizeof(Instruction) == 8, "Invalid size of struct randomx::Instruction");
148  static_assert(std::is_standard_layout<Instruction>(), "randomx::Instruction must be a standard-layout struct");
149 }
void h_ISMULH_M(std::ostream &) const
Definition: instruction.cpp:160
uint8_t mod
Definition: instruction.hpp:106
Definition: allocator.cpp:35
void(Instruction::* InstructionFormatter)(std::ostream &) const
Definition: instruction.hpp:40
friend std::ostream & operator<<(std::ostream &os, const Instruction &i)
Definition: instruction.hpp:86
uint8_t src
Definition: instruction.hpp:105
int i
Definition: pymoduletest.py:23
void h_FADD_M(std::ostream &) const
Definition: instruction.cpp:252
Definition: instruction.hpp:75
int getModCond() const
Definition: instruction.hpp:96
void h_ISWAP_R(std::ostream &) const
Definition: instruction.cpp:233
void h_FSUB_M(std::ostream &) const
Definition: instruction.cpp:266
void h_IMULH_M(std::ostream &) const
Definition: instruction.cpp:139
void h_IADD_M(std::ostream &) const
Definition: instruction.cpp:66
unsigned short uint16_t
Definition: stdint.h:125
uint32_t imm32
Definition: instruction.hpp:107
void genAddressImm(std::ostream &os) const
Definition: instruction.cpp:52
unsigned char uint8_t
Definition: stdint.h:124
int getModShift() const
Definition: instruction.hpp:93
uint8_t opcode
Definition: instruction.hpp:103
uint8_t dst
Definition: instruction.hpp:104
void h_ISTORE(std::ostream &) const
Definition: instruction.cpp:309
void h_FDIV_M(std::ostream &) const
Definition: instruction.cpp:285
void setMod(uint8_t val)
Definition: instruction.hpp:99
void setImm32(uint32_t val)
Definition: instruction.hpp:80
unsigned int uint32_t
Definition: stdint.h:126
static InstructionFormatter engine[256]
Definition: instruction.hpp:111
void h_ISUB_R(std::ostream &) const
Definition: instruction.cpp:81
void h_IMUL_RCP(std::ostream &) const
Definition: instruction.cpp:228
void h_IXOR_M(std::ostream &) const
Definition: instruction.cpp:191
void h_IXOR_R(std::ostream &) const
Definition: instruction.cpp:180
void h_IMUL_M(std::ostream &) const
Definition: instruction.cpp:118
void h_CFROUND(std::ostream &) const
Definition: instruction.cpp:298
void h_FMUL_R(std::ostream &) const
Definition: instruction.cpp:279
uint32_t getImm32() const
Definition: instruction.hpp:77
void h_FSWAP_R(std::ostream &) const
Definition: instruction.cpp:239
void print(std::ostream &) const
Definition: instruction.cpp:34
void genAddressRegDst(std::ostream &, int) const
Definition: instruction.cpp:44
static const char * names[256]
Definition: instruction.hpp:110
void h_IROR_R(std::ostream &) const
Definition: instruction.cpp:206
void h_FSUB_R(std::ostream &) const
Definition: instruction.cpp:260
InstructionType
Definition: instruction.hpp:42
void h_IMUL_R(std::ostream &) const
Definition: instruction.cpp:107
void h_FSCAL_R(std::ostream &) const
Definition: instruction.cpp:274
void h_ISUB_M(std::ostream &) const
Definition: instruction.cpp:92
void h_FSQRT_R(std::ostream &) const
Definition: instruction.cpp:293
int getModMem() const
Definition: instruction.hpp:90
static FORCE_INLINE void store32(void *dst, uint32_t w)
Definition: endian.h:67
void h_IMULH_R(std::ostream &) const
Definition: instruction.cpp:133
void h_ISMULH_R(std::ostream &) const
Definition: instruction.cpp:154
const char * getName() const
Definition: instruction.hpp:83
void h_IROL_R(std::ostream &) const
Definition: instruction.cpp:217
void h_FADD_R(std::ostream &) const
Definition: instruction.cpp:246
void h_IADD_RS(std::ostream &) const
Definition: instruction.cpp:56
void genAddressReg(std::ostream &os, int) const
Definition: instruction.cpp:40
void h_INEG_R(std::ostream &) const
Definition: instruction.cpp:175
void h_NOP(std::ostream &) const
Definition: instruction.cpp:316
static FORCE_INLINE uint32_t load32(const void *src)
Definition: endian.h:29
void h_CBRANCH(std::ostream &) const
Definition: instruction.cpp:303