C++程序  |  189行  |  4.85 KB

//===- UnaryOp.cpp --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Script/UnaryOp.h>
#include <mcld/Script/Operand.h>
#include <mcld/Object/SectionMap.h>
#include <mcld/LD/LDSection.h>
#include <mcld/Module.h>
#include <llvm/Support/Casting.h>
#include <cassert>

using namespace mcld;
//===----------------------------------------------------------------------===//
// UnaryOp
//===----------------------------------------------------------------------===//
template<>
IntOperand* UnaryOp<Operator::UNARY_PLUS>::eval(const Module& pModule,
                                                const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  res->setValue(+ m_pOperand->value());
  return res;
}

template<>
IntOperand*
UnaryOp<Operator::UNARY_MINUS>::eval(const Module& pModule,
                                     const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  res->setValue(- m_pOperand->value());
  return res;
}

template<>
IntOperand*
UnaryOp<Operator::LOGICAL_NOT>::eval(const Module& pModule,
                                     const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  res->setValue(! m_pOperand->value());
  return res;
}

template<>
IntOperand*
UnaryOp<Operator::BITWISE_NOT>::eval(const Module& pModule,
                                     const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  res->setValue(~ m_pOperand->value());
  return res;
}

template<>
IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module& pModule,
                                              const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::ADDR>::eval(const Module& pModule,
                                          const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  const LDSection* sect = NULL;
  switch (m_pOperand->type()) {
  case Operand::SECTION:
    sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
    break;
  case Operand::SECTION_DESC:
    sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
    break;
  default:
    assert(0);
    break;
  }
  assert(sect != NULL);
  res->setValue(sect->addr());
  return res;
}

template<>
IntOperand* UnaryOp<Operator::ALIGNOF>::eval(const Module& pModule,
                                             const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  const LDSection* sect = NULL;
  switch (m_pOperand->type()) {
  case Operand::SECTION:
    sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
    break;
  case Operand::SECTION_DESC:
    sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
    break;
  default:
    assert(0);
    break;
  }
  assert(sect != NULL);
  res->setValue(sect->align());
  return res;
}

template<>
IntOperand*
UnaryOp<Operator::DATA_SEGMENT_END>::eval(const Module& pModule,
                                          const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  res->setValue(m_pOperand->value());
  return res;
}

template<>
IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module& pModule,
                                             const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module& pModule,
                                            const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module& pModule,
                                              const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::NEXT>::eval(const Module& pModule,
                                          const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module& pModule,
                                            const TargetLDBackend& pBackend)
{
  // TODO
  assert(0);
  return result();
}

template<>
IntOperand* UnaryOp<Operator::SIZEOF>::eval(const Module& pModule,
                                            const TargetLDBackend& pBackend)
{
  IntOperand* res = result();
  const LDSection* sect = NULL;
  switch (m_pOperand->type()) {
  case Operand::SECTION:
    sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
    break;
  case Operand::SECTION_DESC:
    sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
    break;
  default:
    assert(0);
    break;
  }
  assert(sect != NULL);
  res->setValue(sect->size());
  return res;
}