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 
11 #include "mcld/ADT/SizeTraits.h"
12 #include "mcld/Script/Operand.h"
13 
14 namespace mcld {
15 
16 //===----------------------------------------------------------------------===//
17 // TernaryOp
18 //===----------------------------------------------------------------------===//
19 template <>
eval(const Module & pModule,const TargetLDBackend & pBackend)20 IntOperand* TernaryOp<Operator::TERNARY_IF>::eval(
21     const Module& pModule,
22     const TargetLDBackend& pBackend) {
23   IntOperand* res = result();
24   if (m_pOperand[0]->value())
25     res->setValue(m_pOperand[1]->value());
26   else
27     res->setValue(m_pOperand[2]->value());
28   return res;
29 }
30 
31 /* DATA_SEGMENT_ALIGN(maxpagesize, commonpagesize) */
32 template <>
eval(const Module & pModule,const TargetLDBackend & pBackend)33 IntOperand* TernaryOp<Operator::DATA_SEGMENT_ALIGN>::eval(
34     const Module& pModule,
35     const TargetLDBackend& pBackend) {
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 }  // namespace mcld
60