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