#ifndef _Instruction #define _Instruction /* Class to read and decode an instruction */ #include #include #include using namespace std; #include "Math/bigint.h" template class Machine; template class Processor; template class SubProcessor; template class MemoryPart; template 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 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 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 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& 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 void execute(Processor& Proc) const; template void execute_clear_gf2n(StackedVector& registers, MemoryPart& memory, ArithmeticProcessor& Proc) const; template void gbitdec(StackedVector& registers) const; template void gbitcom(StackedVector& registers) const; void execute_regint(ArithmeticProcessor& Proc, MemoryPart& Mi) const; void shuffle(ArithmeticProcessor& Proc) const; void bitdecint(ArithmeticProcessor& Proc) const; template void print(SwitchableOutput& out, T* v, T* p = 0, T* s = 0, T* z = 0, T* nan = 0) const; template typename T::clear sanitize(SubProcessor& proc, int reg) const; }; #endif