// // This file is part of Mipsy, a tiny MIPS simulator // Copyright (C) 2003 Benoit Perrot // // Mipsy is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // Mipsy is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef INST_PROGRAM_SOLVER_HH # define INST_PROGRAM_SOLVER_HH // FIXME: lack of compatibility # include # include "common.hh" # include "inst/exp-visitor.hh" # include "inst/exp.hh" # include "inst/visitor.hh" # include "inst/all.hh" # include "inst/program.hh" namespace inst { class ProgramSolver: protected Visitor, protected ExpVisitor { public: virtual ~ProgramSolver() { } public: void solve(Program& program) { _program = &program; int i; for (i = 0, _pc = 4; i < program.text_section().size(); ++i, _pc += 4) _program->text_section()[i].accept(*this); } protected: int _pc; protected: void resolve_exp(Exp& exp) { exp.accept(*this); } virtual void visit(IntExp& i) { i.set_immediate(i.get_integer()); } virtual void visit(LabelExp& l) { if (! _program->data_section().has_label(l.get_label())) if (! _program->text_section().has_label(l.get_label())) { std::cerr << "Undefined label: "<< l.get_label() << std::endl; exit_set(exit_solve); } else l.set_immediate(_program->text_section(). get_offset(l.get_label()) - _pc); else l.set_immediate(_program->data_section().get_offset(l.get_label())); } virtual void visit(OpExp& o) { o.get_left().accept(*this); o.get_right().accept(*this); switch (o.kind) { case OpExp::add: o.set_immediate(o.get_left().get_immediate() + o.get_right().get_immediate()); break; case OpExp::sub: o.set_immediate(o.get_left().get_immediate() - o.get_right().get_immediate()); break; case OpExp::mul: o.set_immediate(o.get_left().get_immediate() * o.get_right().get_immediate()); break; case OpExp::div: o.set_immediate(o.get_left().get_immediate() / o.get_right().get_immediate()); break; } } protected: virtual void visit(Add&) {} virtual void visit(Addi& addi) { resolve_exp(addi.get_imm()); } virtual void visit(Addu&) {} virtual void visit(Addiu& addiu) { resolve_exp(addiu.get_imm()); } virtual void visit(Sub&) {} virtual void visit(Subu&) {} virtual void visit(Sll& sll) { resolve_exp(sll.get_imm()); } virtual void visit(Sllv&) {} virtual void visit(Sra& sra) { resolve_exp(sra.get_imm()); } virtual void visit(Srav&) {} virtual void visit(Srl& srl) { resolve_exp(srl.get_imm()); } virtual void visit(Srlv&) {} virtual void visit(Mul&) {} virtual void visit(Div&) {} virtual void visit(Divu&) {} protected: virtual void visit(And&) {} virtual void visit(Andi& andi) { resolve_exp(andi.get_imm()); } virtual void visit(Or&) {} virtual void visit(Ori& ori) { resolve_exp(ori.get_imm()); } virtual void visit(Nor&) {} virtual void visit(Xor&) {} virtual void visit(Xori& xori) { resolve_exp(xori.get_imm()); } protected: virtual void visit(Slt&) {} virtual void visit(Slti& slti) { resolve_exp(slti.get_imm()); } virtual void visit(Sltu&) {} virtual void visit(Sltiu& sltiu) { resolve_exp(sltiu.get_imm()); } protected: virtual void visit(Beq& beq) { resolve_exp(beq.get_label()); } virtual void visit(Bne& bne) { resolve_exp(bne.get_label()); } virtual void visit(Bgez& bgez) { resolve_exp(bgez.get_label()); } virtual void visit(Bgezal& bgezal) { resolve_exp(bgezal.get_label()); } virtual void visit(Bgtz& bgtz) { resolve_exp(bgtz.get_label()); } virtual void visit(Blez& blez) { resolve_exp(blez.get_label()); } virtual void visit(Bltz& bltz) { resolve_exp(bltz.get_label()); } virtual void visit(Bltzal& bltzal) { resolve_exp(bltzal.get_label()); } virtual void visit(Jmp& jmp) { resolve_exp(jmp.get_label()); } virtual void visit(Jr&) {} virtual void visit(Jal& jal) { resolve_exp(jal.get_label()); } virtual void visit(Jalr&) {} protected: virtual void visit(Lb& lb) { resolve_exp(lb.get_offset()); } virtual void visit(Lbu& lbu) { resolve_exp(lbu.get_offset()); } virtual void visit(Lw& lw) { resolve_exp(lw.get_offset()); } virtual void visit(Li& li) { resolve_exp(li.get_imm()); } virtual void visit(Sb& sb) { resolve_exp(sb.get_offset()); } virtual void visit(Sw& sw) { resolve_exp(sw.get_offset()); } protected: virtual void visit(Mfhi&) {} virtual void visit(Mflo&) {} virtual void visit(Mthi&) {} virtual void visit(Mtlo&) {} protected: virtual void visit(Syscall&) {} protected: virtual void visit(Nop&) {} protected: Program* _program; }; } // namespace inst #endif // !INST_PROGRAM_SOLVER_HH