You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.8 KiB
185 lines
4.8 KiB
//===- 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/LD/LDSection.h"
|
|
#include "mcld/Object/SectionMap.h"
|
|
#include "mcld/Script/Operand.h"
|
|
#include "mcld/Module.h"
|
|
|
|
#include <llvm/Support/Casting.h>
|
|
|
|
#include <cassert>
|
|
|
|
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;
|
|
}
|
|
|
|
} // namespace mcld
|