TernaryOp.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- TernaryOp.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/TernaryOp.h>
10#include <mcld/Script/Operand.h>
11#include <mcld/ADT/SizeTraits.h>
12
13using namespace mcld;
14//===----------------------------------------------------------------------===//
15// TernaryOp
16//===----------------------------------------------------------------------===//
17template<>
18IntOperand*
19TernaryOp<Operator::TERNARY_IF>::eval(const Module& pModule,
20                                      const TargetLDBackend& pBackend)
21{
22  IntOperand* res = result();
23  if (m_pOperand[0]->value())
24    res->setValue(m_pOperand[1]->value());
25  else
26    res->setValue(m_pOperand[2]->value());
27  return res;
28}
29
30/* DATA_SEGMENT_ALIGN(maxpagesize, commonpagesize) */
31template<>
32IntOperand*
33TernaryOp<Operator::DATA_SEGMENT_ALIGN>::eval(const Module& pModule,
34                                              const TargetLDBackend& pBackend)
35{
36  /* This is equivalent to either
37       (ALIGN(maxpagesize) + (. & (maxpagesize - 1)))
38     or
39       (ALIGN(maxpagesize) + (. & (maxpagesize - commonpagesize)))
40   */
41  IntOperand* res = result();
42  uint64_t dot = m_pOperand[0]->value();
43  uint64_t maxPageSize = m_pOperand[1]->value();
44  uint64_t commonPageSize = m_pOperand[2]->value();
45  uint64_t form1 = 0, form2 = 0;
46
47  alignAddress(dot, maxPageSize);
48
49  form1 = dot + (dot & (maxPageSize - 1));
50  form2 = dot + (dot & (maxPageSize - commonPageSize));
51
52  if (form1 <= form2)
53    res->setValue(form1);
54  else
55    res->setValue(form2);
56  return res;
57}
58
59