mirror of
				https://git.wownero.com/wownero/RandomWOW.git
				synced 2024-08-15 00:23:14 +00:00 
			
		
		
		
	Renamed immediate constants
This commit is contained in:
		
							parent
							
								
									b9d2d853aa
								
							
						
					
					
						commit
						1db7dd6e8b
					
				
					 7 changed files with 72 additions and 70 deletions
				
			
		|  | @ -43,4 +43,5 @@ The following people have contributed to the design of RandomX: | |||
| RandomX uses some source code from the following 3rd party repositories: | ||||
| * Argon2d, Blake2b hashing functions: https://github.com/P-H-C/phc-winner-argon2 | ||||
| * PCG32 random number generator: https://github.com/imneme/pcg-c-basic | ||||
| * Software AES implementation https://github.com/fireice-uk/xmr-stak | ||||
| * Software AES implementation https://github.com/fireice-uk/xmr-stak | ||||
| * t1ha2 hashing function: https://github.com/leo-yuriev/t1ha | ||||
							
								
								
									
										33
									
								
								doc/isa.md
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								doc/isa.md
									
										
									
									
									
								
							|  | @ -1,10 +1,11 @@ | |||
| 
 | ||||
| 
 | ||||
| ## RandomX instruction set | ||||
| RandomX uses a simple low-level language (instruction set), which was designed so that any random bitstring forms a valid program. | ||||
| 
 | ||||
| Each RandomX instruction has a length of 128 bits. The encoding is following: | ||||
| 
 | ||||
|  | ||||
|  | ||||
| 
 | ||||
| *All flags are aligned to an 8-bit boundary for easier decoding.* | ||||
| 
 | ||||
|  | @ -33,10 +34,10 @@ The first operand is read from memory. The location is determined by the `loc(a) | |||
| 
 | ||||
| Flag `reg(a)` encodes an integer register `r0`-`r7`.  The read address is calculated as: | ||||
| ``` | ||||
| reg(a) = reg(a) XOR signExtend(addr0) | ||||
| addr(a) = reg(a)[W-1:0] | ||||
| reg(a) = reg(a) XOR signExtend(addr(a)) | ||||
| read_addr = reg(a)[W-1:0] | ||||
| ``` | ||||
| `W` is the address width from the above table. For reading from the scratchpad, `addr(a)` is multiplied by 8 for 8-byte aligned access. | ||||
| `W` is the address width from the above table. For reading from the scratchpad, `read_addr` is multiplied by 8 for 8-byte aligned access. | ||||
| 
 | ||||
| #### Operand B | ||||
| The second operand is loaded either from a register or from an immediate value encoded within the instruction. The `reg(b)` flag encodes an integer register (ALU operations) or a floating point register (FPU operations). | ||||
|  | @ -49,12 +50,12 @@ The second operand is loaded either from a register or from an immediate value e | |||
| |011|register `reg(b)`| | ||||
| |100|register `reg(b)`| | ||||
| |101|register `reg(b)`| | ||||
| |110|`imm0` or `imm1`| | ||||
| |111|`imm0` or `imm1`| | ||||
| |110|`imm8` or `imm32`| | ||||
| |111|`imm8` or `imm32`| | ||||
| 
 | ||||
| `imm0` is an 8-bit immediate value, which is used for shift and rotate ALU operations. | ||||
| `imm8` is an 8-bit immediate value, which is used for shift and rotate ALU operations. | ||||
| 
 | ||||
| `imm1` is a 32-bit immediate value which is used for most operations. For operands larger than 32 bits, the value is sign-extended. For FPU instructions, the value is considered a signed 32-bit integer and then converted to a double precision floating point format. | ||||
| `imm32` is a 32-bit immediate value which is used for most operations. For operands larger than 32 bits, the value is sign-extended. For FPU instructions, the value is considered a signed 32-bit integer and then converted to a double precision floating point format. | ||||
| 
 | ||||
| #### Operand C | ||||
| The third operand is the location where the result is stored. | ||||
|  | @ -72,18 +73,18 @@ The third operand is the location where the result is stored. | |||
| 
 | ||||
| The `reg(c)` flag encodes an integer register (ALU operations) or a floating point register (FPU operations).  For writing to the scratchpad, an integer register is always used and the write address is calculated as: | ||||
| ``` | ||||
| addr(c) = 8 * (addr1 XOR reg(c)[31:0])[W-1:0] | ||||
| write_addr = 8 * (addr(c) XOR reg(c)[31:0])[W-1:0] | ||||
| ``` | ||||
| *CPUs are typically designed for a 2:1 load:store ratio, so each VM instruction performs on average 1 memory read and 0.5 write to memory.* | ||||
| 
 | ||||
| #### imm0 | ||||
| #### imm8 | ||||
| An 8-bit immediate value that is used as the shift/rotate count by some ALU instructions and as the jump offset of the CALL instruction. | ||||
| 
 | ||||
| #### addr0 | ||||
| #### addr(a) | ||||
| A 32-bit address mask that is used to calculate the read address for the A operand. It's sign-extended to 64 bits. | ||||
| 
 | ||||
| #### addr1 | ||||
| A 32-bit address mask that is used to calculate the write address for the C operand. `addr1` is equal to `imm1`. | ||||
| #### addr\(c\) | ||||
| A 32-bit address mask that is used to calculate the write address for the C operand. `addr(c)` is equal to `imm32`. | ||||
| 
 | ||||
| ### ALU instructions | ||||
| 
 | ||||
|  | @ -124,7 +125,7 @@ For the division instructions, the dividend is 64 bits long and the divisor 32 b | |||
| *Division by zero can be handled without branching by a conditional move. Signed overflow happens only for the signed variant when the minimum negative value is divided by -1. This rare case must be handled in x86 (ARM produces the "correct" result).* | ||||
| 
 | ||||
| ##### Shift and rotate | ||||
| The shift/rotate instructions use just the bottom 6 bits of the `B` operand (`imm0` is used as the immediate value). All treat `A` as unsigned except SAR_64, which performs an arithmetic right shift by copying the sign bit. | ||||
| The shift/rotate instructions use just the bottom 6 bits of the `B` operand (`imm8` is used as the immediate value). All treat `A` as unsigned except SAR_64, which performs an arithmetic right shift by copying the sign bit. | ||||
| 
 | ||||
| ### FPU instructions | ||||
| 
 | ||||
|  | @ -169,10 +170,10 @@ The following 2 control flow instructions are supported: | |||
| |17|CALL|near procedure call| | ||||
| |15|RET|return from procedure| | ||||
| 
 | ||||
| Both instructions are conditional in 75% of cases. The jump is taken only if `B <= imm1`. For the 25% of cases when `B` is equal to `imm1`, the jump is unconditional. In case the branch is not taken, both instructions become "arithmetic no-op" `C = A`. | ||||
| Both instructions are conditional in 75% of cases. The jump is taken only if `B <= imm32`. For the 25% of cases when `B` is equal to `imm32`, the jump is unconditional. In case the branch is not taken, both instructions become "arithmetic no-op" `C = A`. | ||||
| 
 | ||||
| ##### CALL | ||||
| Taken CALL instruction pushes the values `A` and `pc` (program counter) onto the stack and then performs a forward jump relative to the value of `pc`. The forward offset is equal to `16 * (imm0[6:0] + 1)`. Maximum jump distance is therefore 128 instructions forward (this means that at least 4 correctly spaced CALL instructions are needed to form a loop in the program). | ||||
| Taken CALL instruction pushes the values `A` and `pc` (program counter) onto the stack and then performs a forward jump relative to the value of `pc`. The forward offset is equal to `16 * (imm8[6:0] + 1)`. Maximum jump distance is therefore 128 instructions forward (this means that at least 4 correctly spaced CALL instructions are needed to form a loop in the program). | ||||
| 
 | ||||
| ##### RET | ||||
| The RET instruction behaves like "not taken" when the stack is empty. Taken RET instruction pops the return address `raddr` from the stack (it's the instruction following the previous CALL), then pops a return value `retval` from the stack and sets `C = A XOR retval`. Finally, the instruction jumps back to `raddr`. | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ namespace RandomX { | |||
| 	} | ||||
| 
 | ||||
| 	void AssemblyGeneratorX86::gena(Instruction& instr) { | ||||
| 		asmCode << "\txor " << regR[instr.rega % RegistersCount] << ", 0" << std::hex << instr.addr0 << "h" << std::dec << std::endl; | ||||
| 		asmCode << "\txor " << regR[instr.rega % RegistersCount] << ", 0" << std::hex << instr.addra << "h" << std::dec << std::endl; | ||||
| 		switch (instr.loca & 7) | ||||
| 		{ | ||||
| 		case 0: | ||||
|  | @ -93,7 +93,7 @@ namespace RandomX { | |||
| 			asmCode << "\t" << instrx86 << " rax, cl" << std::endl; | ||||
| 			return; | ||||
| 		default: | ||||
| 			asmCode << "\t" << instrx86 << " rax, " << (instr.imm0 & 63) << std::endl;; | ||||
| 			asmCode << "\t" << instrx86 << " rax, " << (instr.imm8 & 63) << std::endl;; | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -110,7 +110,7 @@ namespace RandomX { | |||
| 			asmCode << regR[instr.regb % RegistersCount] << std::endl; | ||||
| 			return; | ||||
| 		default: | ||||
| 			asmCode  << instr.imm1 << std::endl;; | ||||
| 			asmCode  << instr.imm32 << std::endl;; | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -127,7 +127,7 @@ namespace RandomX { | |||
| 			asmCode << regR32[instr.regb % RegistersCount] << std::endl; | ||||
| 			return; | ||||
| 		default: | ||||
| 			asmCode << instr.imm1 << std::endl;; | ||||
| 			asmCode << instr.imm32 << std::endl;; | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -147,7 +147,7 @@ namespace RandomX { | |||
| 			return; | ||||
| 		default: | ||||
| 			convertible_t bimm; | ||||
| 			bimm.f64 = (double)instr.imm1; | ||||
| 			bimm.f64 = (double)instr.imm32; | ||||
| 			asmCode << "\tmov rax, " << bimm.i64 << std::endl; | ||||
| 			asmCode << "\tmovd xmm1, rax" << std::endl; | ||||
| 			asmCode << "\t" << instrx86 << " xmm0, xmm1" << std::endl; | ||||
|  | @ -161,7 +161,7 @@ namespace RandomX { | |||
| 		case 0: | ||||
| 			asmCode << "\tmov rcx, rax" << std::endl; | ||||
| 			asmCode << "\tmov eax, " << regR32[instr.regc % RegistersCount] << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addr1 << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addrc << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\tand eax, " << (ScratchpadL2 - 1) << std::endl; | ||||
| 			asmCode << "\tmov qword ptr [rsi + rax * 8], rcx" << std::endl; | ||||
| 			if (trace) { | ||||
|  | @ -174,7 +174,7 @@ namespace RandomX { | |||
| 		case 3: | ||||
| 			asmCode << "\tmov rcx, rax" << std::endl; | ||||
| 			asmCode << "\tmov eax, " << regR32[instr.regc % RegistersCount] << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addr1 << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addrc << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\tand eax, " << (ScratchpadL1 - 1) << std::endl; | ||||
| 			asmCode << "\tmov qword ptr [rsi + rax * 8], rcx" << std::endl; | ||||
| 			if (trace) { | ||||
|  | @ -195,7 +195,7 @@ namespace RandomX { | |||
| 		{ | ||||
| 		case 0: | ||||
| 			asmCode << "\tmov eax, " << regR32[instr.regc % RegistersCount] << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addr1 << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addrc << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\tand eax, " << (ScratchpadL2 - 1) << std::endl; | ||||
| 			asmCode << "\tmovd qword ptr [rsi + rax * 8], xmm0" << std::endl; | ||||
| 			break; | ||||
|  | @ -204,7 +204,7 @@ namespace RandomX { | |||
| 		case 2: | ||||
| 		case 3: | ||||
| 			asmCode << "\tmov eax, " << regR32[instr.regc % RegistersCount] << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addr1 << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\txor eax, 0" << std::hex << instr.addrc << "h" << std::dec << std::endl; | ||||
| 			asmCode << "\tand eax, " << (ScratchpadL1 - 1) << std::endl; | ||||
| 			asmCode << "\tmovd qword ptr [rsi + rax * 8], xmm0" << std::endl; | ||||
| 			break; | ||||
|  | @ -278,7 +278,7 @@ namespace RandomX { | |||
| 		gena(instr); | ||||
| 		asmCode << "\tmovsxd rcx, eax" << std::endl; | ||||
| 		if ((instr.locb & 7) >= 6) { | ||||
| 			asmCode << "\tmov rax, " << instr.imm1 << std::endl; | ||||
| 			asmCode << "\tmov rax, " << instr.imm32 << std::endl; | ||||
| 		} | ||||
| 		else { | ||||
| 			asmCode << "\tmovsxd rax, " << regR32[instr.regb % RegistersCount] << std::endl; | ||||
|  | @ -299,11 +299,11 @@ namespace RandomX { | |||
| 	void AssemblyGeneratorX86::h_DIV_64(Instruction& instr, int i) { | ||||
| 		gena(instr); | ||||
| 		if ((instr.locb & 7) >= 6) { | ||||
| 			if (instr.imm1 == 0) { | ||||
| 			if (instr.imm32 == 0) { | ||||
| 				asmCode << "\tmov ecx, 1" << std::endl; | ||||
| 			} | ||||
| 			else { | ||||
| 				asmCode << "\tmov ecx, " << instr.imm1 << std::endl; | ||||
| 				asmCode << "\tmov ecx, " << instr.imm32 << std::endl; | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
|  | @ -461,7 +461,7 @@ namespace RandomX { | |||
| 	void AssemblyGeneratorX86::h_CALL(Instruction& instr, int i) { | ||||
| 		gena(instr); | ||||
| 		if ((instr.locb & 7) < 6) { | ||||
| 			asmCode << "\tcmp " << regR32[instr.regb % RegistersCount] << ", " << instr.imm1 << std::endl; | ||||
| 			asmCode << "\tcmp " << regR32[instr.regb % RegistersCount] << ", " << instr.imm32 << std::endl; | ||||
| 			asmCode << "\tjbe short taken_call_" << i << std::endl; | ||||
| 			gencr(instr); | ||||
| 			asmCode << "\tjmp rx_i_" << wrapInstr(i + 1) << std::endl; | ||||
|  | @ -471,7 +471,7 @@ namespace RandomX { | |||
| 			asmCode << "\tmov qword ptr [rsi + rdi * 8 + 262144], rax" << std::endl; | ||||
| 		} | ||||
| 		asmCode << "\tpush rax" << std::endl; | ||||
| 		asmCode << "\tcall rx_i_" << wrapInstr(i + (instr.imm0 & 127) + 2) << std::endl; | ||||
| 		asmCode << "\tcall rx_i_" << wrapInstr(i + (instr.imm8 & 127) + 2) << std::endl; | ||||
| 	} | ||||
| 
 | ||||
| 	void AssemblyGeneratorX86::h_RET(Instruction& instr, int i) { | ||||
|  | @ -479,7 +479,7 @@ namespace RandomX { | |||
| 		asmCode << "\tcmp rsp, rbp" << std::endl; | ||||
| 		asmCode << "\tje short not_taken_ret_" << i << std::endl; | ||||
| 		if ((instr.locb & 7) < 6) { | ||||
| 			asmCode << "\tcmp " << regR32[instr.regb % RegistersCount] << ", " << instr.imm1 << std::endl; | ||||
| 			asmCode << "\tcmp " << regR32[instr.regb % RegistersCount] << ", " << instr.imm32 << std::endl; | ||||
| 			asmCode << "\tja short not_taken_ret_" << i << std::endl; | ||||
| 		} | ||||
| 		asmCode << "\txor rax, qword ptr [rsp + 8]" << std::endl; | ||||
|  |  | |||
|  | @ -25,10 +25,10 @@ namespace RandomX { | |||
| 			os << "  A: loc = " << std::dec << (loca & 7) << ", reg: " << (rega & 7) << std::endl; | ||||
| 			os << "  B: loc = " << (locb & 7) << ", reg: " << (regb & 7) << std::endl; | ||||
| 			os << "  C: loc = " << (locc & 7) << ", reg: " << (regc & 7) << std::endl; | ||||
| 			os << "  addr0 = " << std::hex << addr0 << std::endl; | ||||
| 			os << "  addr1 = " << addr1 << std::endl; | ||||
| 			os << "  imm0 = " << std::dec << (int)imm0 << std::endl; | ||||
| 			os << "  imm1 = " << imm1 << std::endl; | ||||
| 			os << "  addra = " << std::hex << addra << std::endl; | ||||
| 			os << "  addrc = " << addrc << std::endl; | ||||
| 			os << "  imm8 = " << std::dec << (int)imm8 << std::endl; | ||||
| 			os << "  imm32 = " << imm32 << std::endl; | ||||
| 		} | ||||
| 
 | ||||
| #include "instructionWeights.hpp" | ||||
|  |  | |||
|  | @ -33,11 +33,11 @@ namespace RandomX { | |||
| 		uint8_t regb; | ||||
| 		uint8_t locc; | ||||
| 		uint8_t regc; | ||||
| 		uint8_t imm0; | ||||
| 		int32_t addr0; | ||||
| 		uint8_t imm8; | ||||
| 		int32_t addra; | ||||
| 		union { | ||||
| 			uint32_t addr1; | ||||
| 			int32_t imm1; | ||||
| 			uint32_t addrc; | ||||
| 			int32_t imm32; | ||||
| 		}; | ||||
| 		const char* getName() const { | ||||
| 			return names[opcode]; | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ namespace RandomX { | |||
| 
 | ||||
| 	convertible_t InterpretedVirtualMachine::loada(Instruction& inst) { | ||||
| 		convertible_t& rega = reg.r[inst.rega % RegistersCount]; | ||||
| 		rega.i64 ^= inst.addr0; //sign-extend addr0
 | ||||
| 		rega.i64 ^= inst.addra; //sign-extend addra
 | ||||
| 		addr_t addr = rega.u32; | ||||
| 		switch (inst.loca & 7) | ||||
| 		{ | ||||
|  | @ -98,7 +98,7 @@ namespace RandomX { | |||
| 		case 6: | ||||
| 		case 7: | ||||
| 			convertible_t temp; | ||||
| 			temp.i64 = inst.imm1; //sign-extend imm1
 | ||||
| 			temp.i64 = inst.imm32; //sign-extend imm32
 | ||||
| 			return temp; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -116,7 +116,7 @@ namespace RandomX { | |||
| 		case 6: | ||||
| 		case 7: | ||||
| 			convertible_t temp; | ||||
| 			temp.u64 = inst.imm0; | ||||
| 			temp.u64 = inst.imm8; | ||||
| 			return temp; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -133,7 +133,7 @@ namespace RandomX { | |||
| 			return reg.f[inst.regb % RegistersCount].f64; | ||||
| 		case 6: | ||||
| 		case 7: | ||||
| 			return (double)inst.imm1; | ||||
| 			return (double)inst.imm32; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -142,13 +142,13 @@ namespace RandomX { | |||
| 		switch (inst.locc & 7) | ||||
| 		{ | ||||
| 		case 0: | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addr1; | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addrc; | ||||
| 			return scratchpad[addr % ScratchpadL2]; | ||||
| 
 | ||||
| 		case 1: | ||||
| 		case 2: | ||||
| 		case 3: | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addr1; | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addrc; | ||||
| 			return scratchpad[addr % ScratchpadL1]; | ||||
| 
 | ||||
| 		case 4: | ||||
|  | @ -164,13 +164,13 @@ namespace RandomX { | |||
| 		switch (inst.locc & 7) | ||||
| 		{ | ||||
| 		case 0: | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addr1; | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addrc; | ||||
| 			return scratchpad[addr % ScratchpadL2]; | ||||
| 
 | ||||
| 		case 1: | ||||
| 		case 2: | ||||
| 		case 3: | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addr1; | ||||
| 			addr = reg.r[inst.regc % RegistersCount].u32 ^ inst.addrc; | ||||
| 			return scratchpad[addr % ScratchpadL1]; | ||||
| 
 | ||||
| 		case 4: | ||||
|  | @ -272,10 +272,10 @@ namespace RandomX { | |||
| 		convertible_t a = loada(inst); | ||||
| 		convertible_t b = loadbr1(inst); | ||||
| 		convertible_t& c = getcr(inst); | ||||
| 		if (b.u32 <= (uint32_t)inst.imm1) { | ||||
| 		if (b.u32 <= (uint32_t)inst.imm32) { | ||||
| 			stackPush(a); | ||||
| 			stackPush(pc); | ||||
| 			pc += (inst.imm0 & 127) + 1; | ||||
| 			pc += (inst.imm8 & 127) + 1; | ||||
| 			pc = pc % ProgramLength; | ||||
| 			if (trace) std::cout << std::hex << a.u64 << std::endl; | ||||
| 		} | ||||
|  | @ -289,7 +289,7 @@ namespace RandomX { | |||
| 		convertible_t a = loada(inst); | ||||
| 		convertible_t b = loadbr1(inst); | ||||
| 		convertible_t& c = getcr(inst); | ||||
| 		if (stack.size() > 0 && b.u32 <= (uint32_t)inst.imm1) { | ||||
| 		if (stack.size() > 0 && b.u32 <= (uint32_t)inst.imm32) { | ||||
| 			auto raddr = stackPopAddress(); | ||||
| 			auto retval = stackPopValue(); | ||||
| 			c.u64 = a.u64 ^ retval.u64; | ||||
|  |  | |||
|  | @ -259,7 +259,7 @@ namespace RandomX { | |||
| 	void JitCompilerX86::gena(Instruction& instr) { | ||||
| 		emit(uint16_t(0x8149)); //xor
 | ||||
| 		emitByte(0xf0 + (instr.rega % RegistersCount)); | ||||
| 		emit(instr.addr0); | ||||
| 		emit(instr.addra); | ||||
| 		int32_t pc; | ||||
| 		switch (instr.loca & 7) | ||||
| 		{ | ||||
|  | @ -301,7 +301,7 @@ namespace RandomX { | |||
| 		else { | ||||
| 			emitByte(0x48); //REX.W
 | ||||
| 			emit(opcodeImm); //xxx rax, imm8
 | ||||
| 			emitByte((instr.imm0 & 63)); | ||||
| 			emitByte((instr.imm8 & 63)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -312,7 +312,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			emit(opcodeImm); // xxx rax, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -323,7 +323,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			emitByte(opcodeImm); // xxx eax, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -343,7 +343,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			convertible_t bimm; | ||||
| 			bimm.f64 = (double)instr.imm1; | ||||
| 			bimm.f64 = (double)instr.imm32; | ||||
| 			emit(uint16_t(0xb848)); //movabs rax,imm64
 | ||||
| 			emit(bimm.i64); | ||||
| 			emitByte(0x66); //movq xmm1,rax
 | ||||
|  | @ -362,7 +362,7 @@ namespace RandomX { | |||
| 			emitByte(0x8b); // mov
 | ||||
| 			emitByte(0xc0 + (instr.regc % RegistersCount)); //eax, regc
 | ||||
| 			emitByte(0x35); // xor eax
 | ||||
| 			emit(instr.addr1); | ||||
| 			emit(instr.addrc); | ||||
| 			emitByte(0x25); //and
 | ||||
| 			emit(ScratchpadL2 - 1); //whole scratchpad
 | ||||
| 			emit(0xc60c8948); // mov    QWORD PTR [rsi+rax*8],rcx
 | ||||
|  | @ -375,7 +375,7 @@ namespace RandomX { | |||
| 			emitByte(0x8b); // mov
 | ||||
| 			emitByte(0xc0 + (instr.regc % RegistersCount)); //eax, regc
 | ||||
| 			emitByte(0x35); // xor eax
 | ||||
| 			emit(instr.addr1); | ||||
| 			emit(instr.addrc); | ||||
| 			emitByte(0x25); //and
 | ||||
| 			emit(ScratchpadL1 - 1); //first 16 KiB of scratchpad
 | ||||
| 			emit(0xc60c8948); // mov    QWORD PTR [rsi+rax*8],rcx
 | ||||
|  | @ -396,7 +396,7 @@ namespace RandomX { | |||
| 			emit(uint16_t(0x8b41)); //mov
 | ||||
| 			emitByte(0xc0 + regc); //eax, regc
 | ||||
| 			emitByte(0x35); // xor eax
 | ||||
| 			emit(instr.addr1); | ||||
| 			emit(instr.addrc); | ||||
| 			emitByte(0x25); //and
 | ||||
| 			emit(ScratchpadL2 - 1); //whole scratchpad
 | ||||
| 			emit(uint16_t(0x4866)); //prefix
 | ||||
|  | @ -409,7 +409,7 @@ namespace RandomX { | |||
| 			emit(uint16_t(0x8b41)); //mov
 | ||||
| 			emitByte(0xc0 + regc); //eax, regc
 | ||||
| 			emitByte(0x35); // xor eax
 | ||||
| 			emit(instr.addr1); | ||||
| 			emit(instr.addrc); | ||||
| 			emitByte(0x25); //and
 | ||||
| 			emit(ScratchpadL1 - 1); //first 16 KiB of scratchpad
 | ||||
| 			emit(uint16_t(0x4866)); //prefix
 | ||||
|  | @ -456,7 +456,7 @@ namespace RandomX { | |||
| 		else { | ||||
| 			emitByte(0x48); //REX
 | ||||
| 			emit(uint16_t(0xc069)); // imul rax, rax, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		gencr(instr); | ||||
| 	} | ||||
|  | @ -469,7 +469,7 @@ namespace RandomX { | |||
| 		else { | ||||
| 			emitByte(0x48); | ||||
| 			emit(uint16_t(0xc1c7)); // mov rcx, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		emitByte(0x48); | ||||
| 		emit(uint16_t(0xe1f7)); // mul rcx
 | ||||
|  | @ -486,7 +486,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			emitByte(0xb8); // mov eax, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		emit(0xc1af0f48); //imul rax,rcx
 | ||||
| 		gencr(instr); | ||||
|  | @ -502,7 +502,7 @@ namespace RandomX { | |||
| 		else { | ||||
| 			emitByte(0x48); | ||||
| 			emit(uint16_t(0xc0c7)); // mov rax, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		emit(0xc1af0f48); //imul rax,rcx
 | ||||
| 		gencr(instr); | ||||
|  | @ -516,7 +516,7 @@ namespace RandomX { | |||
| 		else { | ||||
| 			emitByte(0x48); | ||||
| 			emit(uint16_t(0xc1c7)); // mov rcx, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		emitByte(0x48); | ||||
| 		emit(uint16_t(0xe9f7)); // imul rcx
 | ||||
|  | @ -536,7 +536,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			emitByte(0xb9); //mov ecx, imm32
 | ||||
| 			emit(instr.imm1 != 0 ? instr.imm1 : 1); | ||||
| 			emit(instr.imm32 != 0 ? instr.imm32 : 1); | ||||
| 		} | ||||
| 		emit(0xf748d233); //xor edx,edx; div rcx
 | ||||
| 		emitByte(0xf1); | ||||
|  | @ -550,7 +550,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		else { | ||||
| 			emitByte(0xba); // xxx edx, imm32
 | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 		} | ||||
| 		emit(0xc88b480b75fffa83); | ||||
| 		emit(0x1274c9ff48c1d148); | ||||
|  | @ -661,7 +661,7 @@ namespace RandomX { | |||
| 		if ((instr.locb & 7) <= 5) { | ||||
| 			emit(uint16_t(0x8141)); //cmp regb, imm32
 | ||||
| 			emitByte(0xf8 + (instr.regb % RegistersCount)); | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 			if ((instr.locc & 7) <= 3) { | ||||
| 				emit(uint16_t(0x1676)); //jmp
 | ||||
| 			} | ||||
|  | @ -673,7 +673,7 @@ namespace RandomX { | |||
| 		} | ||||
| 		emitByte(0x50); //push rax
 | ||||
| 		emitByte(0xe8); //call
 | ||||
| 		i = wrapInstr(i + (instr.imm0 & 127) + 2); | ||||
| 		i = wrapInstr(i + (instr.imm8 & 127) + 2); | ||||
| 		if (i < instructionOffsets.size()) { | ||||
| 			emit(instructionOffsets[i] - (codePos + 4)); | ||||
| 		} | ||||
|  | @ -697,7 +697,7 @@ namespace RandomX { | |||
| 		if ((instr.locb & 7) <= 5) { | ||||
| 			emit(uint16_t(0x8141)); //cmp regb, imm32
 | ||||
| 			emitByte(0xf8 + (instr.regb % RegistersCount)); | ||||
| 			emit(instr.imm1); | ||||
| 			emit(instr.imm32); | ||||
| 			emitByte(0x77); //jmp
 | ||||
| 			emitByte(11 + crlen); | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue