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