1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- RpnEvaluator.cpp ---------------------------------------------------===// 2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// The MCLinker Project 4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source 6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details. 7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnEvaluator.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/ExprToken.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operator.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnExpr.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h> 20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/DataTypes.h> 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <stack> 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert> 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesRpnEvaluator::RpnEvaluator(const Module& pModule, 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const TargetLDBackend& pBackend) 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Module(pModule), m_Backend(pBackend) { 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool RpnEvaluator::eval(const RpnExpr& pExpr, uint64_t& pResult) { 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::stack<Operand*> operandStack; 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RpnExpr::const_iterator it = pExpr.begin(), ie = pExpr.end(); it != ie; 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch ((*it)->kind()) { 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case ExprToken::OPERATOR: { 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operator* op = llvm::cast<Operator>(*it); 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (op->arity()) { 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Operator::NULLARY: { 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Operator::UNARY: { 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd = operandStack.top(); 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd); 4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Operator::BINARY: { 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd2 = operandStack.top(); 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd1 = operandStack.top(); 5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd1); 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd2); 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Operator::TERNARY: { 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd3 = operandStack.top(); 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd2 = operandStack.top(); 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd1 = operandStack.top(); 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.pop(); 6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd1); 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd2); 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines op->appendOperand(opd3); 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch operator arity 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines case ExprToken::OPERAND: { 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines Operand* opd = llvm::cast<Operand>(*it); 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (opd->type()) { 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Operand::SYMBOL: { 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines // It's possible that there are no operators in an expression, so 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines // we set up symbol operand here. 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!opd->isDot()) { 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines SymOperand* sym_opd = llvm::cast<SymOperand>(opd); 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSymbol* symbol = 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Module.getNamePool().findSymbol(sym_opd->name()); 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (symbol == NULL) { 9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::fail_sym_resolution) << __FILE__ << __LINE__ 9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines << "mclinker@googlegroups.com"; 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines sym_opd->setValue(symbol->value()); 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(opd); 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines operandStack.push(opd); 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch operand type 102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 106f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // stack top is result 108f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines assert(operandStack.top()->type() == Operand::SYMBOL || 109f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.top()->type() == Operand::INTEGER || 110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.top()->type() == Operand::FRAGMENT); 111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pResult = operandStack.top()->value(); 112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return true; 113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 114f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 116