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
20namespace mcld {
21
22//===----------------------------------------------------------------------===//
23// UnaryOp
24//===----------------------------------------------------------------------===//
25template <>
26IntOperand* 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
34template <>
35IntOperand* 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
43template <>
44IntOperand* 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
52template <>
53IntOperand* 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
61template <>
62IntOperand* UnaryOp<Operator::ABSOLUTE>::eval(const Module& pModule,
63                                              const TargetLDBackend& pBackend) {
64  // TODO
65  assert(0);
66  return result();
67}
68
69template <>
70IntOperand* 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
91template <>
92IntOperand* 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
113template <>
114IntOperand* 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
122template <>
123IntOperand* UnaryOp<Operator::DEFINED>::eval(const Module& pModule,
124                                             const TargetLDBackend& pBackend) {
125  // TODO
126  assert(0);
127  return result();
128}
129
130template <>
131IntOperand* UnaryOp<Operator::LENGTH>::eval(const Module& pModule,
132                                            const TargetLDBackend& pBackend) {
133  // TODO
134  assert(0);
135  return result();
136}
137
138template <>
139IntOperand* UnaryOp<Operator::LOADADDR>::eval(const Module& pModule,
140                                              const TargetLDBackend& pBackend) {
141  // TODO
142  assert(0);
143  return result();
144}
145
146template <>
147IntOperand* UnaryOp<Operator::NEXT>::eval(const Module& pModule,
148                                          const TargetLDBackend& pBackend) {
149  // TODO
150  assert(0);
151  return result();
152}
153
154template <>
155IntOperand* UnaryOp<Operator::ORIGIN>::eval(const Module& pModule,
156                                            const TargetLDBackend& pBackend) {
157  // TODO
158  assert(0);
159  return result();
160}
161
162template <>
163IntOperand* 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