CACAO
Scalar.cpp
Go to the documentation of this file.
1 /* src/vm/jit/loop/Scalar.cpp
2 
3  Copyright (C) 1996-2012
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #include "Scalar.hpp"
26 
27 #include <algorithm>
28 #include <sstream>
29 
31 {
32  if (_instruction == other._instruction)
33  {
34  if (other._constant > _constant)
35  _constant = other._constant;
36  }
37  else
38  {
41  s4 otherLeft = other._constant + other._instruction.lower();
42  s4 otherRight = other._constant + other._instruction.upper();
43 
44  if (right <= otherLeft)
45  {
46  *this = other;
47  }
48  else if (right <= otherRight)
49  {
50  *this = Scalar(otherRight);
51  }
52  else if (left < otherRight)
53  {
54  *this = Scalar(right);
55  }
56  }
57 }
58 
60 {
61  if (_instruction == other._instruction)
62  {
63  if (other._constant < _constant)
64  _constant = other._constant;
65  }
66  else
67  {
70  s4 otherLeft = other._constant + other._instruction.lower();
71  s4 otherRight = other._constant + other._instruction.upper();
72 
73  if (left >= otherRight)
74  {
75  *this = other;
76  }
77  else if (left >= otherLeft)
78  {
79  *this = Scalar(otherLeft);
80  }
81  else if (right > otherLeft)
82  {
83  *this = Scalar(left);
84  }
85  }
86 }
87 
88 bool Scalar::tryAdd(const Scalar& other)
89 {
90  s8 c = static_cast<s8>(_constant) + other._constant;
91 
92  // Does constant overflow?
93  if (c < min() || c > max())
94  return false;
95 
96  if (other._instruction.lower() == 0 && other._instruction.upper() == 0)
97  {
98  // Does (constant + instruction) overflow?
99  if (min() <= c + _instruction.lower() && c + _instruction.upper() <= max())
100  {
101  _constant = static_cast<s4>(c);
102  return true;
103  }
104  }
105  else if (_instruction.lower() == 0 && _instruction.upper() == 0)
106  {
107  // Does (constant + instruction) overflow?
108  if (min() <= c + other._instruction.lower() && c + other._instruction.upper() <= max())
109  {
110  *this = Scalar(static_cast<s4>(c), other._instruction);
111  return true;
112  }
113  }
114 
115  return false;
116 }
117 
118 bool Scalar::trySubtract(const Scalar& other)
119 {
120  s8 c = static_cast<s8>(_constant) - other._constant;
121 
122  // Does constant overflow?
123  if (c < min() || c > max())
124  return false;
125 
126  if (other._instruction.lower() == 0 && other._instruction.upper() == 0)
127  {
128  // Does (constant + instruction) overflow?
129  if (min() <= c + _instruction.lower() && c + _instruction.upper() <= max())
130  {
131  _constant = static_cast<s4>(c);
132  return true;
133  }
134  }
135  else if (_instruction == other._instruction) // (c0 + i) - (c1 + i) == c0 - c1
136  {
137  *this = Scalar(static_cast<s4>(c));
138  return true;
139  }
140 
141  return false;
142 }
143 
144 
145 std::ostream& operator<<(std::ostream& out, const Scalar& scalar)
146 {
147  if (scalar.constant() == Scalar::min())
148  out << "MIN";
149  else if (scalar.constant() == Scalar::max())
150  out << "MAX";
151  else if (scalar.constant() != 0)
152  out << scalar.constant();
153 
154  if (scalar.instruction().lower() != 0 || scalar.instruction().upper() != 0)
155  {
156  if (scalar.constant() != 0)
157  out << '+';
158  out << scalar.instruction();
159  }
160 
161  if (scalar.constant() == 0 && scalar.instruction().lower() == 0 && scalar.instruction().upper() == 0)
162  out << '0';
163 
164  return out;
165 }
166 
167 /*
168  * These are local overrides for various environment variables in Emacs.
169  * Please do not remove this and leave it at the end of the file, where
170  * Emacs will automagically detect them.
171  * ---------------------------------------------------------------------
172  * Local variables:
173  * mode: c++
174  * indent-tabs-mode: t
175  * c-basic-offset: 4
176  * tab-width: 4
177  * End:
178  * vim:noexpandtab:sw=4:ts=4:
179  */
180 
void lowerBoundOfMinimumWith(const Scalar &)
Computes a lower bound of the minimum of this and the specified scalar.
Definition: Scalar.cpp:59
s4 _constant
Definition: Scalar.hpp:42
Scalar()
Creates a scalar which equals zero.
Definition: Scalar.hpp:53
static s4 min()
Definition: Scalar.hpp:47
int64_t s8
Definition: types.hpp:48
Right right
Definition: OStream.cpp:47
An integral value of the form Constant + NumericInstruction.
Definition: Scalar.hpp:40
Left left
Definition: OStream.cpp:46
s4 lower() const
The smallest value this instruction can return.
static s4 max()
Definition: Scalar.hpp:48
int32_t s4
Definition: types.hpp:45
OStream & operator<<(OStream &OS, const std::string &t)
Definition: OStream.hpp:459
void upperBoundOfMaximumWith(const Scalar &)
Computes an upper bound of the maximum of this and the specified scalar.
Definition: Scalar.cpp:30
NumericInstruction instruction() const
Definition: Scalar.hpp:87
bool tryAdd(const Scalar &)
Tries to add a scalar to this scalar.
Definition: Scalar.cpp:88
s4 upper() const
The largest value this instruction can return.
NumericInstruction _instruction
Definition: Scalar.hpp:43
OStream & out()
Definition: OStream.cpp:39
bool trySubtract(const Scalar &)
Tries to subtract a scalar from this scalar.
Definition: Scalar.cpp:118
s4 constant() const
Definition: Scalar.hpp:86