#include #include "instruction.h" #include "emulator.h" instruction::instruction( const char * name, evaluator * evaluator, std::vector dst, unsigned int src_reg_count) : m_name(name), m_evaluator(evaluator), m_dst(dst), m_src_reg_count(src_reg_count) { } void instruction::execute(emulator & emulator) { unsigned int i; for (i = 0; i < m_dst.size(); i++) { value * l = NULL; value * r = NULL; switch(m_src_regs.size()) { case 2: r = emulator.get_value(m_src_regs[1][i]); /* Fall trough */ case 1: l = emulator.get_value(m_src_regs[0][i]); break; } emulator.queue_write(m_dst[i], new tree_value(m_evaluator, l, r)); } } void instruction::add_src_reg(std::vector src_reg) { assert(m_src_regs.size() < m_src_reg_count); m_src_regs.push_back(src_reg); } add_instruction::add_instruction( std::vector dst, std::vector src0, std::vector src1) : /*XXX: Can we call our own constructor here? */ instruction("ADD", new add_evaluator(), dst, 2) { m_src_regs.push_back(src0); m_src_regs.push_back(src1); } add_instruction::add_instruction(std::vector dst) : instruction("ADD", new add_evaluator(), dst, 2) { } void add_instruction::execute(emulator & emulator) { unsigned int i; for (i = 0; i < m_dst.size(); i++) { tree_value * val = new tree_value(this->m_evaluator, emulator.get_value(m_src_regs[0][i]), emulator.get_value(m_src_regs[1][i])); emulator.queue_write(m_dst[i], val); } } mov_instruction::mov_instruction(std::vector dst) : instruction("MOV", NULL, dst, 1) { } void mov_instruction::execute(emulator & emulator) { unsigned int i; for (i = 0; i < m_dst.size(); i++) { emulator.queue_write(m_dst[i], emulator.get_value(m_src_regs[0][i])); } } mul_instruction::mul_instruction(std::vector dst) : instruction("MUL", new mul_evaluator(), dst, 2) { } void mul_instruction::execute(emulator & emulator) { unsigned int i; for (i = 0; i < m_dst.size(); i++) { tree_value * val = new tree_value(this->m_evaluator, emulator.get_value(m_src_regs[0][i]), emulator.get_value(m_src_regs[1][i])); emulator.queue_write(m_dst[i], val); } } mad_instruction::mad_instruction(std::vector dst) : instruction("MAD", NULL, dst, 3) { } void mad_instruction::execute(emulator & emulator) { unsigned int i; for(i = 0; i < m_dst.size(); i++) { tree_value * mul = new tree_value(new mul_evaluator(), emulator.get_value(m_src_regs[0][i]), emulator.get_value(m_src_regs[1][i])); tree_value * mad = new tree_value(new add_evaluator(), mul, emulator.get_value(m_src_regs[2][i])); emulator.queue_write(m_dst[i], mad); } } abs_instruction::abs_instruction(std::vector dst) : instruction("ABS", new abs_evaluator(), dst, 1) { } sub_instruction::sub_instruction(std::vector dst) : instruction("SUB", new sub_evaluator(), dst, 2) { } sat_instruction::sat_instruction(std::vector dst) : instruction("SAT", new sat_evaluator(), dst, 1) { } rcp_instruction::rcp_instruction(std::vector dst) : instruction("RCP", new rcp_evaluator(), dst, 1) { } min_instruction::min_instruction(std::vector dst) : instruction("MIN", new min_evaluator(), dst, 2) { } max_instruction::max_instruction(std::vector dst) : instruction("MAX", new max_evaluator(), dst, 2) { } dp_instruction::dp_instruction( unsigned int components, std::vector dst) : instruction("DP", NULL, dst, 2), m_components(components) { } void dp_instruction::execute(emulator & emulator) { std::vector mul; tree_value * dp; unsigned int i; int j; for (i = 0; i < m_components; i++) { mul.push_back(new tree_value( new mul_evaluator(), emulator.get_value(m_src_regs[0][i]), emulator.get_value(m_src_regs[1][i]))); } dp = new tree_value(new add_evaluator(), mul[mul.size() -1], mul[mul.size() -2]); for (j = mul.size() - 3; j >= 0; j--) { dp = new tree_value(new add_evaluator(), mul[j], dp); } for (i = 0; i < m_dst.size(); i++) { emulator.queue_write(m_dst[i], dp->clone()); } delete dp; }