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 11 #include "mcld/LD/LDSection.h" 12 #include "mcld/Object/SectionMap.h" 13 #include "mcld/Script/Operand.h" 14 #include "mcld/Module.h" 15 16 #include <llvm/Support/Casting.h> 17 18 #include <cassert> 19 20 namespace mcld { 21 22 //===----------------------------------------------------------------------===// 23 // UnaryOp 24 //===----------------------------------------------------------------------===// 25 template <> 26 IntOperand* UnaryOp<Operator::UNARY_PLUS>::eval( 27 const Module& pModule, 28 const TargetLDBackend& pBackend) { 29 IntOperand* res = result(); 30 res->setValue(+m_pOperand->value()); 31 return res; 32 } 33 34 template <> 35 IntOperand* UnaryOp<Operator::UNARY_MINUS>::eval( 36 const Module& pModule, 37 const TargetLDBackend& pBackend) { 38 IntOperand* res = result(); 39 res->setValue(-m_pOperand->value()); 40 return res; 41 } 42 43 template <> 44 IntOperand* UnaryOp<Operator::LOGICAL_NOT>::eval( 45 const Module& pModule, 46 const TargetLDBackend& pBackend) { 47 IntOperand* res = result(); 48 res->setValue(!m_pOperand->value()); 49 return res; 50 } 51 52 template <> 53 IntOperand* UnaryOp<Operator::BITWISE_NOT>::eval( 54 const Module& pModule, 55 const TargetLDBackend& pBackend) { 56 IntOperand* res = result(); 57 res->setValue(~m_pOperand->value()); 58 return res; 59 } 60 61 template <> 62 IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module& pModule, 63 const TargetLDBackend& pBackend) { 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 IntOperand* res = result(); 73 const LDSection* sect = NULL; 74 switch (m_pOperand->type()) { 75 case Operand::SECTION: 76 sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name()); 77 break; 78 case Operand::SECTION_DESC: 79 sect = 80 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 IntOperand* res = result(); 95 const LDSection* sect = NULL; 96 switch (m_pOperand->type()) { 97 case Operand::SECTION: 98 sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name()); 99 break; 100 case Operand::SECTION_DESC: 101 sect = 102 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* UnaryOp<Operator::DATA_SEGMENT_END>::eval( 115 const Module& pModule, 116 const TargetLDBackend& pBackend) { 117 IntOperand* res = result(); 118 res->setValue(m_pOperand->value()); 119 return res; 120 } 121 122 template <> 123 IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module& pModule, 124 const TargetLDBackend& pBackend) { 125 // TODO 126 assert(0); 127 return result(); 128 } 129 130 template <> 131 IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module& pModule, 132 const TargetLDBackend& pBackend) { 133 // TODO 134 assert(0); 135 return result(); 136 } 137 138 template <> 139 IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module& pModule, 140 const TargetLDBackend& pBackend) { 141 // TODO 142 assert(0); 143 return result(); 144 } 145 146 template <> 147 IntOperand* UnaryOp<Operator::NEXT>::eval(const Module& pModule, 148 const TargetLDBackend& pBackend) { 149 // TODO 150 assert(0); 151 return result(); 152 } 153 154 template <> 155 IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module& pModule, 156 const TargetLDBackend& pBackend) { 157 // TODO 158 assert(0); 159 return result(); 160 } 161 162 template <> 163 IntOperand* UnaryOp<Operator::SIZEOF>::eval(const Module& pModule, 164 const TargetLDBackend& pBackend) { 165 IntOperand* res = result(); 166 const LDSection* sect = NULL; 167 switch (m_pOperand->type()) { 168 case Operand::SECTION: 169 sect = pModule.getSection(llvm::cast<SectOperand>(m_pOperand)->name()); 170 break; 171 case Operand::SECTION_DESC: 172 sect = 173 llvm::cast<SectDescOperand>(m_pOperand)->outputDesc()->getSection(); 174 break; 175 default: 176 assert(0); 177 break; 178 } 179 assert(sect != NULL); 180 res->setValue(sect->size()); 181 return res; 182 } 183 184 } // namespace mcld 185