Home | History | Annotate | Download | only in Script
      1 //===- UnaryOp.cpp --------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include <mcld/Script/UnaryOp.h>
     10 #include <mcld/Script/Operand.h>
     11 #include <mcld/Object/SectionMap.h>
     12 #include <mcld/LD/LDSection.h>
     13 #include <mcld/Module.h>
     14 #include <llvm/Support/Casting.h>
     15 #include <cassert>
     16 
     17 using namespace mcld;
     18 //===----------------------------------------------------------------------===//
     19 // UnaryOp
     20 //===----------------------------------------------------------------------===//
     21 template<>
     22 IntOperand* UnaryOp<Operator::UNARY_PLUS>::eval(const Module& pModule,
     23                                                 const TargetLDBackend& pBackend)
     24 {
     25   IntOperand* res = result();
     26   res->setValue(+ m_pOperand->value());
     27   return res;
     28 }
     29 
     30 template<>
     31 IntOperand*
     32 UnaryOp<Operator::UNARY_MINUS>::eval(const Module& pModule,
     33                                      const TargetLDBackend& pBackend)
     34 {
     35   IntOperand* res = result();
     36   res->setValue(- m_pOperand->value());
     37   return res;
     38 }
     39 
     40 template<>
     41 IntOperand*
     42 UnaryOp<Operator::LOGICAL_NOT>::eval(const Module& pModule,
     43                                      const TargetLDBackend& pBackend)
     44 {
     45   IntOperand* res = result();
     46   res->setValue(! m_pOperand->value());
     47   return res;
     48 }
     49 
     50 template<>
     51 IntOperand*
     52 UnaryOp<Operator::BITWISE_NOT>::eval(const Module& pModule,
     53                                      const TargetLDBackend& pBackend)
     54 {
     55   IntOperand* res = result();
     56   res->setValue(~ m_pOperand->value());
     57   return res;
     58 }
     59 
     60 template<>
     61 IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module& pModule,
     62                                               const TargetLDBackend& pBackend)
     63 {
     64   // TODO
     65   assert(0);
     66   return result();
     67 }
     68 
     69 template<>
     70 IntOperand* UnaryOp<Operator::ADDR>::eval(const Module& pModule,
     71                                           const TargetLDBackend& pBackend)
     72 {
     73   IntOperand* res = result();
     74   const LDSection* sect = NULL;
     75   switch (m_pOperand->type()) {
     76   case Operand::SECTION:
     77     sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
     78     break;
     79   case Operand::SECTION_DESC:
     80     sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
     81     break;
     82   default:
     83     assert(0);
     84     break;
     85   }
     86   assert(sect != NULL);
     87   res->setValue(sect->addr());
     88   return res;
     89 }
     90 
     91 template<>
     92 IntOperand* UnaryOp<Operator::ALIGNOF>::eval(const Module& pModule,
     93                                              const TargetLDBackend& pBackend)
     94 {
     95   IntOperand* res = result();
     96   const LDSection* sect = NULL;
     97   switch (m_pOperand->type()) {
     98   case Operand::SECTION:
     99     sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
    100     break;
    101   case Operand::SECTION_DESC:
    102     sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
    103     break;
    104   default:
    105     assert(0);
    106     break;
    107   }
    108   assert(sect != NULL);
    109   res->setValue(sect->align());
    110   return res;
    111 }
    112 
    113 template<>
    114 IntOperand*
    115 UnaryOp<Operator::DATA_SEGMENT_END>::eval(const Module& pModule,
    116                                           const TargetLDBackend& pBackend)
    117 {
    118   IntOperand* res = result();
    119   res->setValue(m_pOperand->value());
    120   return res;
    121 }
    122 
    123 template<>
    124 IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module& pModule,
    125                                              const TargetLDBackend& pBackend)
    126 {
    127   // TODO
    128   assert(0);
    129   return result();
    130 }
    131 
    132 template<>
    133 IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module& pModule,
    134                                             const TargetLDBackend& pBackend)
    135 {
    136   // TODO
    137   assert(0);
    138   return result();
    139 }
    140 
    141 template<>
    142 IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module& pModule,
    143                                               const TargetLDBackend& pBackend)
    144 {
    145   // TODO
    146   assert(0);
    147   return result();
    148 }
    149 
    150 template<>
    151 IntOperand* UnaryOp<Operator::NEXT>::eval(const Module& pModule,
    152                                           const TargetLDBackend& pBackend)
    153 {
    154   // TODO
    155   assert(0);
    156   return result();
    157 }
    158 
    159 template<>
    160 IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module& pModule,
    161                                             const TargetLDBackend& pBackend)
    162 {
    163   // TODO
    164   assert(0);
    165   return result();
    166 }
    167 
    168 template<>
    169 IntOperand* UnaryOp<Operator::SIZEOF>::eval(const Module& pModule,
    170                                             const TargetLDBackend& pBackend)
    171 {
    172   IntOperand* res = result();
    173   const LDSection* sect = NULL;
    174   switch (m_pOperand->type()) {
    175   case Operand::SECTION:
    176     sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name());
    177     break;
    178   case Operand::SECTION_DESC:
    179     sect = llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection();
    180     break;
    181   default:
    182     assert(0);
    183     break;
    184   }
    185   assert(sect != NULL);
    186   res->setValue(sect->size());
    187   return res;
    188 }
    189