mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-08 05:03:59 -05:00
431 lines
9.1 KiB
C++
431 lines
9.1 KiB
C++
#ifndef _Instruction
|
|
#define _Instruction
|
|
|
|
/* Class to read and decode an instruction
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
#include "Math/bigint.h"
|
|
|
|
template<class sint, class sgf2n> class Machine;
|
|
template<class sint, class sgf2n> class Processor;
|
|
template<class T> class SubProcessor;
|
|
template<class T> class MemoryPart;
|
|
template<class T> class StackedVector;
|
|
class ArithmeticProcessor;
|
|
class SwitchableOutput;
|
|
|
|
/*
|
|
* Opcode constants
|
|
*
|
|
* Whenever these are changed the corresponding dict in Compiler/instructions_base.py
|
|
* MUST also be changed. (+ the documentation)
|
|
*/
|
|
enum
|
|
{
|
|
CISC = 0,
|
|
// Load/store
|
|
LDI = 0x1,
|
|
LDSI = 0x2,
|
|
LDMC = 0x3,
|
|
LDMS = 0x4,
|
|
STMC = 0x5,
|
|
STMS = 0x6,
|
|
LDMCI = 0x7,
|
|
LDMSI = 0x8,
|
|
STMCI = 0x9,
|
|
STMSI = 0xA,
|
|
MOVC = 0xB,
|
|
MOVS = 0xC,
|
|
PROTECTMEMS = 0xD,
|
|
PROTECTMEMC = 0xE,
|
|
PROTECTMEMINT = 0xF,
|
|
LDMINT = 0xCA,
|
|
STMINT = 0xCB,
|
|
LDMINTI = 0xCC,
|
|
STMINTI = 0xCD,
|
|
PUSHINT = 0xCE,
|
|
POPINT = 0xCF,
|
|
MOVINT = 0xD0,
|
|
// Machine
|
|
LDTN = 0x10,
|
|
LDARG = 0x11,
|
|
REQBL = 0x12,
|
|
STARG = 0x13,
|
|
TIME = 0x14,
|
|
START = 0x15,
|
|
STOP = 0x16,
|
|
USE = 0x17,
|
|
USE_INP = 0x18,
|
|
RUN_TAPE = 0x19,
|
|
JOIN_TAPE = 0x1A,
|
|
CRASH = 0x1B,
|
|
USE_PREP = 0x1C,
|
|
STARTGRIND = 0x1D,
|
|
STOPGRIND = 0x1E,
|
|
NPLAYERS = 0xE2,
|
|
THRESHOLD = 0xE3,
|
|
PLAYERID = 0xE4,
|
|
USE_EDABIT = 0xE5,
|
|
USE_MATMUL = 0x1F,
|
|
ACTIVE = 0xE9,
|
|
CMDLINEARG = 0xEB,
|
|
CALL_TAPE = 0xEC,
|
|
CALL_ARG = 0xED,
|
|
// Addition
|
|
ADDC = 0x20,
|
|
ADDS = 0x21,
|
|
ADDM = 0x22,
|
|
ADDCI = 0x23,
|
|
ADDSI = 0x24,
|
|
SUBC = 0x25,
|
|
SUBS = 0x26,
|
|
SUBML = 0x27,
|
|
SUBMR = 0x28,
|
|
SUBCI = 0x29,
|
|
SUBSI = 0x2A,
|
|
SUBCFI = 0x2B,
|
|
SUBSFI = 0x2C,
|
|
PREFIXSUMS = 0x2D,
|
|
PICKS = 0x2E,
|
|
CONCATS = 0x2F,
|
|
ZIPS = 0x3F,
|
|
// Multiplication/division/other arithmetic
|
|
MULC = 0x30,
|
|
MULM = 0x31,
|
|
MULCI = 0x32,
|
|
MULSI = 0x33,
|
|
DIVC = 0x34,
|
|
DIVCI = 0x35,
|
|
MODC = 0x36,
|
|
MODCI = 0x37,
|
|
LEGENDREC = 0x38,
|
|
DIGESTC = 0x39,
|
|
INV2M = 0x3a,
|
|
FLOORDIVC = 0x3b,
|
|
// Open
|
|
OPEN = 0xA5,
|
|
MULS = 0xA6,
|
|
MULRS = 0xA7,
|
|
DOTPRODS = 0xA8,
|
|
TRUNC_PR = 0xA9,
|
|
MATMULS = 0xAA,
|
|
MATMULSM = 0xAB,
|
|
CONV2DS = 0xAC,
|
|
CHECK = 0xAF,
|
|
PRIVATEOUTPUT = 0xAD,
|
|
// Shuffling
|
|
SECSHUFFLE = 0xFA,
|
|
GENSECSHUFFLE = 0xFB,
|
|
APPLYSHUFFLE = 0xFC,
|
|
DELSHUFFLE = 0xFD,
|
|
INVPERM = 0xFE,
|
|
// Data access
|
|
TRIPLE = 0x50,
|
|
BIT = 0x51,
|
|
SQUARE = 0x52,
|
|
INV = 0x53,
|
|
INPUTMASK = 0x56,
|
|
INPUTMASKREG = 0x5C,
|
|
PREP = 0x57,
|
|
DABIT = 0x58,
|
|
EDABIT = 0x59,
|
|
SEDABIT = 0x5A,
|
|
RANDOMS = 0x5B,
|
|
RANDOMFULLS = 0x5D,
|
|
UNSPLIT = 0x5E,
|
|
// Input
|
|
INPUT = 0x60,
|
|
INPUTFIX = 0xF0,
|
|
INPUTFLOAT = 0xF1,
|
|
INPUTMIXED = 0xF2,
|
|
INPUTMIXEDREG = 0xF3,
|
|
RAWINPUT = 0xF4,
|
|
INPUTPERSONAL = 0xF5,
|
|
SENDPERSONAL = 0xF6,
|
|
STARTINPUT = 0x61,
|
|
STOPINPUT = 0x62,
|
|
READSOCKETC = 0x63,
|
|
READSOCKETS = 0x64,
|
|
WRITESOCKETC = 0x65,
|
|
WRITESOCKETS = 0x66,
|
|
READSOCKETINT = 0x69,
|
|
WRITESOCKETINT = 0x6a,
|
|
WRITESOCKETSHARE = 0x6b,
|
|
LISTEN = 0x6c,
|
|
ACCEPTCLIENTCONNECTION = 0x6d,
|
|
CLOSECLIENTCONNECTION = 0x6e,
|
|
INITCLIENTCONNECTION = 0x6f,
|
|
// Bitwise logic
|
|
ANDC = 0x70,
|
|
XORC = 0x71,
|
|
ORC = 0x72,
|
|
ANDCI = 0x73,
|
|
XORCI = 0x74,
|
|
ORCI = 0x75,
|
|
NOTC = 0x76,
|
|
// Bitwise shifts
|
|
SHLC = 0x80,
|
|
SHRC = 0x81,
|
|
SHLCI = 0x82,
|
|
SHRCI = 0x83,
|
|
SHRSI = 0x84,
|
|
// Branching and comparison
|
|
JMP = 0x90,
|
|
JMPNZ = 0x91,
|
|
JMPEQZ = 0x92,
|
|
EQZC = 0x93,
|
|
LTZC = 0x94,
|
|
LTC = 0x95,
|
|
GTC = 0x96,
|
|
EQC = 0x97,
|
|
JMPI = 0x98,
|
|
// Integers
|
|
BITDECINT = 0x99,
|
|
LDINT = 0x9A,
|
|
ADDINT = 0x9B,
|
|
SUBINT = 0x9C,
|
|
MULINT = 0x9D,
|
|
DIVINT = 0x9E,
|
|
PRINTINT = 0x9F,
|
|
INCINT = 0xD1,
|
|
SHUFFLE = 0xD2,
|
|
// Conversion
|
|
CONVINT = 0xC0,
|
|
CONVMODP = 0xC1,
|
|
|
|
// IO
|
|
PRINTMEM = 0xB0,
|
|
PRINTREG = 0XB1,
|
|
RAND = 0xB2,
|
|
PRINTREGPLAIN = 0xB3,
|
|
PRINTREGPLAINS = 0xEA,
|
|
PRINTCHR = 0xB4,
|
|
PRINTSTR = 0xB5,
|
|
PUBINPUT = 0xB6,
|
|
RAWOUTPUT = 0xB7,
|
|
STARTPRIVATEOUTPUT = 0xB8,
|
|
STOPPRIVATEOUTPUT = 0xB9,
|
|
PRINTCHRINT = 0xBA,
|
|
PRINTSTRINT = 0xBB,
|
|
PRINTFLOATPLAIN = 0xBC,
|
|
WRITEFILESHARE = 0xBD,
|
|
READFILESHARE = 0xBE,
|
|
CONDPRINTSTR = 0xBF,
|
|
PRINTFLOATPREC = 0xE0,
|
|
CONDPRINTPLAIN = 0xE1,
|
|
INTOUTPUT = 0xE6,
|
|
FLOATOUTPUT = 0xE7,
|
|
FIXINPUT = 0xE8,
|
|
|
|
// GF(2^n) versions
|
|
|
|
// Load/store
|
|
GLDI = 0x101,
|
|
GLDSI = 0x102,
|
|
GLDMC = 0x103,
|
|
GLDMS = 0x104,
|
|
GSTMC = 0x105,
|
|
GSTMS = 0x106,
|
|
GLDMCI = 0x107,
|
|
GLDMSI = 0x108,
|
|
GSTMCI = 0x109,
|
|
GSTMSI = 0x10A,
|
|
GMOVC = 0x10B,
|
|
GMOVS = 0x10C,
|
|
GPROTECTMEMS = 0x10D,
|
|
GPROTECTMEMC = 0x10E,
|
|
// Machine
|
|
GREQBL = 0x112,
|
|
GUSE_PREP = 0x11C,
|
|
// Addition
|
|
GADDC = 0x120,
|
|
GADDS = 0x121,
|
|
GADDM = 0x122,
|
|
GADDCI = 0x123,
|
|
GADDSI = 0x124,
|
|
GSUBC = 0x125,
|
|
GSUBS = 0x126,
|
|
GSUBML = 0x127,
|
|
GSUBMR = 0x128,
|
|
GSUBCI = 0x129,
|
|
GSUBSI = 0x12A,
|
|
GSUBCFI = 0x12B,
|
|
GSUBSFI = 0x12C,
|
|
// Multiplication/division
|
|
GMULC = 0x130,
|
|
GMULM = 0x131,
|
|
GMULCI = 0x132,
|
|
GMULSI = 0x133,
|
|
GDIVC = 0x134,
|
|
GDIVCI = 0x135,
|
|
GMULBITC = 0x136,
|
|
GMULBITM = 0x137,
|
|
// Open
|
|
GOPEN = 0x1A5,
|
|
GMULS = 0x1A6,
|
|
GMULRS = 0x1A7,
|
|
GDOTPRODS = 0x1A8,
|
|
GMATMULS = 0x1AA,
|
|
GMATMULSM = 0x1AB,
|
|
GSECSHUFFLE = 0x1FA,
|
|
// Data access
|
|
GTRIPLE = 0x150,
|
|
GBIT = 0x151,
|
|
GSQUARE = 0x152,
|
|
GINV = 0x153,
|
|
GBITTRIPLE = 0x154,
|
|
GBITGF2NTRIPLE = 0x155,
|
|
GINPUTMASK = 0x156,
|
|
GPREP = 0x157,
|
|
// Input
|
|
GINPUT = 0x160,
|
|
GSTARTINPUT = 0x161,
|
|
GSTOPINPUT = 0x162,
|
|
GREADSOCKETS = 0x164,
|
|
GWRITESOCKETS = 0x166,
|
|
GRAWINPUT = 0x1F4,
|
|
// Bitwise logic
|
|
GANDC = 0x170,
|
|
GXORC = 0x171,
|
|
GORC = 0x172,
|
|
GANDCI = 0x173,
|
|
GXORCI = 0x174,
|
|
GORCI = 0x175,
|
|
GNOTC = 0x176,
|
|
// Bitwise shifts
|
|
GSHLCI = 0x182,
|
|
GSHRCI = 0x183,
|
|
GSHRSI = 0x184,
|
|
GBITDEC = 0x18A,
|
|
GBITCOM = 0x18B,
|
|
// Conversion
|
|
GCONVINT = 0x1C0,
|
|
GCONVGF2N = 0x1C1,
|
|
// IO
|
|
GPRINTMEM = 0x1B0,
|
|
GPRINTREG = 0X1B1,
|
|
GPRINTREGPLAIN = 0x1B3,
|
|
GPRINTREGPLAINS = 0x1EA,
|
|
GRAWOUTPUT = 0x1B7,
|
|
GSTARTPRIVATEOUTPUT = 0x1B8,
|
|
GSTOPPRIVATEOUTPUT = 0x1B9,
|
|
GWRITEFILESHARE = 0x1BD,
|
|
GREADFILESHARE = 0x1BE,
|
|
// Commsec ops
|
|
INITSECURESOCKET = 0x1BA,
|
|
RESPSECURESOCKET = 0x1BB
|
|
};
|
|
|
|
|
|
// Register types
|
|
enum RegType {
|
|
INT,
|
|
SBIT,
|
|
CBIT,
|
|
DYN_SBIT,
|
|
SINT,
|
|
CINT,
|
|
SGF2N,
|
|
CGF2N,
|
|
NONE,
|
|
MAX_REG_TYPE,
|
|
};
|
|
|
|
template<class sint, class sgf2n>
|
|
struct TempVars {
|
|
typename sgf2n::clear ans2;
|
|
typename sint::clear ansp;
|
|
sint Sansp;
|
|
bigint aa,aa2;
|
|
typename sint::open_type rrp, xip;
|
|
};
|
|
|
|
|
|
class BaseInstruction
|
|
{
|
|
friend class Program;
|
|
template<class T> friend class RepRingOnlyEdabitPrep;
|
|
|
|
protected:
|
|
int opcode; // The code
|
|
int size; // Vector size
|
|
int r[4]; // Fixed parameter registers
|
|
size_t n; // Possible immediate value
|
|
vector<int> start; // Values for a start/stop open
|
|
string str;
|
|
|
|
void bytecode_assert(bool condition) const;
|
|
|
|
public:
|
|
BaseInstruction() : opcode(0), size(0), n(0) {}
|
|
virtual ~BaseInstruction() {};
|
|
|
|
int get_r(int i) const { return r[i]; }
|
|
size_t get_n() const { return n; }
|
|
const vector<int>& get_start() const { return start; }
|
|
int get_opcode() const { return opcode; }
|
|
int get_size() const { return size; }
|
|
|
|
// Reads a single instruction from the istream
|
|
void parse(istream& s, int inst_pos);
|
|
void parse_operands(istream& s, int pos, int file_pos);
|
|
|
|
bool is_gf2n_instruction() const { return ((opcode&0x100)!=0); }
|
|
virtual int get_reg_type() const;
|
|
|
|
bool is_direct_memory_access() const;
|
|
|
|
// Returns the memory size used if applicable and known
|
|
size_t get_mem(RegType reg_type) const;
|
|
|
|
// Returns the maximal register used
|
|
unsigned get_max_reg(int reg_type) const;
|
|
|
|
string get_name() const;
|
|
};
|
|
|
|
class DataPositions;
|
|
|
|
class Instruction : public BaseInstruction
|
|
{
|
|
public:
|
|
// Return whether usage is known
|
|
bool get_offline_data_usage(DataPositions& usage);
|
|
|
|
friend ostream& operator<<(ostream& s,const Instruction& instr);
|
|
|
|
// Execute this instruction, updateing the processor and memory
|
|
// and streams pointing to the triples etc
|
|
template<class sint, class sgf2n>
|
|
void execute(Processor<sint, sgf2n>& Proc) const;
|
|
|
|
template<class cgf2n>
|
|
void execute_clear_gf2n(StackedVector<cgf2n>& registers, MemoryPart<cgf2n>& memory,
|
|
ArithmeticProcessor& Proc) const;
|
|
|
|
template<class cgf2n>
|
|
void gbitdec(StackedVector<cgf2n>& registers) const;
|
|
template<class cgf2n>
|
|
void gbitcom(StackedVector<cgf2n>& registers) const;
|
|
|
|
void execute_regint(ArithmeticProcessor& Proc, MemoryPart<Integer>& Mi) const;
|
|
|
|
void shuffle(ArithmeticProcessor& Proc) const;
|
|
void bitdecint(ArithmeticProcessor& Proc) const;
|
|
|
|
template<class T>
|
|
void print(SwitchableOutput& out, T* v, T* p = 0, T* s = 0, T* z = 0,
|
|
T* nan = 0) const;
|
|
|
|
template<class T>
|
|
typename T::clear sanitize(SubProcessor<T>& proc, int reg) const;
|
|
};
|
|
|
|
#endif
|
|
|