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