optoreg.hpp revision 6760:22b98ab2a69f
1/* 2 * Copyright (c) 2006, 2014, 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#ifndef SHARE_VM_OPTO_OPTOREG_HPP 26#define SHARE_VM_OPTO_OPTOREG_HPP 27 28// AdGlobals contains c2 specific register handling code as specified 29// in the .ad files. 30#ifdef TARGET_ARCH_MODEL_x86_32 31# include "adfiles/adGlobals_x86_32.hpp" 32#endif 33#ifdef TARGET_ARCH_MODEL_x86_64 34# include "adfiles/adGlobals_x86_64.hpp" 35#endif 36#ifdef TARGET_ARCH_MODEL_sparc 37# include "adfiles/adGlobals_sparc.hpp" 38#endif 39#ifdef TARGET_ARCH_MODEL_zero 40# include "adfiles/adGlobals_zero.hpp" 41#endif 42#ifdef TARGET_ARCH_MODEL_arm 43# include "adfiles/adGlobals_arm.hpp" 44#endif 45#ifdef TARGET_ARCH_MODEL_ppc_32 46# include "adfiles/adGlobals_ppc_32.hpp" 47#endif 48#ifdef TARGET_ARCH_MODEL_ppc_64 49# include "adfiles/adGlobals_ppc_64.hpp" 50#endif 51 52//------------------------------OptoReg---------------------------------------- 53// We eventually need Registers for the Real World. Registers are essentially 54// non-SSA names. A Register is represented as a number. Non-regular values 55// (e.g., Control, Memory, I/O) use the Special register. The actual machine 56// registers (as described in the ADL file for a machine) start at zero. 57// Stack-slots (spill locations) start at the nest Chunk past the last machine 58// register. 59// 60// Note that stack spill-slots are treated as a very large register set. 61// They have all the correct properties for a Register: not aliased (unique 62// named). There is some simple mapping from a stack-slot register number 63// to the actual location on the stack; this mapping depends on the calling 64// conventions and is described in the ADL. 65// 66// Note that Name is not enum. C++ standard defines that the range of enum 67// is the range of smallest bit-field that can represent all enumerators 68// declared in the enum. The result of assigning a value to enum is undefined 69// if the value is outside the enumeration's valid range. OptoReg::Name is 70// typedef'ed as int, because it needs to be able to represent spill-slots. 71// 72class OptoReg VALUE_OBJ_CLASS_SPEC { 73 74 friend class C2Compiler; 75 public: 76 typedef int Name; 77 enum { 78 // Chunk 0 79 Physical = AdlcVMDeps::Physical, // Start of physical regs 80 // A few oddballs at the edge of the world 81 Special = -2, // All special (not allocated) values 82 Bad = -1 // Not a register 83 }; 84 85 private: 86 87 static const VMReg opto2vm[REG_COUNT]; 88 static Name vm2opto[ConcreteRegisterImpl::number_of_registers]; 89 90 public: 91 92 // Stack pointer register 93 static OptoReg::Name c_frame_pointer; 94 95 96 97 // Increment a register number. As in: 98 // "for ( OptoReg::Name i; i=Control; i = add(i,1) ) ..." 99 static Name add( Name x, int y ) { return Name(x+y); } 100 101 // (We would like to have an operator+ for RegName, but it is not 102 // a class, so this would be illegal in C++.) 103 104 static void dump(int, outputStream *st = tty); 105 106 // Get the stack slot number of an OptoReg::Name 107 static unsigned int reg2stack( OptoReg::Name r) { 108 assert( r >= stack0(), " must be"); 109 return r - stack0(); 110 } 111 112 // convert a stack slot number into an OptoReg::Name 113 static OptoReg::Name stack2reg( int idx) { 114 return Name(stack0() + idx); 115 } 116 117 static bool is_stack(Name n) { 118 return n >= stack0(); 119 } 120 121 static bool is_valid(Name n) { 122 return (n != Bad); 123 } 124 125 static bool is_reg(Name n) { 126 return is_valid(n) && !is_stack(n); 127 } 128 129 static VMReg as_VMReg(OptoReg::Name n) { 130 if (is_reg(n)) { 131 // Must use table, it'd be nice if Bad was indexable... 132 return opto2vm[n]; 133 } else { 134 assert(!is_stack(n), "must un warp"); 135 return VMRegImpl::Bad(); 136 } 137 } 138 139 // Can un-warp a stack slot or convert a register or Bad 140 static VMReg as_VMReg(OptoReg::Name n, int frame_size, int arg_count) { 141 if (is_reg(n)) { 142 // Must use table, it'd be nice if Bad was indexable... 143 return opto2vm[n]; 144 } else if (is_stack(n)) { 145 int stack_slot = reg2stack(n); 146 if (stack_slot < arg_count) { 147 return VMRegImpl::stack2reg(stack_slot + frame_size); 148 } 149 return VMRegImpl::stack2reg(stack_slot - arg_count); 150 // return return VMRegImpl::stack2reg(reg2stack(OptoReg::add(n, -arg_count))); 151 } else { 152 return VMRegImpl::Bad(); 153 } 154 } 155 156 static OptoReg::Name as_OptoReg(VMReg r) { 157 if (r->is_stack()) { 158 assert(false, "must warp"); 159 return stack2reg(r->reg2stack()); 160 } else if (r->is_valid()) { 161 // Must use table, it'd be nice if Bad was indexable... 162 return vm2opto[r->value()]; 163 } else { 164 return Bad; 165 } 166 } 167 168 static OptoReg::Name stack0() { 169 return VMRegImpl::stack0->value(); 170 } 171 172 static const char* regname(OptoReg::Name n) { 173 return as_VMReg(n)->name(); 174 } 175 176}; 177 178//---------------------------OptoRegPair------------------------------------------- 179// Pairs of 32-bit registers for the allocator. 180// This is a very similar class to VMRegPair. C2 only interfaces with VMRegPair 181// via the calling convention code which is shared between the compilers. 182// Since C2 uses OptoRegs for register allocation it is more efficient to use 183// VMRegPair internally for nodes that can contain a pair of OptoRegs rather 184// than use VMRegPair and continually be converting back and forth. So normally 185// C2 will take in a VMRegPair from the calling convention code and immediately 186// convert them to an OptoRegPair and stay in the OptoReg world. The only over 187// conversion between OptoRegs and VMRegs is for debug info and oopMaps. This 188// is not a high bandwidth spot and so it is not an issue. 189// Note that onde other consequence of staying in the OptoReg world with OptoRegPairs 190// is that there are "physical" OptoRegs that are not representable in the VMReg 191// world, notably flags. [ But by design there is "space" in the VMReg world 192// for such registers they just may not be concrete ]. So if we were to use VMRegPair 193// then the VMReg world would have to have a representation for these registers 194// so that a OptoReg->VMReg->OptoReg would reproduce ther original OptoReg. As it 195// stands if you convert a flag (condition code) to a VMReg you will get VMRegImpl::Bad 196// and converting that will return OptoReg::Bad losing the identity of the OptoReg. 197 198class OptoRegPair { 199 friend class VMStructs; 200private: 201 short _second; 202 short _first; 203public: 204 void set_bad ( ) { _second = OptoReg::Bad; _first = OptoReg::Bad; } 205 void set1 ( OptoReg::Name n ) { _second = OptoReg::Bad; _first = n; } 206 void set2 ( OptoReg::Name n ) { _second = n + 1; _first = n; } 207 void set_pair( OptoReg::Name second, OptoReg::Name first ) { _second= second; _first= first; } 208 void set_ptr ( OptoReg::Name ptr ) { 209#ifdef _LP64 210 _second = ptr+1; 211#else 212 _second = OptoReg::Bad; 213#endif 214 _first = ptr; 215 } 216 217 OptoReg::Name second() const { return _second; } 218 OptoReg::Name first() const { return _first; } 219 OptoRegPair(OptoReg::Name second, OptoReg::Name first) { _second = second; _first = first; } 220 OptoRegPair(OptoReg::Name f) { _second = OptoReg::Bad; _first = f; } 221 OptoRegPair() { _second = OptoReg::Bad; _first = OptoReg::Bad; } 222}; 223 224#endif // SHARE_VM_OPTO_OPTOREG_HPP 225