UnaryOp.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
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
17using namespace mcld;
18//===----------------------------------------------------------------------===//
19// UnaryOp
20//===----------------------------------------------------------------------===//
21template<>
22IntOperand* 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
30template<>
31IntOperand*
32UnaryOp<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
40template<>
41IntOperand*
42UnaryOp<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
50template<>
51IntOperand*
52UnaryOp<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
60template<>
61IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module& pModule,
62                                              const TargetLDBackend& pBackend)
63{
64  // TODO
65  assert(0);
66  return result();
67}
68
69template<>
70IntOperand* 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
91template<>
92IntOperand* 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
113template<>
114IntOperand*
115UnaryOp<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
123template<>
124IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module& pModule,
125                                             const TargetLDBackend& pBackend)
126{
127  // TODO
128  assert(0);
129  return result();
130}
131
132template<>
133IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module& pModule,
134                                            const TargetLDBackend& pBackend)
135{
136  // TODO
137  assert(0);
138  return result();
139}
140
141template<>
142IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module& pModule,
143                                              const TargetLDBackend& pBackend)
144{
145  // TODO
146  assert(0);
147  return result();
148}
149
150template<>
151IntOperand* UnaryOp<Operator::NEXT>::eval(const Module& pModule,
152                                          const TargetLDBackend& pBackend)
153{
154  // TODO
155  assert(0);
156  return result();
157}
158
159template<>
160IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module& pModule,
161                                            const TargetLDBackend& pBackend)
162{
163  // TODO
164  assert(0);
165  return result();
166}
167
168template<>
169IntOperand* 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