/* * Processor.h * */ #ifndef GC_PROCESSOR_H_ #define GC_PROCESSOR_H_ #include using namespace std; #include "GC/Clear.h" #include "GC/Machine.h" #include "GC/RuntimeBranching.h" #include "Math/Integer.h" #include "Processor/ProcessorBase.h" #include "Processor/Instruction.h" #include "Tools/CheckVector.h" namespace GC { template class Processor : public ::ProcessorBase, public GC::RuntimeBranching { public: static int check_args(const vector& args, int n); template static void check_input(const U& in, const int* params); Machine* machine; Memories& memories; unsigned int PC; unsigned int time; // rough measure for the memory usage size_t complexity; StackedVector S; StackedVector C; StackedVector I; Timer xor_timer; typename T::out_type out; Processor(Machine& machine); Processor(Memories& memories, Machine* machine = 0); ~Processor(); template void reset(const U& program, int arg); template void reset(const U& program); long long get_input(const int* params, bool interactive = false); template U get_long_input(const int* params, ProcessorBase& input_proc, bool interactive = false); void bitcoms(T& x, const vector& regs) { x.bitcom(S, regs); } void bitdecs(const vector& regs, const T& x) { x.bitdec(S, regs); } void bitdecc(const vector& regs, const Clear& x); void bitdecint(const vector& regs, const Integer& x); void random_bit(T &x) { x.random_bit(); } template void load_dynamic_direct(const vector& args, U& dynamic_memory); template void store_dynamic_direct(const vector& args, U& dynamic_memory); template void load_dynamic_indirect(const vector& args, U& dynamic_memory); template void store_dynamic_indirect(const vector& args, U& dynamic_memory); template void store_clear_in_dynamic(const vector& args, U& dynamic_memory); template void mem_op(int n, U& dest, const V& source, Integer dest_address, Integer source_address); void xors(const vector& args); void xors(const vector& args, size_t start, size_t end); void xorc(const ::BaseInstruction& instruction); void nots(const ::BaseInstruction& instruction); void notcb(const ::BaseInstruction& instruction); void movsb(const ::BaseInstruction& instruction); void andm(const ::BaseInstruction& instruction); void and_(const vector& args, bool repeat); void andrs(const vector& args) { and_(args, true); } void ands(const vector& args) { and_(args, false); } void andrsvec(const vector& args); void input(const vector& args); void inputb(typename T::Input& input, ProcessorBase& input_processor, const vector& args, int my_num); void inputbvec(typename T::Input& input, ProcessorBase& input_processor, const vector& args, PlayerBase& P); void reveal(const vector& args); template void convcbit2s(const BaseInstruction& instruction); void convcbitvec(const BaseInstruction& instruction, StackedVector& Ci, Player* P); void print_reg(int reg, int n, int size); template void print_reg_plain(U& value); void print_reg_signed(unsigned n_bits, Integer value); void print_chr(int n); void print_str(int n); void print_float(const vector& args); void print_float_prec(int n); void incint(const BaseInstruction& instruction); void push_stack(); void push_args(const vector& args); void pop_stack(const vector& results); template void call_tape(const BaseInstruction& instruction, U& dynamic_memory); }; template inline int GC::Processor::check_args(const vector& args, int n) { if (args.size() % n != 0) throw runtime_error("invalid number of arguments"); int total = 0; for (auto it = args.begin(); it < args.end(); it += n) { total += *it; } return total; } } /* namespace GC */ #endif /* GC_PROCESSOR_H_ */