mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-08 05:03:59 -05:00
146 lines
3.6 KiB
C++
146 lines
3.6 KiB
C++
/*
|
|
* Instruction.cpp
|
|
*
|
|
*/
|
|
|
|
#include "Instruction.h"
|
|
#include "instructions.h"
|
|
#include "Processor.h"
|
|
#include "Memory.h"
|
|
#include "Math/gf2n.h"
|
|
#include "GC/instructions.h"
|
|
|
|
#include "Memory.hpp"
|
|
#include "Instruction.hpp"
|
|
|
|
#include <iomanip>
|
|
|
|
template<class cgf2n>
|
|
void Instruction::execute_clear_gf2n(StackedVector<cgf2n>& registers,
|
|
MemoryPart<cgf2n>& memory, ArithmeticProcessor& Proc) const
|
|
{
|
|
auto& C2 = registers;
|
|
auto& M2C = memory;
|
|
switch (opcode)
|
|
{
|
|
#define X(NAME, PRE, CODE) \
|
|
case NAME: { PRE; for (int i = 0; i < size; i++) { CODE; } } break;
|
|
CLEAR_GF2N_INSTRUCTIONS
|
|
#undef X
|
|
}
|
|
}
|
|
|
|
template<class cgf2n>
|
|
void Instruction::gbitdec(StackedVector<cgf2n>& registers) const
|
|
{
|
|
for (int j = 0; j < size; j++)
|
|
{
|
|
typename cgf2n::internal_type a = registers.at(r[0] + j).get();
|
|
for (unsigned int i = 0; i < start.size(); i++)
|
|
{
|
|
registers.at(start[i] + j) = a & 1;
|
|
a >>= n;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class cgf2n>
|
|
void Instruction::gbitcom(StackedVector<cgf2n>& registers) const
|
|
{
|
|
for (int j = 0; j < size; j++)
|
|
{
|
|
typename cgf2n::internal_type a = 0;
|
|
for (unsigned int i = 0; i < start.size(); i++)
|
|
{
|
|
a ^= registers.at(start[i] + j).get() << (i * n);
|
|
}
|
|
registers.at(r[0] + j) = a;
|
|
}
|
|
}
|
|
|
|
void Instruction::execute_regint(ArithmeticProcessor& Proc, MemoryPart<Integer>& Mi) const
|
|
{
|
|
(void) Mi;
|
|
auto& Ci = Proc.get_Ci();
|
|
switch (opcode)
|
|
{
|
|
#define X(NAME, PRE, CODE) \
|
|
case NAME: { PRE; for (int i = 0; i < size; i++) { CODE; } } break;
|
|
REGINT_INSTRUCTIONS
|
|
#undef X
|
|
}
|
|
}
|
|
|
|
void Instruction::shuffle(ArithmeticProcessor& Proc) const
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
Proc.write_Ci(r[0] + i, Proc.read_Ci(r[1] + i));
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
int j = Proc.shared_prng.get_uint(size - i);
|
|
swap(Proc.get_Ci_ref(r[0] + i), Proc.get_Ci_ref(r[0] + i + j));
|
|
}
|
|
}
|
|
|
|
void Instruction::bitdecint(ArithmeticProcessor& Proc) const
|
|
{
|
|
for (int j = 0; j < size; j++)
|
|
{
|
|
long a = Proc.read_Ci(r[0] + j);
|
|
for (unsigned int i = 0; i < start.size(); i++)
|
|
{
|
|
Proc.get_Ci_ref(start[i] + j) = (a >> i) & 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
string BaseInstruction::get_name() const
|
|
{
|
|
switch (get_opcode())
|
|
{
|
|
#define X(NAME, PRE, CODE) \
|
|
case NAME: return #NAME;
|
|
ALL_INSTRUCTIONS
|
|
#undef X
|
|
#define X(NAME, CODE) \
|
|
case NAME: return #NAME;
|
|
COMBI_INSTRUCTIONS
|
|
default:
|
|
stringstream ss;
|
|
ss << showbase << hex << get_opcode();
|
|
return ss.str();
|
|
}
|
|
}
|
|
|
|
void BaseInstruction::bytecode_assert(bool condition) const
|
|
{
|
|
if (not condition)
|
|
throw runtime_error("bytecode assertion violated");
|
|
}
|
|
|
|
ostream& operator<<(ostream& s, const Instruction& instr)
|
|
{
|
|
s << instr.get_name();
|
|
s << " size=" << instr.get_size();
|
|
s << " n=" << instr.get_n();
|
|
s << " r=(";
|
|
for (int i = 0; i < 3; i++)
|
|
s << instr.get_r(i) << ", ";
|
|
s << instr.get_r(3);
|
|
s << ")";
|
|
if (not instr.get_start().empty())
|
|
{
|
|
s << " args=(";
|
|
for (unsigned i = 0; i < instr.get_start().size() - 1; i++)
|
|
s << instr.get_start()[i] << ", ";
|
|
s << instr.get_start().back();
|
|
s << ")";
|
|
}
|
|
return s;
|
|
}
|
|
|
|
template void Instruction::execute_clear_gf2n(StackedVector<gf2n_short>& registers,
|
|
MemoryPart<gf2n_short>& memory, ArithmeticProcessor& Proc) const;
|
|
template void Instruction::execute_clear_gf2n(StackedVector<gf2n_long>& registers,
|
|
MemoryPart<gf2n_long>& memory, ArithmeticProcessor& Proc) const;
|