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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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 <>
eval(const Module & pModule,const TargetLDBackend & pBackend)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