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