vmreg.hpp 7.9 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35 36 37 38
#ifndef SHARE_VM_CODE_VMREG_HPP
#define SHARE_VM_CODE_VMREG_HPP

#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef TARGET_ARCH_x86
# include "register_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "register_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "register_zero.hpp"
#endif
39 40 41 42 43 44
#ifdef TARGET_ARCH_arm
# include "register_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "register_ppc.hpp"
#endif
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#ifdef COMPILER2
#include "opto/adlcVMDeps.hpp"
#include "utilities/ostream.hpp"
#ifdef TARGET_ARCH_MODEL_x86_32
# include "adfiles/adGlobals_x86_32.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_x86_64
# include "adfiles/adGlobals_x86_64.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_sparc
# include "adfiles/adGlobals_sparc.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_zero
# include "adfiles/adGlobals_zero.hpp"
#endif
60 61 62 63 64 65
#ifdef TARGET_ARCH_MODEL_arm
# include "adfiles/adGlobals_arm.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_ppc
# include "adfiles/adGlobals_ppc.hpp"
#endif
66 67
#endif

D
duke 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//------------------------------VMReg------------------------------------------
// The VM uses 'unwarped' stack slots; the compiler uses 'warped' stack slots.
// Register numbers below VMRegImpl::stack0 are the same for both.  Register
// numbers above stack0 are either warped (in the compiler) or unwarped
// (in the VM).  Unwarped numbers represent stack indices, offsets from
// the current stack pointer.  Warped numbers are required during compilation
// when we do not yet know how big the frame will be.

class VMRegImpl;
typedef VMRegImpl* VMReg;

class VMRegImpl {
// friend class OopMap;
friend class VMStructs;
friend class OptoReg;
// friend class Location;
private:
  enum {
    BAD = -1
  };



  static VMReg stack0;
  // Names for registers
  static const char *regName[];
  static const int register_count;


public:

  static VMReg  as_VMReg(int val, bool bad_ok = false) { assert(val > BAD || bad_ok, "invalid"); return (VMReg) (intptr_t) val; }

  const char*  name() {
    if (is_reg()) {
      return regName[value()];
    } else if (!is_valid()) {
      return "BAD";
    } else {
      // shouldn't really be called with stack
      return "STACKED REG";
    }
  }
  static VMReg Bad() { return (VMReg) (intptr_t) BAD; }
112 113 114
  bool is_valid() const { return ((intptr_t) this) != BAD; }
  bool is_stack() const { return (intptr_t) this >= (intptr_t) stack0; }
  bool is_reg()   const { return is_valid() && !is_stack(); }
D
duke 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

  // A concrete register is a value that returns true for is_reg() and is
  // also a register you could use in the assembler. On machines with
  // 64bit registers only one half of the VMReg (and OptoReg) is considered
  // concrete.
  bool is_concrete();

  // VMRegs are 4 bytes wide on all platforms
  static const int stack_slot_size;
  static const int slots_per_word;


  // This really ought to check that the register is "real" in the sense that
  // we don't try and get the VMReg number of a physical register that doesn't
  // have an expressible part. That would be pd specific code
  VMReg next() {
    assert((is_reg() && value() < stack0->value() - 1) || is_stack(), "must be");
    return (VMReg)(intptr_t)(value() + 1);
  }
  VMReg prev() {
    assert((is_stack() && value() > stack0->value()) || (is_reg() && value() != 0), "must be");
    return (VMReg)(intptr_t)(value() - 1);
  }


  intptr_t value() const         {return (intptr_t) this; }

142
  void print_on(outputStream* st) const;
143
  void print() const { print_on(tty); }
D
duke 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169

  // bias a stack slot.
  // Typically used to adjust a virtual frame slots by amounts that are offset by
  // amounts that are part of the native abi. The VMReg must be a stack slot
  // and the result must be also.

  VMReg bias(int offset) {
    assert(is_stack(), "must be");
    // VMReg res = VMRegImpl::as_VMReg(value() + offset);
    VMReg res = stack2reg(reg2stack() + offset);
    assert(res->is_stack(), "must be");
    return res;
  }

  // Convert register numbers to stack slots and vice versa
  static VMReg stack2reg( int idx ) {
    return (VMReg) (intptr_t) (stack0->value() + idx);
  }

  uintptr_t reg2stack() {
    assert( is_stack(), "Not a stack-based register" );
    return value() - stack0->value();
  }

  static void set_regName();

170 171 172 173 174 175 176 177 178
#ifdef TARGET_ARCH_x86
# include "vmreg_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "vmreg_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "vmreg_zero.hpp"
#endif
179 180 181 182 183 184
#ifdef TARGET_ARCH_arm
# include "vmreg_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "vmreg_ppc.hpp"
#endif
185

D
duke 已提交
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

};

//---------------------------VMRegPair-------------------------------------------
// Pairs of 32-bit registers for arguments.
// SharedRuntime::java_calling_convention will overwrite the structs with
// the calling convention's registers.  VMRegImpl::Bad is returned for any
// unused 32-bit register.  This happens for the unused high half of Int
// arguments, or for 32-bit pointers or for longs in the 32-bit sparc build
// (which are passed to natives in low 32-bits of e.g. O0/O1 and the high
// 32-bits of O0/O1 are set to VMRegImpl::Bad).  Longs in one register & doubles
// always return a high and a low register, as do 64-bit pointers.
//
class VMRegPair {
private:
  VMReg _second;
  VMReg _first;
public:
  void set_bad (                   ) { _second=VMRegImpl::Bad(); _first=VMRegImpl::Bad(); }
  void set1    (         VMReg v  ) { _second=VMRegImpl::Bad(); _first=v; }
  void set2    (         VMReg v  ) { _second=v->next();  _first=v; }
  void set_pair( VMReg second, VMReg first    ) { _second= second;    _first= first; }
  void set_ptr ( VMReg ptr ) {
#ifdef _LP64
    _second = ptr->next();
#else
    _second = VMRegImpl::Bad();
#endif
    _first = ptr;
  }
  // Return true if single register, even if the pair is really just adjacent stack slots
217
  bool is_single_reg() const {
D
duke 已提交
218 219 220 221
    return (_first->is_valid()) && (_first->value() + 1 == _second->value());
  }

  // Return true if single stack based "register" where the slot alignment matches input alignment
222
  bool is_adjacent_on_stack(int alignment) const {
D
duke 已提交
223 224 225 226
    return (_first->is_stack() && (_first->value() + 1 == _second->value()) && ((_first->value() & (alignment-1)) == 0));
  }

  // Return true if single stack based "register" where the slot alignment matches input alignment
227
  bool is_adjacent_aligned_on_stack(int alignment) const {
D
duke 已提交
228 229 230 231
    return (_first->is_stack() && (_first->value() + 1 == _second->value()) && ((_first->value() & (alignment-1)) == 0));
  }

  // Return true if single register but adjacent stack slots do not count
232
  bool is_single_phys_reg() const {
D
duke 已提交
233 234 235 236 237 238 239 240 241
    return (_first->is_reg() && (_first->value() + 1 == _second->value()));
  }

  VMReg second() const { return _second; }
  VMReg first()  const { return _first; }
  VMRegPair(VMReg s, VMReg f) {  _second = s; _first = f; }
  VMRegPair(VMReg f) { _second = VMRegImpl::Bad(); _first = f; }
  VMRegPair() { _second = VMRegImpl::Bad(); _first = VMRegImpl::Bad(); }
};
242 243

#endif // SHARE_VM_CODE_VMREG_HPP