1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- BinaryOp.cpp -------------------------------------------------------===//
2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//                     The MCLinker Project
4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source
6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details.
7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/BinaryOp.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/SizeTraits.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/TargetLDBackend.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h>
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert>
20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines
23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// BinaryOp
25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::MUL>::eval(const Module& pModule,
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() * m_pOperand[1]->value());
31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::DIV>::eval(const Module& pModule,
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() / m_pOperand[1]->value());
39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::MOD>::eval(const Module& pModule,
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() % m_pOperand[1]->value());
47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::ADD>::eval(const Module& pModule,
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() + m_pOperand[1]->value());
55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::SUB>::eval(const Module& pModule,
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() - m_pOperand[1]->value());
63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::LSHIFT>::eval(const Module& pModule,
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             const TargetLDBackend& pBackend) {
69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() << m_pOperand[1]->value());
71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::RSHIFT>::eval(const Module& pModule,
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             const TargetLDBackend& pBackend) {
77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() >> m_pOperand[1]->value());
79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::LT>::eval(const Module& pModule,
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() < m_pOperand[1]->value());
87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::LE>::eval(const Module& pModule,
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
93f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() <= m_pOperand[1]->value());
95f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::GT>::eval(const Module& pModule,
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() > m_pOperand[1]->value());
103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::GE>::eval(const Module& pModule,
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
109f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() >= m_pOperand[1]->value());
111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
11437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
115f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::EQ>::eval(const Module& pModule,
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
118f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() == m_pOperand[1]->value());
119f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
120f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
121f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::NE>::eval(const Module& pModule,
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         const TargetLDBackend& pBackend) {
125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
126f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() != m_pOperand[1]->value());
127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
128f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
129f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
13137b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::BITWISE_AND>::eval(
13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
134f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() & m_pOperand[1]->value());
136f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
137f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
138f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
14037b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::BITWISE_XOR>::eval(
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
143f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
144f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() ^ m_pOperand[1]->value());
145f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
14937b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::BITWISE_OR>::eval(
15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
152f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
153f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() | m_pOperand[1]->value());
154f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
155f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
15737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
15837b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::LOGICAL_AND>::eval(
15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
161f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
162f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() && m_pOperand[1]->value());
163f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
164f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
165f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
16737b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::LOGICAL_OR>::eval(
16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
170f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
171f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(m_pOperand[0]->value() || m_pOperand[1]->value());
172f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
173f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
174f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
176f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::ALIGN>::eval(const Module& pModule,
17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                            const TargetLDBackend& pBackend) {
178f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  uint64_t value = m_pOperand[0]->value();
180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  uint64_t align = m_pOperand[1]->value();
181f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  alignAddress(value, align);
182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(value);
183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
185f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
18637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
18737b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::DATA_SEGMENT_RELRO_END>::eval(
18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
190f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /* FIXME: Currently we handle relro in a different way, and now the result
191f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines     of this expression won't affect DATA_SEGMENT_ALIGN. */
192f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  uint64_t value = m_pOperand[0]->value() + m_pOperand[1]->value();
194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  alignAddress(value, pBackend.commonPageSize());
195f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  res->setValue(value);
196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
198f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
19937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
200f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::MAX>::eval(const Module& pModule,
20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
202f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
203f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_pOperand[0]->value() >= m_pOperand[1]->value())
204f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(m_pOperand[0]->value());
205f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else
206f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(m_pOperand[1]->value());
207f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
208f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
209f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
21037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
211f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesIntOperand* BinaryOp<Operator::MIN>::eval(const Module& pModule,
21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                          const TargetLDBackend& pBackend) {
213f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
214f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_pOperand[0]->value() <= m_pOperand[1]->value())
215f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(m_pOperand[0]->value());
216f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else
217f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(m_pOperand[1]->value());
218f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
219f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
220f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
221f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines/* SEGMENT_START(segment, default) */
22237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
22337b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntOperand* BinaryOp<Operator::SEGMENT_START>::eval(
22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Module& pModule,
22537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const TargetLDBackend& pBackend) {
226f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  IntOperand* res = result();
227f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  /* Currently we look up segment address from -T command line options. */
228f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  SectOperand* sect = llvm::cast<SectOperand>(m_pOperand[0]);
22937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const LinkerScript::AddressMap& addressMap = pModule.getScript().addressMap();
230f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  LinkerScript::AddressMap::const_iterator addr;
231f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (sect->name().compare("text-segment") == 0)
232f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    addr = addressMap.find(".text");
233f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else if (sect->name().compare("data-segment") == 0)
234f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    addr = addressMap.find(".data");
235f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else if (sect->name().compare("bss-segment") == 0)
236f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    addr = addressMap.find(".bss");
237f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else
238f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    addr = addressMap.find(sect->name());
239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
240f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (addr != addressMap.end())
241f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(addr.getEntry()->value());
242f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  else {
243f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    assert(m_pOperand[1]->type() == Operand::INTEGER);
244f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    res->setValue(m_pOperand[1]->value());
245f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
246f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return res;
247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
250