c1_FpuStackSim_x86.cpp revision 1472:c18cbe5936b8
1/*
2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25# include "incls/_precompiled.incl"
26# include "incls/_c1_FpuStackSim_x86.cpp.incl"
27
28//--------------------------------------------------------
29//               FpuStackSim
30//--------------------------------------------------------
31
32// This class maps the FPU registers to their stack locations; it computes
33// the offsets between individual registers and simulates the FPU stack.
34
35const int EMPTY = -1;
36
37int FpuStackSim::regs_at(int i) const {
38  assert(i >= 0 && i < FrameMap::nof_fpu_regs, "out of bounds");
39  return _regs[i];
40}
41
42void FpuStackSim::set_regs_at(int i, int val) {
43  assert(i >= 0 && i < FrameMap::nof_fpu_regs, "out of bounds");
44  _regs[i] = val;
45}
46
47void FpuStackSim::dec_stack_size() {
48  _stack_size--;
49  assert(_stack_size >= 0, "FPU stack underflow");
50}
51
52void FpuStackSim::inc_stack_size() {
53  _stack_size++;
54  assert(_stack_size <= FrameMap::nof_fpu_regs, "FPU stack overflow");
55}
56
57FpuStackSim::FpuStackSim(Compilation* compilation)
58 : _compilation(compilation)
59{
60  _stack_size = 0;
61  for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
62    set_regs_at(i, EMPTY);
63  }
64}
65
66
67void FpuStackSim::pop() {
68  if (TraceFPUStack) { tty->print("FPU-pop "); print(); tty->cr(); }
69  set_regs_at(tos_index(), EMPTY);
70  dec_stack_size();
71}
72
73void FpuStackSim::pop(int rnr) {
74  if (TraceFPUStack) { tty->print("FPU-pop %d", rnr); print(); tty->cr(); }
75  assert(regs_at(tos_index()) == rnr, "rnr is not on TOS");
76  set_regs_at(tos_index(), EMPTY);
77  dec_stack_size();
78}
79
80
81void FpuStackSim::push(int rnr) {
82  if (TraceFPUStack) { tty->print("FPU-push %d", rnr); print(); tty->cr(); }
83  assert(regs_at(stack_size()) == EMPTY, "should be empty");
84  set_regs_at(stack_size(), rnr);
85  inc_stack_size();
86}
87
88
89void FpuStackSim::swap(int offset) {
90  if (TraceFPUStack) { tty->print("FPU-swap %d", offset); print(); tty->cr(); }
91  int t = regs_at(tos_index() - offset);
92  set_regs_at(tos_index() - offset, regs_at(tos_index()));
93  set_regs_at(tos_index(), t);
94}
95
96
97int FpuStackSim::offset_from_tos(int rnr) const {
98  for (int i = tos_index(); i >= 0; i--) {
99    if (regs_at(i) == rnr) {
100      return tos_index() - i;
101    }
102  }
103  assert(false, "FpuStackSim: register not found");
104  BAILOUT_("FpuStackSim: register not found", 0);
105}
106
107
108int FpuStackSim::get_slot(int tos_offset) const {
109  return regs_at(tos_index() - tos_offset);
110}
111
112void FpuStackSim::set_slot(int tos_offset, int rnr) {
113  set_regs_at(tos_index() - tos_offset, rnr);
114}
115
116void FpuStackSim::rename(int old_rnr, int new_rnr) {
117  if (TraceFPUStack) { tty->print("FPU-rename %d %d", old_rnr, new_rnr); print(); tty->cr(); }
118  if (old_rnr == new_rnr)
119    return;
120  bool found = false;
121  for (int i = 0; i < stack_size(); i++) {
122    assert(regs_at(i) != new_rnr, "should not see old occurrences of new_rnr on the stack");
123    if (regs_at(i) == old_rnr) {
124      set_regs_at(i, new_rnr);
125      found = true;
126    }
127  }
128  assert(found, "should have found at least one instance of old_rnr");
129}
130
131
132bool FpuStackSim::contains(int rnr) {
133  for (int i = 0; i < stack_size(); i++) {
134    if (regs_at(i) == rnr) {
135      return true;
136    }
137  }
138  return false;
139}
140
141bool FpuStackSim::is_empty() {
142#ifdef ASSERT
143  if (stack_size() == 0) {
144    for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
145      assert(regs_at(i) == EMPTY, "must be empty");
146    }
147  }
148#endif
149  return stack_size() == 0;
150}
151
152
153bool FpuStackSim::slot_is_empty(int tos_offset) {
154  return (regs_at(tos_index() - tos_offset) == EMPTY);
155}
156
157
158void FpuStackSim::clear() {
159  if (TraceFPUStack) { tty->print("FPU-clear"); print(); tty->cr(); }
160  for (int i = tos_index(); i >= 0; i--) {
161    set_regs_at(i, EMPTY);
162  }
163  _stack_size = 0;
164}
165
166
167intArray* FpuStackSim::write_state() {
168  intArray* res = new intArray(1 + FrameMap::nof_fpu_regs);
169  (*res)[0] = stack_size();
170  for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
171    (*res)[1 + i] = regs_at(i);
172  }
173  return res;
174}
175
176
177void FpuStackSim::read_state(intArray* fpu_stack_state) {
178  _stack_size = (*fpu_stack_state)[0];
179  for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
180    set_regs_at(i, (*fpu_stack_state)[1 + i]);
181  }
182}
183
184
185#ifndef PRODUCT
186void FpuStackSim::print() {
187  tty->print(" N=%d[", stack_size());\
188  for (int i = 0; i < stack_size(); i++) {
189    int reg = regs_at(i);
190    if (reg != EMPTY) {
191      tty->print("%d", reg);
192    } else {
193      tty->print("_");
194    }
195  };
196  tty->print(" ]");
197}
198#endif
199