src/cpu/mips/vm/assembler_mips.hpp

changeset 1
2d8a650513c2
child 14
92759d406e78
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/cpu/mips/vm/assembler_mips.hpp	Fri Apr 29 00:06:10 2016 +0800
     1.3 @@ -0,0 +1,1951 @@
     1.4 +/*
     1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
     1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 + *
     1.9 + * This code is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License version 2 only, as
    1.11 + * published by the Free Software Foundation.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + *
    1.27 + */
    1.28 +
    1.29 +#ifndef CPU_MIPS_VM_ASSEMBLER_MIPS_HPP
    1.30 +#define CPU_MIPS_VM_ASSEMBLER_MIPS_HPP
    1.31 +
    1.32 +#include "asm/register.hpp"
    1.33 +
    1.34 +class BiasedLockingCounters;
    1.35 +
    1.36 +
    1.37 +// Note: A register location is represented via a Register, not
    1.38 +//       via an address for efficiency & simplicity reasons.
    1.39 +
    1.40 +class ArrayAddress;
    1.41 +
    1.42 +class Address VALUE_OBJ_CLASS_SPEC {
    1.43 +  
    1.44 +public:
    1.45 +  enum ScaleFactor {
    1.46 +    no_scale = -1,
    1.47 +    times_1  =  0,
    1.48 +    times_2  =  1,
    1.49 +    times_4  =  2,
    1.50 +    times_8  =  3,
    1.51 +    times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
    1.52 +  };
    1.53 +
    1.54 +  static ScaleFactor times(int size) {
    1.55 +    assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
    1.56 +    if (size == 8)  return times_8;
    1.57 +    if (size == 4)  return times_4;
    1.58 +    if (size == 2)  return times_2;
    1.59 +    return times_1;
    1.60 +  }
    1.61 +
    1.62 + private:
    1.63 +  Register         _base;
    1.64 +  Register         _index;
    1.65 +  ScaleFactor      _scale;
    1.66 +  int              _disp;
    1.67 +  RelocationHolder _rspec;
    1.68 +
    1.69 +  // Easily misused constructors make them private
    1.70 +  // %%% can we make these go away?
    1.71 +  //FIXME aoqi
    1.72 +  //NOT_LP64(Address(address loc, RelocationHolder spec);)
    1.73 +  Address(address loc, RelocationHolder spec);
    1.74 +  Address(int disp, address loc, relocInfo::relocType rtype);
    1.75 +  Address(int disp, address loc, RelocationHolder spec);
    1.76 +
    1.77 + public:
    1.78 +
    1.79 + int disp() { return _disp; }
    1.80 +  // creation
    1.81 +  Address()
    1.82 +    : _base(noreg),
    1.83 +      _index(noreg),
    1.84 +      _scale(no_scale),
    1.85 +      _disp(0) {
    1.86 +  }
    1.87 +
    1.88 +  // No default displacement otherwise Register can be implicitly
    1.89 +  // converted to 0(Register) which is quite a different animal.
    1.90 +
    1.91 +  Address(Register base, int disp)
    1.92 +    : _base(base),
    1.93 +      _index(noreg),
    1.94 +      _scale(no_scale),
    1.95 +      _disp(disp) {
    1.96 +  }
    1.97 +
    1.98 +  Address(Register base) 
    1.99 +   : _base(base),
   1.100 +     _index(noreg),
   1.101 +     _scale(no_scale),
   1.102 +     _disp(0) {
   1.103 +  }
   1.104 +
   1.105 +  Address(Register base, Register index, ScaleFactor scale, int disp = 0)
   1.106 +    : _base (base),
   1.107 +      _index(index),
   1.108 +      _scale(scale),
   1.109 +      _disp (disp) {
   1.110 +    assert(!index->is_valid() == (scale == Address::no_scale),
   1.111 +           "inconsistent address");
   1.112 +  }
   1.113 +
   1.114 +  // The following two overloads are used in connection with the
   1.115 +  // ByteSize type (see sizes.hpp).  They simplify the use of
   1.116 +  // ByteSize'd arguments in assembly code. Note that their equivalent
   1.117 +  // for the optimized build are the member functions with int disp
   1.118 +  // argument since ByteSize is mapped to an int type in that case.
   1.119 +  //
   1.120 +  // Note: DO NOT introduce similar overloaded functions for WordSize
   1.121 +  // arguments as in the optimized mode, both ByteSize and WordSize
   1.122 +  // are mapped to the same type and thus the compiler cannot make a
   1.123 +  // distinction anymore (=> compiler errors).
   1.124 +
   1.125 +#ifdef ASSERT
   1.126 +  Address(Register base, ByteSize disp)
   1.127 +    : _base(base),
   1.128 +      _index(noreg),
   1.129 +      _scale(no_scale),
   1.130 +      _disp(in_bytes(disp)) {
   1.131 +  }
   1.132 +
   1.133 +  Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
   1.134 +    : _base(base),
   1.135 +      _index(index),
   1.136 +      _scale(scale),
   1.137 +      _disp(in_bytes(disp)) {
   1.138 +    assert(!index->is_valid() == (scale == Address::no_scale),
   1.139 +           "inconsistent address");
   1.140 +  }
   1.141 +#endif // ASSERT
   1.142 +
   1.143 +  // accessors
   1.144 +  bool        uses(Register reg) const { return _base == reg || _index == reg; }
   1.145 +  Register    base()             const { return _base;  }
   1.146 +  Register    index()            const { return _index; }
   1.147 +  ScaleFactor scale()            const { return _scale; }
   1.148 +  int         disp()             const { return _disp;  }
   1.149 +
   1.150 +  // Convert the raw encoding form into the form expected by the constructor for
   1.151 +  // Address.  An index of 4 (rsp) corresponds to having no index, so convert
   1.152 +  // that to noreg for the Address constructor.
   1.153 +  //static Address make_raw(int base, int index, int scale, int disp);
   1.154 +
   1.155 +  static Address make_array(ArrayAddress);
   1.156 +
   1.157 +/*
   1.158 + private:
   1.159 +  bool base_needs_rex() const {
   1.160 +    return _base != noreg && _base->encoding() >= 8;
   1.161 +  }
   1.162 +
   1.163 +  bool index_needs_rex() const {
   1.164 +    return _index != noreg &&_index->encoding() >= 8;
   1.165 +  }
   1.166 +
   1.167 +  relocInfo::relocType reloc() const { return _rspec.type(); }
   1.168 +*/
   1.169 +  friend class Assembler;
   1.170 +  friend class MacroAssembler;
   1.171 +  friend class LIR_Assembler; // base/index/scale/disp
   1.172 +};
   1.173 +
   1.174 +
   1.175 +// Calling convention
   1.176 +class Argument VALUE_OBJ_CLASS_SPEC {
   1.177 + private:
   1.178 +	int _number;
   1.179 + public:
   1.180 +	enum {
   1.181 +#ifdef _LP64
   1.182 +	  n_register_parameters = 8,   // 8 integer registers used to pass parameters
   1.183 +	  n_float_register_parameters = 8   // 4 float registers used to pass parameters
   1.184 +#else
   1.185 +	    n_register_parameters = 4,   // 4 integer registers used to pass parameters
   1.186 +	  n_float_register_parameters = 4   // 4 float registers used to pass parameters
   1.187 +#endif
   1.188 +	};
   1.189 +	
   1.190 +	Argument(int number):_number(number){ }
   1.191 +	Argument successor() {return Argument(number() + 1);}
   1.192 +
   1.193 +	int number()const {return _number;}
   1.194 +	bool is_Register()const {return _number < n_register_parameters;}
   1.195 +	bool is_FloatRegister()const {return _number < n_float_register_parameters;}
   1.196 +
   1.197 +	Register as_Register()const {
   1.198 +		assert(is_Register(), "must be a register argument");
   1.199 +		return ::as_Register(A0->encoding() + _number);
   1.200 +	}
   1.201 +	FloatRegister  as_FloatRegister()const {
   1.202 +		assert(is_FloatRegister(), "must be a float register argument");
   1.203 +		return ::as_FloatRegister(F12->encoding() + _number);
   1.204 +	}
   1.205 +	
   1.206 +	Address as_caller_address()const {return Address(SP, (number() LP64_ONLY( -n_register_parameters)) * wordSize);}
   1.207 +};
   1.208 +
   1.209 +
   1.210 +
   1.211 +//
   1.212 +// AddressLiteral has been split out from Address because operands of this type
   1.213 +// need to be treated specially on 32bit vs. 64bit platforms. By splitting it out
   1.214 +// the few instructions that need to deal with address literals are unique and the
   1.215 +// MacroAssembler does not have to implement every instruction in the Assembler
   1.216 +// in order to search for address literals that may need special handling depending
   1.217 +// on the instruction and the platform. As small step on the way to merging i486/amd64
   1.218 +// directories.
   1.219 +//
   1.220 +class AddressLiteral VALUE_OBJ_CLASS_SPEC {
   1.221 +  friend class ArrayAddress;
   1.222 +  RelocationHolder _rspec;
   1.223 +  // Typically we use AddressLiterals we want to use their rval
   1.224 +  // However in some situations we want the lval (effect address) of the item.
   1.225 +  // We provide a special factory for making those lvals.
   1.226 +  bool _is_lval;
   1.227 +
   1.228 +  // If the target is far we'll need to load the ea of this to
   1.229 +  // a register to reach it. Otherwise if near we can do rip
   1.230 +  // relative addressing.
   1.231 +
   1.232 +  address          _target;
   1.233 +
   1.234 + protected:
   1.235 +  // creation
   1.236 +  AddressLiteral()
   1.237 +    : _is_lval(false),
   1.238 +      _target(NULL)
   1.239 +  {}
   1.240 +
   1.241 +  public:
   1.242 +
   1.243 +  AddressLiteral(address target, relocInfo::relocType rtype);
   1.244 +
   1.245 +  AddressLiteral(address target, RelocationHolder const& rspec)
   1.246 +    : _rspec(rspec),
   1.247 +      _is_lval(false),
   1.248 +      _target(target)
   1.249 +  {}
   1.250 +#ifdef _LP64
   1.251 +   // 32-bit complains about a multiple declaration for int*.
   1.252 +   AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none)
   1.253 +     : _target((address) addr),
   1.254 +       _rspec(rspec_from_rtype(rtype, (address) addr)) {}
   1.255 +#endif
   1.256 +
   1.257 +
   1.258 +  AddressLiteral addr() {
   1.259 +    AddressLiteral ret = *this;
   1.260 +    ret._is_lval = true;
   1.261 +    return ret;
   1.262 +  }
   1.263 +
   1.264 +
   1.265 + private:
   1.266 +
   1.267 +  address target() { return _target; }
   1.268 +  bool is_lval() { return _is_lval; }
   1.269 +
   1.270 +  relocInfo::relocType reloc() const { return _rspec.type(); }
   1.271 +  const RelocationHolder& rspec() const { return _rspec; }
   1.272 +
   1.273 +  friend class Assembler;
   1.274 +  friend class MacroAssembler;
   1.275 +  friend class Address;
   1.276 +  friend class LIR_Assembler;
   1.277 + RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) {
   1.278 +   switch (rtype) {
   1.279 +   case relocInfo::external_word_type:
   1.280 +     return external_word_Relocation::spec(addr);
   1.281 +   case relocInfo::internal_word_type:
   1.282 +    return internal_word_Relocation::spec(addr);
   1.283 +   case relocInfo::opt_virtual_call_type:
   1.284 +    return opt_virtual_call_Relocation::spec();
   1.285 +   case relocInfo::static_call_type:
   1.286 +     return static_call_Relocation::spec();
   1.287 +   case relocInfo::runtime_call_type:
   1.288 +     return runtime_call_Relocation::spec();
   1.289 +   case relocInfo::poll_type:
   1.290 +   case relocInfo::poll_return_type:
   1.291 +     return Relocation::spec_simple(rtype);
   1.292 +   case relocInfo::none:
   1.293 +   case relocInfo::oop_type:
   1.294 +     // Oops are a special case. Normally they would be their own section
   1.295 +     // but in cases like icBuffer they are literals in the code stream that
   1.296 +     // we don't have a section for. We use none so that we get a literal address
   1.297 +     // which is always patchable.
   1.298 +     return RelocationHolder();
   1.299 +   default: 
   1.300 +     ShouldNotReachHere();
   1.301 +     return RelocationHolder();
   1.302 + }
   1.303 +}
   1.304 +
   1.305 +};
   1.306 +
   1.307 +// Convience classes
   1.308 +class RuntimeAddress: public AddressLiteral {
   1.309 +
   1.310 +  public:
   1.311 +
   1.312 +  RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {}
   1.313 +
   1.314 +};
   1.315 +
   1.316 +class OopAddress: public AddressLiteral {
   1.317 +
   1.318 +  public:
   1.319 +
   1.320 +  OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){}
   1.321 +
   1.322 +};
   1.323 +
   1.324 +class ExternalAddress: public AddressLiteral {
   1.325 +
   1.326 +  public:
   1.327 +
   1.328 +  ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){}
   1.329 +
   1.330 +};
   1.331 +
   1.332 +class InternalAddress: public AddressLiteral {
   1.333 +
   1.334 +  public:
   1.335 +
   1.336 +  InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {}
   1.337 +
   1.338 +};
   1.339 +
   1.340 +// x86 can do array addressing as a single operation since disp can be an absolute
   1.341 +// address amd64 can't. We create a class that expresses the concept but does extra
   1.342 +// magic on amd64 to get the final result
   1.343 +
   1.344 +class ArrayAddress VALUE_OBJ_CLASS_SPEC {
   1.345 +  private:
   1.346 +
   1.347 +  AddressLiteral _base;
   1.348 +  Address        _index;
   1.349 +
   1.350 +  public:
   1.351 +
   1.352 +  ArrayAddress() {};
   1.353 +  ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {};
   1.354 +  AddressLiteral base() { return _base; }
   1.355 +  Address index() { return _index; }
   1.356 +
   1.357 +};
   1.358 +
   1.359 +const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize);
   1.360 +
   1.361 +// The MIPS LOONGSON Assembler: Pure assembler doing NO optimizations on the instruction
   1.362 +// level ; i.e., what you write is what you get. The Assembler is generating code into 
   1.363 +// a CodeBuffer.
   1.364 +
   1.365 +class Assembler : public AbstractAssembler  {
   1.366 +  friend class AbstractAssembler; // for the non-virtual hack
   1.367 +  friend class LIR_Assembler; // as_Address()
   1.368 +  friend class StubGenerator;
   1.369 +
   1.370 +  public:
   1.371 +  enum ops {
   1.372 +		special_op  = 0x00,
   1.373 +		regimm_op   = 0x01,
   1.374 +  	j_op        = 0x02,
   1.375 +  	jal_op      = 0x03,
   1.376 +	  beq_op      = 0x04,
   1.377 +	  bne_op      = 0x05,
   1.378 +	  blez_op     = 0x06,
   1.379 +	  bgtz_op     = 0x07,
   1.380 +	  addi_op     = 0x08,
   1.381 +	  addiu_op    = 0x09,
   1.382 +	  slti_op     = 0x0a,
   1.383 +	  sltiu_op    = 0x0b,
   1.384 +	  andi_op     = 0x0c,
   1.385 +	  ori_op      = 0x0d,
   1.386 +	  xori_op     = 0x0e,
   1.387 +	  lui_op      = 0x0f,
   1.388 +	  cop0_op     = 0x10,
   1.389 +	  cop1_op     = 0x11,
   1.390 +	  cop2_op     = 0x12,
   1.391 +	  cop3_op     = 0x13,
   1.392 +	  beql_op     = 0x14,
   1.393 +	  bnel_op     = 0x15,
   1.394 +	  blezl_op    = 0x16,
   1.395 +	  bgtzl_op    = 0x17,
   1.396 +	  daddi_op    = 0x18,
   1.397 +	  daddiu_op   = 0x19,
   1.398 +	  ldl_op      = 0x1a,
   1.399 +	  ldr_op      = 0x1b,
   1.400 +	  lb_op       = 0x20,
   1.401 +	  lh_op       = 0x21,
   1.402 +	  lwl_op      = 0x22,
   1.403 +	  lw_op       = 0x23,
   1.404 +	  lbu_op      = 0x24,
   1.405 +	  lhu_op      = 0x25,
   1.406 +    lwr_op      = 0x26,
   1.407 +    lwu_op      = 0x27,
   1.408 +    sb_op       = 0x28,
   1.409 +    sh_op       = 0x29,
   1.410 +    swl_op      = 0x2a,
   1.411 +	  sw_op       = 0x2b,
   1.412 +	  sdl_op      = 0x2c,
   1.413 +	  sdr_op      = 0x2d,
   1.414 +	  swr_op      = 0x2e,
   1.415 +	  cache_op    = 0x2f,
   1.416 +	  ll_op       = 0x30,
   1.417 +	  lwc1_op     = 0x31,
   1.418 +	  lld_op      = 0x34,
   1.419 +	  ldc1_op     = 0x35,
   1.420 +	  ld_op       = 0x37,
   1.421 +	  sc_op       = 0x38,
   1.422 +	  swc1_op     = 0x39,
   1.423 +	  scd_op      = 0x3c,
   1.424 +	  sdc1_op     = 0x3d,
   1.425 +	  sd_op       = 0x3f
   1.426 +  };
   1.427 +	
   1.428 +	static	const char *ops_name[];
   1.429 +
   1.430 +	//special family, the opcode is in low 6 bits. 
   1.431 +	enum special_ops {
   1.432 +		sll_op			= 0x00,
   1.433 +		srl_op			= 0x02,
   1.434 +		sra_op			= 0x03,
   1.435 +		sllv_op			= 0x04,
   1.436 +		srlv_op			= 0x06,
   1.437 +		srav_op 		= 0x07,
   1.438 +		jr_op				= 0x08,
   1.439 +		jalr_op			= 0x09,
   1.440 +		syscall_op	= 0x0c,
   1.441 +		break_op		= 0x0d,
   1.442 +		sync_op			= 0x0f,
   1.443 +		mfhi_op			= 0x10,
   1.444 +		mthi_op			= 0x11,
   1.445 +		mflo_op			= 0x12,
   1.446 +		mtlo_op			= 0x13,
   1.447 +		dsllv_op		= 0x14,
   1.448 +		dsrlv_op		= 0x16,
   1.449 +		dsrav_op		= 0x17,
   1.450 +		mult_op			= 0x18,
   1.451 +		multu_op 		= 0x19,
   1.452 +		div_op			= 0x1a,
   1.453 +		divu_op			= 0x1b,
   1.454 +		dmult_op		= 0x1c,
   1.455 +		dmultu_op		= 0x1d,
   1.456 +		ddiv_op			= 0x1e,
   1.457 +		ddivu_op		= 0x1f,
   1.458 +		add_op			= 0x20,
   1.459 +		addu_op			= 0x21,
   1.460 +		sub_op			= 0x22,
   1.461 +		subu_op			= 0x23,
   1.462 +		and_op			= 0x24,
   1.463 +		or_op				= 0x25,
   1.464 +		xor_op			= 0x26,
   1.465 +		nor_op			= 0x27,
   1.466 +		slt_op			= 0x2a,
   1.467 +		sltu_op			= 0x2b,
   1.468 +		dadd_op			= 0x2c,
   1.469 +		daddu_op		= 0x2d,
   1.470 +		dsub_op			= 0x2e,
   1.471 +		dsubu_op		= 0x2f,
   1.472 +		tge_op			= 0x30,
   1.473 +		tgeu_op			= 0x31,
   1.474 +		tlt_op			= 0x32,
   1.475 +		tltu_op			= 0x33,
   1.476 +		teq_op			= 0x34,
   1.477 +		tne_op			= 0x36,
   1.478 +		dsll_op			= 0x38,
   1.479 +		dsrl_op			= 0x3a,
   1.480 +		dsra_op			= 0x3b,
   1.481 +		dsll32_op		= 0x3c,
   1.482 +		dsrl32_op		= 0x3e,
   1.483 +		dsra32_op		= 0x3f
   1.484 +	};
   1.485 +	
   1.486 +	static	const char* special_name[]; 
   1.487 +	
   1.488 +	//regimm family, the opcode is in rt[16...20], 5 bits
   1.489 +	enum regimm_ops {
   1.490 +		bltz_op			= 0x00,
   1.491 +		bgez_op			= 0x01,
   1.492 +		bltzl_op		= 0x02,
   1.493 +		bgezl_op		= 0x03,
   1.494 +		tgei_op			= 0x08,
   1.495 +		tgeiu_op		= 0x09,
   1.496 +		tlti_op			= 0x0a,
   1.497 +		tltiu_op		= 0x0b,
   1.498 +		teqi_op			= 0x0c,
   1.499 +		tnei_op			= 0x0e,
   1.500 +		bltzal_op		= 0x10,
   1.501 +		bgezal_op		= 0x11,
   1.502 +		bltzall_op	= 0x12,
   1.503 +		bgezall_op	= 0x13,
   1.504 +	};
   1.505 +
   1.506 +	static	const char* regimm_name[]; 
   1.507 +
   1.508 +	//copx family,the op in rs, 5 bits
   1.509 +	enum cop_ops {
   1.510 +		mf_op				= 0x00,
   1.511 +		dmf_op			= 0x01,
   1.512 +		cf_op				= 0x02,
   1.513 +		mt_op				= 0x04,
   1.514 +		dmt_op			= 0x05,
   1.515 +		ct_op				= 0x06,
   1.516 +		bc_op				= 0x08,
   1.517 +		single_fmt	= 0x10,
   1.518 +		double_fmt	= 0x11,
   1.519 +		word_fmt		= 0x14,
   1.520 +		long_fmt		= 0x15
   1.521 +	};
   1.522 +
   1.523 +	enum bc_ops {
   1.524 +		bcf_op			= 0x00,
   1.525 +		bct_op			= 0x01,
   1.526 +		bcfl_op			= 0x02,
   1.527 +		bctl_op			= 0x03,
   1.528 +	};
   1.529 +
   1.530 +	enum c_conds {
   1.531 +		f_cond			= 0x30,
   1.532 +		un_cond			= 0x31,
   1.533 +		eq_cond			= 0x32,
   1.534 +		ueq_cond		= 0x33,
   1.535 +		olt_cond		= 0x34,
   1.536 +		ult_cond		= 0x35,
   1.537 +		ole_cond		= 0x36,
   1.538 +		ule_cond		= 0x37,
   1.539 +		sf_cond			= 0x38,
   1.540 +		ngle_cond		= 0x39,
   1.541 +		seq_cond		= 0x3a,
   1.542 +		ngl_cond		= 0x3b,
   1.543 +		lt_cond			= 0x3c,
   1.544 +		nge_cond		= 0x3d,
   1.545 +		le_cond			= 0x3e,
   1.546 +		ngt_cond		= 0x3f
   1.547 +	};
   1.548 +
   1.549 +	//low 6 bits of cp1 instruction
   1.550 +	enum float_ops {
   1.551 +		fadd_op			= 0x00,
   1.552 +		fsub_op			= 0x01,
   1.553 +		fmul_op			= 0x02,
   1.554 +		fdiv_op			= 0x03,
   1.555 +		fsqrt_op		= 0x04,
   1.556 +		fabs_op			= 0x05,
   1.557 +		fmov_op			= 0x06,
   1.558 +		fneg_op			= 0x07,
   1.559 +		froundl_op	= 0x08,
   1.560 +		ftruncl_op	= 0x09,
   1.561 +		fceill_op		= 0x0a,
   1.562 +		ffloorl_op	= 0x0b,
   1.563 +		froundw_op 	= 0x0c,
   1.564 +		ftruncw_op	= 0x0d,
   1.565 +		fceilw_op 	= 0x0e,
   1.566 +		ffloorw_op	= 0x0f,
   1.567 +		fcvts_op		= 0x20,
   1.568 +		fcvtd_op		= 0x21,
   1.569 +		fcvtw_op		= 0x24,
   1.570 +		fcvtl_op		= 0x25,
   1.571 +		fpll_op		=0x2c,
   1.572 +		fplu_op		=0x2d,
   1.573 +		fpul_op		=0x2e,
   1.574 +		fpuu_op		=0x2f,
   1.575 +
   1.576 +	};
   1.577 +	
   1.578 +  /* 2013.10.16 Jin: merge from OpenJDK 8 */
   1.579 +  enum WhichOperand {
   1.580 +    // input to locate_operand, and format code for relocations
   1.581 +    imm_operand  = 0,            // embedded 32-bit|64-bit immediate operand
   1.582 +    disp32_operand = 1,          // embedded 32-bit displacement or address
   1.583 +    call32_operand = 2,          // embedded 32-bit self-relative displacement
   1.584 +#ifndef _LP64
   1.585 +    _WhichOperand_limit = 3
   1.586 +#else
   1.587 +     narrow_oop_operand = 3,     // embedded 32-bit immediate narrow oop
   1.588 +    _WhichOperand_limit = 4
   1.589 +#endif
   1.590 +  };
   1.591 +
   1.592 +       /* Godson3 extension */
   1.593 +       enum godson3_ops {
   1.594 +               gsldx_op        = (0x36 << 26) | 0x3,
   1.595 +               gslwx_op        = (0x36 << 26) | 0x2,
   1.596 +       };
   1.597 +
   1.598 +	static const char* float_name[]; 
   1.599 +
   1.600 +	static int opcode(int insn) { return (insn>>26)&0x3f; }
   1.601 +	static int rs(int insn) { return (insn>>21)&0x1f; }
   1.602 +	static int rt(int insn) { return (insn>>16)&0x1f; }
   1.603 +	static int rd(int insn) { return (insn>>11)&0x1f; }
   1.604 +	static int sa(int insn) { return (insn>>6)&0x1f; }
   1.605 +	static int special(int insn) { return insn&0x3f; }
   1.606 +	static int imm_off(int insn) { return (short)low16(insn); }
   1.607 +
   1.608 +	static int low  (int x, int l) { return bitfield(x, 0, l); }
   1.609 +	static int low16(int x)        { return low(x, 16); }
   1.610 +	static int low26(int x)        { return low(x, 26); }
   1.611 +	
   1.612 +protected:
   1.613 +	//help methods for instruction ejection
   1.614 +
   1.615 +	//I-Type (Immediate)
   1.616 +	// 31				 26 25        21 20      16 15    													0
   1.617 +	//|   opcode   |			rs		|    rt    |						immediat						 |
   1.618 +	//| 					 |						|					 |																 |
   1.619 +	//			6							5					  5					 					16
   1.620 +	static int insn_ORRI(int op, int rs, int rt, int imm) { return (op<<26) | (rs<<21) | (rt<<16) | low16(imm); } 
   1.621 +
   1.622 +	//R-Type (Register)
   1.623 +	// 31				  26 25       21 20      16 15      11 10				 6 5			  0
   1.624 +	//|   special   |			rs		|    rt    |	  rd	  | 		0		  |	 opcode  |
   1.625 +	//| 0 0 0 0 0 0 |						|					 |					| 0 0 0 0 0 | 				 |
   1.626 +	//			6							5					  5					 5					5						6
   1.627 +	static int insn_RRRO(int rs, int rt, int rd,   int op) { return (rs<<21) | (rt<<16) | (rd<<11)  | op; }
   1.628 +	static int insn_RRSO(int rt, int rd, int sa,   int op) { return (rt<<16) | (rd<<11) | (sa<<6)   | op; }
   1.629 +	static int insn_RRCO(int rs, int rt, int code, int op) { return (rs<<21) | (rt<<16) | (code<<6) | op; }
   1.630 +	
   1.631 +	static int insn_COP0(int op, int rt, int rd) { return (cop0_op<<26) | (op<<21) | (rt<<16) | (rd<<11); }
   1.632 +	static int insn_COP1(int op, int rt, int fs) { return (cop1_op<<26) | (op<<21) | (rt<<16) | (fs<<11); }
   1.633 +
   1.634 +	static int insn_F3RO(int fmt, int ft, int fs, int fd, int func) { 
   1.635 +		return (cop1_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
   1.636 +	}
   1.637 +	
   1.638 +
   1.639 +	//static int low  (int x, int l) { return bitfield(x, 0, l); }
   1.640 +	//static int low16(int x)        { return low(x, 16); }
   1.641 +	//static int low26(int x)        { return low(x, 26); }
   1.642 +	
   1.643 +	static int high  (int x, int l) { return bitfield(x, 32-l, l); }
   1.644 +	static int high16(int x)        { return high(x, 16); }
   1.645 +	static int high6 (int x)        { return high(x, 6); }
   1.646 +
   1.647 +	//get the offset field of jump/branch instruction
   1.648 +	int offset(address entry) { 
   1.649 +		assert(is_simm16((entry - pc() - 4) / 4), "change this code");
   1.650 +		if (!is_simm16((entry - pc() - 4) / 4)) {
   1.651 +			tty->print_cr("!!! is_simm16: %x", (entry - pc() - 4) / 4);
   1.652 +		}
   1.653 +		return (entry - pc() - 4) / 4; 
   1.654 +	}
   1.655 +	
   1.656 +
   1.657 +public:
   1.658 +	using AbstractAssembler::offset;
   1.659 +
   1.660 +	//sign expand with the sign bit is h
   1.661 +	static int expand(int x, int h) { return -(x & (1<<h)) | x;	}
   1.662 +
   1.663 +	// mips lui/addiu is both sign extended, so if you wan't to use off32/imm32, you have to use the follow three
   1.664 +	// by yjl 6/22/2005
   1.665 +	static int split_low(int x) {
   1.666 +		return (x & 0xffff);
   1.667 +	}
   1.668 +
   1.669 +	static int split_high(int x) {
   1.670 +		return ( (x >> 16) + ((x & 0x8000) != 0) ) & 0xffff;
   1.671 +	}
   1.672 +
   1.673 +	static int merge(int low, int high) {
   1.674 +		return expand(low, 15) + (high<<16);
   1.675 +	}
   1.676 +
   1.677 +#ifdef _LP64
   1.678 +	static intptr_t merge(intptr_t x0, intptr_t x16, intptr_t x32, intptr_t x48) {
   1.679 +	  return (x48 << 48) | (x32 << 32) | (x16 << 16) | x0;
   1.680 +	  /*
   1.681 +	     return ((intptr_t)(long_at(0) & 0xffff) << 48) 
   1.682 +	     + expand((intptr_t)(long_at(4) & 0xffff) << 32, 47)
   1.683 +	     + expand((intptr_t)(long_at(12) & 0xffff) << 16, 31)
   1.684 +	     + expand((intptr_t)(long_at(20) & 0xffff), 15);
   1.685 +	     return expand(low, 15) + (high<<16);
   1.686 +	   */
   1.687 +	}
   1.688 +#endif
   1.689 +
   1.690 +	// modified by spark 2005/08/18
   1.691 +	static bool is_simm  (int x, int nbits) { return -( 1 << nbits-1 )  <= x   &&   x  <  ( 1 << nbits-1 ); }
   1.692 +	static bool is_simm16(int x)            { return is_simm(x, 16); }
   1.693 +	
   1.694 +	// test if imm can be coded in a instruction with 16-bit imm/off
   1.695 +	// by yjl 6/23/2005
   1.696 +	/*static bool fit_in_insn(int imm) {
   1.697 +		return imm == (short)imm;
   1.698 +	}*/
   1.699 +
   1.700 +	static bool fit_in_jal(int offset) {
   1.701 +		return is_simm(offset, 26);
   1.702 +	}
   1.703 +	
   1.704 +	
   1.705 +	// test if entry can be filled in the jl/jal, 
   1.706 +	// must be used just before you emit jl/jal 
   1.707 +	// by yjl 6/27/2005 
   1.708 +	bool fit_int_jal(address entry) {
   1.709 +		return fit_in_jal(offset(entry));
   1.710 +	}
   1.711 +	
   1.712 +	bool fit_int_branch(address entry) {
   1.713 +		return is_simm16(offset(entry));
   1.714 +	}
   1.715 +
   1.716 +protected:
   1.717 +#ifdef ASSERT
   1.718 +	  #define CHECK_DELAY
   1.719 +#endif
   1.720 +#ifdef CHECK_DELAY
   1.721 +	enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state;
   1.722 +#endif
   1.723 +		
   1.724 +public:
   1.725 +	void assert_not_delayed() {
   1.726 +#ifdef CHECK_DELAY
   1.727 +		assert_not_delayed("next instruction should not be a delay slot");
   1.728 +#endif
   1.729 +	}
   1.730 +
   1.731 +	void assert_not_delayed(const char* msg) {
   1.732 +#ifdef CHECK_DELAY
   1.733 +		//guarantee( delay_state == no_delay, msg );
   1.734 +		//aoqi_test
   1.735 +		if(delay_state != no_delay){
   1.736 +		tty->print_cr("%s:%d, pc: %lx", __func__, __LINE__, pc());
   1.737 +		}
   1.738 +		assert(delay_state == no_delay, msg);
   1.739 +#endif		
   1.740 +	}
   1.741 +
   1.742 +protected:
   1.743 +	// Delay slot helpers
   1.744 +	// cti is called when emitting control-transfer instruction,
   1.745 +	// BEFORE doing the emitting.
   1.746 +	// Only effective when assertion-checking is enabled.
   1.747 +	
   1.748 +	// called when emitting cti with a delay slot, AFTER emitting
   1.749 +	void has_delay_slot() {
   1.750 +#ifdef CHECK_DELAY
   1.751 +		assert_not_delayed("just checking");
   1.752 +		delay_state = at_delay_slot;
   1.753 +#endif
   1.754 +	}
   1.755 +
   1.756 +public:
   1.757 +	Assembler* delayed() {
   1.758 +#ifdef CHECK_DELAY
   1.759 +		guarantee( delay_state == at_delay_slot, "delayed instructition is not in delay slot");
   1.760 +		delay_state = filling_delay_slot;
   1.761 +#endif
   1.762 +		return this;						
   1.763 +	}
   1.764 +
   1.765 +	void flush() {
   1.766 +#ifdef CHECK_DELAY
   1.767 +		guarantee( delay_state == no_delay, "ending code with a delay slot");
   1.768 +#endif
   1.769 +		AbstractAssembler::flush();
   1.770 +	}
   1.771 +	
   1.772 +	inline void emit_long(int);  // shadows AbstractAssembler::emit_long
   1.773 +	inline void emit_data(int x) { emit_long(x); }
   1.774 +	inline void emit_data(int, RelocationHolder const&);
   1.775 +	inline void emit_data(int, relocInfo::relocType rtype);		
   1.776 +	inline void check_delay();
   1.777 + 
   1.778 +
   1.779 +  // Generic instructions
   1.780 +  // Does 32bit or 64bit as needed for the platform. In some sense these
   1.781 +  // belong in macro assembler but there is no need for both varieties to exist
   1.782 +
   1.783 +#ifndef _LP64
   1.784 +	void add(Register rd, Register rs, Register rt)  { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
   1.785 +	void addi(Register rt, Register rs, int imm)     { emit_long(insn_ORRI(addi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.786 +	void addiu(Register rt, Register rs, int imm)    { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.787 +	void addu(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
   1.788 +#else
   1.789 +	void add(Register rd, Register rs, Register rt)  { dadd	  (rd, rs, rt); }
   1.790 +	void add32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
   1.791 +	void addu32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
   1.792 +	void addiu32(Register rt, Register rs, int imm)    { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.793 +	void addi(Register rt, Register rs, int imm)     { daddi  (rt, rs, imm);}
   1.794 +	void addiu(Register rt, Register rs, int imm)    { daddiu (rt, rs, imm);}
   1.795 +	void addu(Register rd, Register rs, Register rt) { daddu  (rd, rs, rt);	}
   1.796 +#endif
   1.797 +
   1.798 +	void andr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), and_op)); }
   1.799 +	void andi(Register rt, Register rs, int imm)     { emit_long(insn_ORRI(andi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.800 +	
   1.801 +	void beq    (Register rs, Register rt, int off) { emit_long(insn_ORRI(beq_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
   1.802 +	void beql   (Register rs, Register rt, int off) { emit_long(insn_ORRI(beql_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
   1.803 +	void bgez   (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgez_op, off)); has_delay_slot(); }
   1.804 +	void bgezal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezal_op, off)); has_delay_slot(); }
   1.805 +	void bgezall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezall_op, off)); has_delay_slot(); }
   1.806 +	void bgezl  (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezl_op, off)); has_delay_slot(); }
   1.807 +	void bgtz   (Register rs, int off) { emit_long(insn_ORRI(bgtz_op,   (int)rs->encoding(), 0, off)); has_delay_slot(); }
   1.808 +	void bgtzl  (Register rs, int off) { emit_long(insn_ORRI(bgtzl_op,  (int)rs->encoding(), 0, off)); has_delay_slot(); }
   1.809 +	void blez   (Register rs, int off) { emit_long(insn_ORRI(blez_op,   (int)rs->encoding(), 0, off)); has_delay_slot(); }
   1.810 +	void blezl  (Register rs, int off) { emit_long(insn_ORRI(blezl_op,  (int)rs->encoding(), 0, off)); has_delay_slot(); }
   1.811 +	void bltz   (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltz_op, off)); has_delay_slot(); }
   1.812 +	void bltzal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzal_op, off)); has_delay_slot(); }
   1.813 +	void bltzall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzall_op, off)); has_delay_slot(); }
   1.814 +	void bltzl  (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzl_op, off)); has_delay_slot(); }
   1.815 +	void bne    (Register rs, Register rt, int off) { emit_long(insn_ORRI(bne_op,  (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
   1.816 +	void bnel   (Register rs, Register rt, int off) { emit_long(insn_ORRI(bnel_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
   1.817 +	void brk    (int code) { emit_long(break_op | (code<<16)); }
   1.818 +	
   1.819 +	void beq    (Register rs, Register rt, address entry) { beq(rs, rt, offset(entry)); }
   1.820 +	void beql   (Register rs, Register rt, address entry) { beql(rs, rt, offset(entry));}
   1.821 +	void bgez   (Register rs, address entry) { bgez   (rs, offset(entry)); }
   1.822 +	void bgezal (Register rs, address entry) { bgezal (rs, offset(entry)); }
   1.823 +	void bgezall(Register rs, address entry) { bgezall(rs, offset(entry)); }
   1.824 +	void bgezl  (Register rs, address entry) { bgezl  (rs, offset(entry)); }
   1.825 +	void bgtz   (Register rs, address entry) { bgtz   (rs, offset(entry)); }
   1.826 +	void bgtzl  (Register rs, address entry) { bgtzl  (rs, offset(entry)); }
   1.827 +	void blez   (Register rs, address entry) { blez   (rs, offset(entry)); }
   1.828 +	void blezl  (Register rs, address entry) { blezl  (rs, offset(entry)); }
   1.829 +	void bltz   (Register rs, address entry) { bltz   (rs, offset(entry)); }
   1.830 +	void bltzal (Register rs, address entry) { bltzal (rs, offset(entry)); }
   1.831 +	void bltzall(Register rs, address entry) { bltzall(rs, offset(entry)); }
   1.832 +	void bltzl  (Register rs, address entry) { bltzl  (rs, offset(entry)); }
   1.833 +	void bne    (Register rs, Register rt, address entry) { bne(rs, rt, offset(entry)); }
   1.834 +	void bnel   (Register rs, Register rt, address entry) { bnel(rs, rt, offset(entry)); }
   1.835 +	
   1.836 +	void beq    (Register rs, Register rt, Label& L) { beq(rs, rt, target(L)); }
   1.837 +	void beql   (Register rs, Register rt, Label& L) { beql(rs, rt, target(L)); }
   1.838 +	void bgez   (Register rs, Label& L){ bgez   (rs, target(L)); }
   1.839 +	void bgezal (Register rs, Label& L){ bgezal (rs, target(L)); }
   1.840 +	void bgezall(Register rs, Label& L){ bgezall(rs, target(L)); }
   1.841 +	void bgezl  (Register rs, Label& L){ bgezl  (rs, target(L)); }
   1.842 +	void bgtz   (Register rs, Label& L){ bgtz   (rs, target(L)); }
   1.843 +	void bgtzl  (Register rs, Label& L){ bgtzl  (rs, target(L)); }
   1.844 +	void blez   (Register rs, Label& L){ blez   (rs, target(L)); }
   1.845 +	void blezl  (Register rs, Label& L){ blezl  (rs, target(L)); }
   1.846 +	void bltz   (Register rs, Label& L){ bltz   (rs, target(L)); }
   1.847 +	void bltzal (Register rs, Label& L){ bltzal (rs, target(L)); }
   1.848 +	void bltzall(Register rs, Label& L){ bltzall(rs, target(L)); }
   1.849 +	void bltzl  (Register rs, Label& L){ bltzl  (rs, target(L)); }
   1.850 +	void bne    (Register rs, Register rt, Label& L){ bne(rs, rt, target(L)); }
   1.851 +	void bnel   (Register rs, Register rt, Label& L){ bnel(rs, rt, target(L)); }
   1.852 +
   1.853 +	void dadd  (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dadd_op)); }
   1.854 +	void daddi (Register rt, Register rs, int imm)     { emit_long(insn_ORRI(daddi_op,  (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.855 +	void daddiu(Register rt, Register rs, int imm)     { emit_long(insn_ORRI(daddiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.856 +	void daddu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), daddu_op)); }
   1.857 +	void ddiv  (Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddiv_op));	}
   1.858 +	void ddivu (Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddivu_op)); }
   1.859 +// Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
   1.860 +//#ifndef _LP64
   1.861 +#if 1
   1.862 +	void div   (Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, div_op)); }
   1.863 +	void divu  (Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, divu_op)); }
   1.864 +#else
   1.865 +	void div   (Register rs, Register rt)              { ddiv (rs, rt);}
   1.866 +	void divu  (Register rs, Register rt)              { ddivu(rs, rt);}
   1.867 +#endif
   1.868 +	void dmfc0 (Register rt, FloatRegister rd)         { emit_long(insn_COP0(dmf_op, (int)rt->encoding(), (int)rd->encoding())); }
   1.869 +	void dmtc0 (Register rt, FloatRegister rd)         { emit_long(insn_COP0(dmt_op, (int)rt->encoding(), (int)rd->encoding())); }
   1.870 +	void dmult (Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmult_op)); }
   1.871 +	void dmultu(Register rs, Register rt)              { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmultu_op)); }
   1.872 +	void dsll  (Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll_op)); }
   1.873 +	void dsllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsllv_op)); }	
   1.874 +	void dsll32(Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll32_op)); }
   1.875 +	void dsra  (Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra_op)); }
   1.876 +	void dsrav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrav_op)); }	
   1.877 +	void dsra32(Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra32_op)); }
   1.878 +	void dsrl  (Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl_op)); }
   1.879 +	void dsrlv (Register rd, Register rt, Register rs)  { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrlv_op)); }	
   1.880 +	void dsrl32(Register rd, Register rt , int sa)     { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl32_op)); }
   1.881 +	void dsub  (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsub_op)); }
   1.882 +	void dsubu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsubu_op)); }
   1.883 +
   1.884 +	void b(int off)       { beq(R0, R0, off); }
   1.885 +	void b(address entry) { b(offset(entry)); }
   1.886 +	void b(Label& L)      { b(target(L)); }
   1.887 +	
   1.888 +	void j(address entry);
   1.889 +	void jal(address entry);
   1.890 +	
   1.891 +	void jalr(Register rd, Register rs) { emit_long( ((int)rs->encoding()<<21) | ((int)rd->encoding()<<11) | jalr_op); has_delay_slot(); }
   1.892 +	void jalr(Register rs)              { jalr(RA, rs); }
   1.893 +	void jalr()                         { jalr(T9); }
   1.894 +
   1.895 +	void jr(Register rs) { emit_long(((int)rs->encoding()<<21) | jr_op); has_delay_slot(); }
   1.896 +
   1.897 +	void lb (Register rt, Register base, int off) { emit_long(insn_ORRI(lb_op,  (int)base->encoding(), (int)rt->encoding(), off)); }
   1.898 +	void lbu(Register rt, Register base, int off) { emit_long(insn_ORRI(lbu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.899 +	void ld (Register rt, Register base, int off) { emit_long(insn_ORRI(ld_op,  (int)base->encoding(), (int)rt->encoding(), off)); }
   1.900 +	void ldl(Register rt, Register base, int off) { emit_long(insn_ORRI(ldl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.901 +	void ldr(Register rt, Register base, int off) { emit_long(insn_ORRI(ldr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.902 +	void lh (Register rt, Register base, int off) { emit_long(insn_ORRI(lh_op,  (int)base->encoding(), (int)rt->encoding(), off)); }
   1.903 +	void lhu(Register rt, Register base, int off) { emit_long(insn_ORRI(lhu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.904 +	void ll (Register rt, Register base, int off) { emit_long(insn_ORRI(ll_op,  (int)base->encoding(), (int)rt->encoding(), off)); }
   1.905 +	void lld(Register rt, Register base, int off) { emit_long(insn_ORRI(lld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.906 +	void lui(Register rt, int imm)                { emit_long(insn_ORRI(lui_op, 0, (int)rt->encoding(), imm)); }
   1.907 +	void lw (Register rt, Register base, int off) { emit_long(insn_ORRI(lw_op,  (int)base->encoding(), (int)rt->encoding(), off)); }
   1.908 +	void lwl(Register rt, Register base, int off) { emit_long(insn_ORRI(lwl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.909 +	void lwr(Register rt, Register base, int off) { emit_long(insn_ORRI(lwr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.910 +	void lwu(Register rt, Register base, int off) { emit_long(insn_ORRI(lwu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
   1.911 +
   1.912 +	void lb (Register rt, Address src);
   1.913 +	void lbu(Register rt, Address src);
   1.914 +	void ld (Register rt, Address src);
   1.915 +	void ldl(Register rt, Address src);
   1.916 +	void ldr(Register rt, Address src);
   1.917 +	void lh (Register rt, Address src);
   1.918 +	void lhu(Register rt, Address src);
   1.919 +	void ll (Register rt, Address src);
   1.920 +	void lld(Register rt, Address src);
   1.921 +	void lw (Register rt, Address src);
   1.922 +	void lwl(Register rt, Address src);
   1.923 +	void lwr(Register rt, Address src);
   1.924 +	void lwu(Register rt, Address src);
   1.925 +	void lea(Register rt, Address src);
   1.926 +	
   1.927 +	void mfc0 (Register rt, Register rd) { emit_long(insn_COP0(mf_op, (int)rt->encoding(), (int)rd->encoding())); }
   1.928 +	void mfhi (Register rd)              { emit_long( ((int)rd->encoding()<<11) | mfhi_op ); }	
   1.929 +	void mflo (Register rd)              { emit_long( ((int)rd->encoding()<<11) | mflo_op ); }	
   1.930 +	void mtc0 (Register rt, Register rd) { emit_long(insn_COP0(mt_op, (int)rt->encoding(), (int)rd->encoding())); }
   1.931 +	void mthi (Register rs)              { emit_long( ((int)rs->encoding()<<21) | mthi_op ); }	
   1.932 +	void mtlo (Register rs)              { emit_long( ((int)rs->encoding()<<21) | mtlo_op ); }	
   1.933 +// Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
   1.934 +//#ifndef _LP64
   1.935 +#if 1
   1.936 +	void mult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, mult_op)); }
   1.937 +	void multu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, multu_op)); }
   1.938 +#else
   1.939 +	void mult (Register rs, Register rt) { dmult  (rs, rt); }
   1.940 +	void multu(Register rs, Register rt) { dmultu (rs, rt); }
   1.941 +#endif
   1.942 +	
   1.943 +	void nor(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), nor_op)); }
   1.944 +	
   1.945 +	void orr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), or_op)); }
   1.946 +	void ori(Register rt, Register rs, int imm)     { emit_long(insn_ORRI(ori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
   1.947 +
   1.948 +	void sb   (Register rt, Register base, int off)     { emit_long(insn_ORRI(sb_op,    (int)base->encoding(), (int)rt->encoding(), off)); }
   1.949 +	void sc   (Register rt, Register base, int off)     { emit_long(insn_ORRI(sc_op,    (int)base->encoding(), (int)rt->encoding(), off)); }
   1.950 +	void scd  (Register rt, Register base, int off)     { emit_long(insn_ORRI(scd_op,   (int)base->encoding(), (int)rt->encoding(), off)); }
   1.951 +	void sd   (Register rt, Register base, int off)     { emit_long(insn_ORRI(sd_op,    (int)base->encoding(), (int)rt->encoding(), off)); }
   1.952 +	void sdl  (Register rt, Register base, int off)     { emit_long(insn_ORRI(sdl_op,   (int)base->encoding(), (int)rt->encoding(), off)); }
   1.953 +	void sdr  (Register rt, Register base, int off)     { emit_long(insn_ORRI(sdr_op,   (int)base->encoding(), (int)rt->encoding(), off)); }
   1.954 +	void sh   (Register rt, Register base, int off)     { emit_long(insn_ORRI(sh_op,    (int)base->encoding(), (int)rt->encoding(), off)); }
   1.955 +//#ifndef _LP64
   1.956 +#if 1
   1.957 +	void sll  (Register rd, Register rt ,  int sa)      { emit_long(insn_RRSO((int)rt->encoding(),  (int)rd->encoding(),   sa,      sll_op)); }
   1.958 +	void sllv (Register rd, Register rt,   Register rs) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), sllv_op)); }
   1.959 +#else
   1.960 +	void sll  (Register rd, Register rt ,  int sa)      { dsll  (rd, rt, sa);}
   1.961 +	void sllv (Register rd, Register rt,   Register rs) { dsllv (rd, rt, rs); }
   1.962 +#endif
   1.963 +	void slt  (Register rd, Register rs,   Register rt) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), slt_op)); }	
   1.964 +	void slti (Register rt, Register rs,   int imm)     { emit_long(insn_ORRI(slti_op,  (int)rs->encoding(),   (int)rt->encoding(), imm)); }
   1.965 +	void sltiu(Register rt, Register rs,   int imm)     { emit_long(insn_ORRI(sltiu_op, (int)rs->encoding(),   (int)rt->encoding(), imm)); }
   1.966 +	void sltu (Register rd, Register rs,   Register rt) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), sltu_op)); }	
   1.967 +//#ifndef _LP64
   1.968 +#if 1
   1.969 +	void sra  (Register rd, Register rt ,  int sa)      { emit_long(insn_RRSO((int)rt->encoding(),  (int)rd->encoding(),   sa,      sra_op)); }
   1.970 +	void srav (Register rd, Register rt,   Register rs) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), srav_op)); }	
   1.971 +	void srl  (Register rd, Register rt ,  int sa)      { emit_long(insn_RRSO((int)rt->encoding(),  (int)rd->encoding(),   sa,      srl_op)); }
   1.972 +	void srlv (Register rd, Register rt,   Register rs) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), srlv_op)); }	
   1.973 +#else
   1.974 +	void sra  (Register rd, Register rt ,  int sa)      { dsra  (rd, rt, sa); }
   1.975 +	void srav (Register rd, Register rt,   Register rs) { dsrav (rd, rt, rs); }
   1.976 +	void srl  (Register rd, Register rt ,  int sa)      { dsrl  (rd, rt, sa); }
   1.977 +	void srlv (Register rd, Register rt,   Register rs) { dsrlv (rd, rt, rs); }	
   1.978 +#endif
   1.979 +#ifndef _LP64
   1.980 +	void sub  (Register rd, Register rs,   Register rt) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), sub_op)); }
   1.981 +	void subu (Register rd, Register rs,   Register rt) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), subu_op)); }
   1.982 +#else
   1.983 +	void sub  (Register rd, Register rs,   Register rt) { dsub  (rd, rs, rt); }
   1.984 +	void subu (Register rd, Register rs,   Register rt) { dsubu (rd, rs, rt); }
   1.985 +	void subu32 (Register rd, Register rs,   Register rt) { emit_long(insn_RRRO((int)rs->encoding(),  (int)rt->encoding(),   (int)rd->encoding(), subu_op)); }
   1.986 +#endif
   1.987 +	void sw   (Register rt, Register base, int off)     { emit_long(insn_ORRI(sw_op,    (int)base->encoding(), (int)rt->encoding(), off)); }
   1.988 +	void swl  (Register rt, Register base, int off)     { emit_long(insn_ORRI(swl_op,   (int)base->encoding(), (int)rt->encoding(), off)); }
   1.989 +	void swr  (Register rt, Register base, int off)     { emit_long(insn_ORRI(swr_op,   (int)base->encoding(), (int)rt->encoding(), off)); }
   1.990 +	void sync ()                                        { emit_long(sync_op); }
   1.991 +	void syscall(int code)                              { emit_long( (code<<6) | syscall_op ); }
   1.992 +
   1.993 +	void sb(Register rt, Address dst);
   1.994 +	void sc(Register rt, Address dst);
   1.995 +	void scd(Register rt, Address dst);
   1.996 +	void sd(Register rt, Address dst);
   1.997 +	void sdl(Register rt, Address dst);
   1.998 +	void sdr(Register rt, Address dst);
   1.999 +	void sh(Register rt, Address dst);
  1.1000 +	void sw(Register rt, Address dst);
  1.1001 +	void swl(Register rt, Address dst);
  1.1002 +	void swr(Register rt, Address dst);
  1.1003 +	
  1.1004 +	void teq  (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, teq_op)); }
  1.1005 +	void teqi (Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), teqi_op, imm)); }
  1.1006 +	void tge  (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, tge_op)); }
  1.1007 +	void tgei (Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgei_op, imm)); }
  1.1008 +	void tgeiu(Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgeiu_op, imm)); }
  1.1009 +	void tgeu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, tgeu_op)); }
  1.1010 +	void tlt  (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, tlt_op)); }
  1.1011 +	void tlti (Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tlti_op, imm)); }
  1.1012 +	void tltiu(Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tltiu_op, imm)); }
  1.1013 +	void tltu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, tltu_op)); }
  1.1014 +	void tne  (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(),   (int)rt->encoding(), code, tne_op)); }
  1.1015 +	void tnei (Register rs, int imm)               { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tnei_op, imm)); }
  1.1016 +	
  1.1017 +	void xorr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), xor_op)); }
  1.1018 +	void xori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(xori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
  1.1019 +
  1.1020 +	void nop() 				      { emit_long(0); }
  1.1021 +	//float instructions for mips
  1.1022 +	void abs_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fabs_op));}
  1.1023 +	void abs_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fabs_op));}
  1.1024 +	void add_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fadd_op));}
  1.1025 +	void add_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fadd_op));}
  1.1026 +	
  1.1027 +	void bc1f (int off) { emit_long(insn_ORRI(cop1_op, bc_op, bcf_op, off)); has_delay_slot(); }
  1.1028 +	void bc1fl(int off) {	emit_long(insn_ORRI(cop1_op, bc_op, bcfl_op, off)); has_delay_slot(); }
  1.1029 +	void bc1t (int off) { emit_long(insn_ORRI(cop1_op, bc_op, bct_op, off)); has_delay_slot(); }
  1.1030 +	void bc1tl(int off) {	emit_long(insn_ORRI(cop1_op, bc_op, bctl_op, off));	has_delay_slot(); }
  1.1031 +
  1.1032 +	void bc1f (address entry) { bc1f(offset(entry)); }
  1.1033 +	void bc1fl(address entry) {	bc1fl(offset(entry)); }
  1.1034 +	void bc1t (address entry) { bc1t(offset(entry)); }
  1.1035 +	void bc1tl(address entry) {	bc1tl(offset(entry)); }
  1.1036 +	
  1.1037 +	void bc1f (Label& L) { bc1f(target(L)); }
  1.1038 +	void bc1fl(Label& L) {	bc1fl(target(L)); }
  1.1039 +	void bc1t (Label& L) { bc1t(target(L)); }
  1.1040 +	void bc1tl(Label& L) {	bc1tl(target(L)); }
  1.1041 +	
  1.1042 +	void c_f_s   (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, f_cond)); }
  1.1043 +	void c_f_d   (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, f_cond)); }
  1.1044 +	void c_un_s  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, un_cond)); }
  1.1045 +	void c_un_d  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, un_cond)); }
  1.1046 +	void c_eq_s  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, eq_cond)); }
  1.1047 +	void c_eq_d  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, eq_cond)); }
  1.1048 +	void c_ueq_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ueq_cond)); }
  1.1049 +	void c_ueq_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ueq_cond)); }
  1.1050 +	void c_olt_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, olt_cond)); }
  1.1051 +	void c_olt_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, olt_cond)); }
  1.1052 +	void c_ult_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ult_cond)); }
  1.1053 +	void c_ult_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ult_cond)); }
  1.1054 +	void c_ole_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ole_cond)); }
  1.1055 +	void c_ole_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ole_cond)); }
  1.1056 +	void c_ule_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ule_cond)); }
  1.1057 +	void c_ule_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ule_cond)); }
  1.1058 +	void c_sf_s  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, sf_cond)); }
  1.1059 +	void c_sf_d  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, sf_cond)); }
  1.1060 +	void c_ngle_s(FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngle_cond)); }
  1.1061 +	void c_ngle_d(FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngle_cond)); }
  1.1062 +	void c_seq_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, seq_cond)); }
  1.1063 +	void c_seq_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, seq_cond)); }
  1.1064 +	void c_ngl_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngl_cond)); }
  1.1065 +	void c_ngl_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngl_cond)); }
  1.1066 +	void c_lt_s  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, lt_cond)); }
  1.1067 +	void c_lt_d  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, lt_cond)); }
  1.1068 +	void c_nge_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, nge_cond)); }
  1.1069 +	void c_nge_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, nge_cond)); }
  1.1070 +	void c_le_s  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, le_cond)); }
  1.1071 +	void c_le_d  (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, le_cond)); }
  1.1072 +	void c_ngt_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngt_cond)); }
  1.1073 +	void c_ngt_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngt_cond)); }
  1.1074 +	
  1.1075 +	void ceil_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceill_op)); }
  1.1076 +	void ceil_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceill_op)); }
  1.1077 +	void ceil_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceilw_op)); }
  1.1078 +	void ceil_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceilw_op)); }
  1.1079 +	void cfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(cf_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1080 +	void ctc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(ct_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1081 +	void cfc1(Register rt, int fs) { emit_long(insn_COP1(cf_op, (int)rt->encoding(), fs)); }
  1.1082 +	void ctc1(Register rt, int fs) { emit_long(insn_COP1(ct_op, (int)rt->encoding(), fs)); }
  1.1083 +
  1.1084 +	void cvt_d_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
  1.1085 +	void cvt_d_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
  1.1086 +	void cvt_d_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
  1.1087 +	void cvt_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
  1.1088 +	void cvt_l_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
  1.1089 +	void cvt_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
  1.1090 +	void cvt_s_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
  1.1091 +	void cvt_s_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
  1.1092 +	void cvt_s_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
  1.1093 +	void cvt_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
  1.1094 +	void cvt_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
  1.1095 +	void cvt_w_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
  1.1096 +	void pll(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpll_op)); }
  1.1097 +	void plu(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fplu_op)); }
  1.1098 +	void pul(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpul_op)); }
  1.1099 +	void puu(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpuu_op)); }
  1.1100 +	
  1.1101 +	void div_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fdiv_op)); }
  1.1102 +	void div_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fdiv_op)); }
  1.1103 +	void dmfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmf_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1104 +	void dmtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmt_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1105 +
  1.1106 +	void floor_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorl_op)); }
  1.1107 +	void floor_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorl_op)); }
  1.1108 +	void floor_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorw_op)); }
  1.1109 +	void floor_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorw_op)); }
  1.1110 +	
  1.1111 +	void ldc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(ldc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
  1.1112 +	void lwc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(lwc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
  1.1113 +	void ldc1(FloatRegister ft, Address src);
  1.1114 +	void lwc1(FloatRegister ft, Address src);
  1.1115 +	
  1.1116 +	void mfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(mf_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1117 +	void mov_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fmov_op)); }
  1.1118 +	void mov_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fmov_op)); }
  1.1119 +	void mtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(mt_op, (int)rt->encoding(), (int)fs->encoding())); }
  1.1120 +	void mul_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fmul_op)); }
  1.1121 +	void mul_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fmul_op)); }
  1.1122 +
  1.1123 +	void neg_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fneg_op)); }
  1.1124 +	void neg_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fneg_op)); }
  1.1125 +	
  1.1126 +	void round_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundl_op)); }
  1.1127 +	void round_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundl_op)); }
  1.1128 +	void round_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundw_op)); }
  1.1129 +	void round_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundw_op)); }
  1.1130 +	
  1.1131 +	void sdc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(sdc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
  1.1132 +	void sdc1(FloatRegister ft, Address dst);
  1.1133 +	void sqrt_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fsqrt_op)); }
  1.1134 +	void sqrt_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fsqrt_op)); }
  1.1135 +	void sub_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fsub_op)); }
  1.1136 +	void sub_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fsub_op)); }
  1.1137 +	void swc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(swc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
  1.1138 +	void swc1(FloatRegister ft, Address dst);
  1.1139 +
  1.1140 +	void trunc_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncl_op)); }
  1.1141 +	void trunc_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncl_op)); }
  1.1142 +	void trunc_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncw_op)); }
  1.1143 +	void trunc_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncw_op)); }
  1.1144 +  
  1.1145 +	void int3();
  1.1146 +	static void print_instruction(int);
  1.1147 +	int patched_branch(int dest_pos, int inst, int inst_pos);
  1.1148 +	int branch_destination(int inst, int pos);
  1.1149 +
  1.1150 +	/* Godson3 extension */
  1.1151 +	void gsldx(Register rt, Register base, Register index, int off) {
  1.1152 +		assert(is_simm(off, 8), "gsldx: off exceeds 8 bits");
  1.1153 +		emit_long(gsldx_op | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)index->encoding() << 11) | (off << 3));
  1.1154 +	}
  1.1155 +
  1.1156 +	void gslwx(Register rt, Register base, Register index, int off) {
  1.1157 +		assert(is_simm(off, 8), "gslwx: off exceeds 8 bits");
  1.1158 +		emit_long(gslwx_op | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)index->encoding() << 11) | (off << 3));
  1.1159 +	}
  1.1160 +
  1.1161 +public:
  1.1162 +	// Creation
  1.1163 +	Assembler(CodeBuffer* code) : AbstractAssembler(code) {
  1.1164 +#ifdef CHECK_DELAY
  1.1165 +	  delay_state = no_delay;
  1.1166 +#endif
  1.1167 +	}
  1.1168 +
  1.1169 +  // Decoding
  1.1170 +  static address locate_operand(address inst, WhichOperand which);
  1.1171 +  static address locate_next_instruction(address inst);
  1.1172 +};
  1.1173 +
  1.1174 +
  1.1175 +// MacroAssembler extends Assembler by frequently used macros.
  1.1176 +//
  1.1177 +// Instructions for which a 'better' code sequence exists depending
  1.1178 +// on arguments should also go in here.
  1.1179 +
  1.1180 +class MacroAssembler: public Assembler {
  1.1181 +  friend class LIR_Assembler;
  1.1182 +  friend class Runtime1;      // as_Address()
  1.1183 +
  1.1184 +public:
  1.1185 +static intptr_t	i[32];
  1.1186 +static float	f[32];
  1.1187 +static void print(outputStream *s);
  1.1188 +
  1.1189 +static int i_offset(unsigned int k);
  1.1190 +static int f_offset(unsigned int k);
  1.1191 +	
  1.1192 +static void save_registers(MacroAssembler *masm);
  1.1193 +static void restore_registers(MacroAssembler *masm);
  1.1194 +
  1.1195 + protected:
  1.1196 +
  1.1197 +  Address as_Address(AddressLiteral adr);
  1.1198 +  Address as_Address(ArrayAddress adr);
  1.1199 +
  1.1200 +  // Support for VM calls
  1.1201 +  //
  1.1202 +  // This is the base routine called by the different versions of call_VM_leaf. The interpreter
  1.1203 +  // may customize this version by overriding it for its purposes (e.g., to save/restore
  1.1204 +  // additional registers when doing a VM call).
  1.1205 +#ifdef CC_INTERP
  1.1206 +  // c++ interpreter never wants to use interp_masm version of call_VM
  1.1207 +  #define VIRTUAL
  1.1208 +#else
  1.1209 +  #define VIRTUAL virtual
  1.1210 +#endif
  1.1211 +
  1.1212 +  VIRTUAL void call_VM_leaf_base(
  1.1213 +    address entry_point,               // the entry point
  1.1214 +    int     number_of_arguments        // the number of arguments to pop after the call
  1.1215 +  );
  1.1216 +
  1.1217 +  // This is the base routine called by the different versions of call_VM. The interpreter
  1.1218 +  // may customize this version by overriding it for its purposes (e.g., to save/restore
  1.1219 +  // additional registers when doing a VM call).
  1.1220 +  //
  1.1221 +  // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base
  1.1222 +  // returns the register which contains the thread upon return. If a thread register has been
  1.1223 +  // specified, the return value will correspond to that register. If no last_java_sp is specified
  1.1224 +  // (noreg) than rsp will be used instead.
  1.1225 +  VIRTUAL void call_VM_base(           // returns the register containing the thread upon return
  1.1226 +    Register oop_result,               // where an oop-result ends up if any; use noreg otherwise
  1.1227 +    Register java_thread,              // the thread if computed before     ; use noreg otherwise
  1.1228 +    Register last_java_sp,             // to set up last_Java_frame in stubs; use noreg otherwise
  1.1229 +    address  entry_point,              // the entry point
  1.1230 +    int      number_of_arguments,      // the number of arguments (w/o thread) to pop after the call
  1.1231 +    bool     check_exceptions          // whether to check for pending exceptions after return
  1.1232 +  );
  1.1233 +
  1.1234 +  // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
  1.1235 +  // The implementation is only non-empty for the InterpreterMacroAssembler,
  1.1236 +  // as only the interpreter handles PopFrame and ForceEarlyReturn requests.
  1.1237 +  virtual void check_and_handle_popframe(Register java_thread);
  1.1238 +  virtual void check_and_handle_earlyret(Register java_thread);
  1.1239 +
  1.1240 +  void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
  1.1241 +
  1.1242 +  // helpers for FPU flag access
  1.1243 +  // tmp is a temporary register, if none is available use noreg
  1.1244 +  //void save_rax   (Register tmp);
  1.1245 +  //void restore_rax(Register tmp);
  1.1246 +
  1.1247 + public:
  1.1248 +  MacroAssembler(CodeBuffer* code) : Assembler(code) {}
  1.1249 +
  1.1250 +  // Support for NULL-checks
  1.1251 +  //
  1.1252 +  // Generates code that causes a NULL OS exception if the content of reg is NULL.
  1.1253 +  // If the accessed location is M[reg + offset] and the offset is known, provide the
  1.1254 +  // offset. No explicit code generation is needed if the offset is within a certain
  1.1255 +  // range (0 <= offset <= page_size).
  1.1256 +  // use "teq 83, reg" in mips now, by yjl 6/20/2005
  1.1257 +  void null_check(Register reg, int offset = -1);
  1.1258 +  static bool needs_explicit_null_check(intptr_t offset);
  1.1259 +	
  1.1260 +	// Required platform-specific helpers for Label::patch_instructions.
  1.1261 +  // They _shadow_ the declarations in AbstractAssembler, which are undefined.
  1.1262 +  void pd_patch_instruction(address branch, address target);
  1.1263 +
  1.1264 +  // Alignment
  1.1265 +  void align(int modulus);
  1.1266 +
  1.1267 +  // Misc
  1.1268 +  //void fat_nop(); // 5 byte nop
  1.1269 +
  1.1270 +  // Stack frame creation/removal
  1.1271 +  void enter();
  1.1272 +  void leave();
  1.1273 +
  1.1274 +  // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
  1.1275 +  // The pointer will be loaded into the thread register.
  1.1276 +  void get_thread(Register thread);
  1.1277 +
  1.1278 +
  1.1279 +  // Support for VM calls
  1.1280 +  //
  1.1281 +  // It is imperative that all calls into the VM are handled via the call_VM macros.
  1.1282 +  // They make sure that the stack linkage is setup correctly. call_VM's correspond
  1.1283 +  // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
  1.1284 +
  1.1285 +
  1.1286 +  void call_VM(Register oop_result,
  1.1287 +               address entry_point,
  1.1288 +               bool check_exceptions = true);
  1.1289 +  void call_VM(Register oop_result,
  1.1290 +               address entry_point,
  1.1291 +               Register arg_1,
  1.1292 +               bool check_exceptions = true);
  1.1293 +  void call_VM(Register oop_result,
  1.1294 +               address entry_point,
  1.1295 +               Register arg_1, Register arg_2,
  1.1296 +               bool check_exceptions = true);
  1.1297 +  void call_VM(Register oop_result,
  1.1298 +               address entry_point,
  1.1299 +               Register arg_1, Register arg_2, Register arg_3,
  1.1300 +               bool check_exceptions = true);
  1.1301 +  // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
  1.1302 +  void super_call_VM_leaf(address entry_point);
  1.1303 +  void super_call_VM_leaf(address entry_point, Register arg_1);
  1.1304 +  void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2);
  1.1305 +  void super_call_VM_leaf(address entry_point,
  1.1306 +                          Register arg_1, Register arg_2, Register arg_3);
  1.1307 +
  1.1308 +  // Overloadings with last_Java_sp
  1.1309 +  void call_VM(Register oop_result,
  1.1310 +               Register last_java_sp,
  1.1311 +               address entry_point,
  1.1312 +               int number_of_arguments = 0,
  1.1313 +               bool check_exceptions = true);
  1.1314 +  void call_VM(Register oop_result,
  1.1315 +               Register last_java_sp,
  1.1316 +               address entry_point,
  1.1317 +               Register arg_1, bool
  1.1318 +               check_exceptions = true);
  1.1319 +  void call_VM(Register oop_result,
  1.1320 +               Register last_java_sp,
  1.1321 +               address entry_point,
  1.1322 +               Register arg_1, Register arg_2,
  1.1323 +               bool check_exceptions = true);
  1.1324 +  void call_VM(Register oop_result,
  1.1325 +               Register last_java_sp,
  1.1326 +               address entry_point,
  1.1327 +               Register arg_1, Register arg_2, Register arg_3,
  1.1328 +               bool check_exceptions = true);
  1.1329 +
  1.1330 +  void call_VM_leaf(address entry_point,
  1.1331 +                    int number_of_arguments = 0);
  1.1332 +  void call_VM_leaf(address entry_point,
  1.1333 +                    Register arg_1);
  1.1334 +  void call_VM_leaf(address entry_point,
  1.1335 +                    Register arg_1, Register arg_2);
  1.1336 +  void call_VM_leaf(address entry_point,
  1.1337 +                    Register arg_1, Register arg_2, Register arg_3);
  1.1338 +
  1.1339 +  // last Java Frame (fills frame anchor)
  1.1340 +  void set_last_Java_frame(Register thread,
  1.1341 +                           Register last_java_sp,
  1.1342 +                           Register last_java_fp,
  1.1343 +                           address last_java_pc);
  1.1344 +
  1.1345 +  // thread in the default location (r15_thread on 64bit)
  1.1346 +  void set_last_Java_frame(Register last_java_sp,
  1.1347 +                           Register last_java_fp,
  1.1348 +                           address last_java_pc);
  1.1349 +
  1.1350 +  void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
  1.1351 +
  1.1352 +  // thread in the default location (r15_thread on 64bit)
  1.1353 +  void reset_last_Java_frame(bool clear_fp, bool clear_pc);
  1.1354 +
  1.1355 +  // Stores
  1.1356 +  void store_check(Register obj);                // store check for obj - register is destroyed afterwards
  1.1357 +  void store_check(Register obj, Address dst);   // same as above, dst is exact store location (reg. is destroyed)
  1.1358 +
  1.1359 +
  1.1360 +  void g1_write_barrier_pre(Register obj,
  1.1361 +#ifndef _LP64
  1.1362 +                            Register thread,
  1.1363 +#endif
  1.1364 +                            Register tmp,
  1.1365 +                            Register tmp2,
  1.1366 +                            bool     tosca_live);
  1.1367 +  void g1_write_barrier_post(Register store_addr,
  1.1368 +                             Register new_val,
  1.1369 +#ifndef _LP64
  1.1370 +                             Register thread,
  1.1371 +#endif
  1.1372 +                             Register tmp,
  1.1373 +                             Register tmp2);
  1.1374 +
  1.1375 +
  1.1376 +
  1.1377 +  // split store_check(Register obj) to enhance instruction interleaving
  1.1378 +  void store_check_part_1(Register obj);
  1.1379 +  void store_check_part_2(Register obj);
  1.1380 +
  1.1381 +  // C 'boolean' to Java boolean: x == 0 ? 0 : 1
  1.1382 +  void c2bool(Register x);
  1.1383 +  //add for compressedoops
  1.1384 +  void load_klass(Register dst, Register src);
  1.1385 +  void store_klass(Register dst, Register src);
  1.1386 +  void load_prototype_header(Register dst, Register src);
  1.1387 +/*
  1.1388 +  // C++ bool manipulation
  1.1389 +
  1.1390 +  void movbool(Register dst, Address src);
  1.1391 +  void movbool(Address dst, bool boolconst);
  1.1392 +  void movbool(Address dst, Register src);
  1.1393 +  void testbool(Register dst);
  1.1394 +
  1.1395 +  // oop manipulations
  1.1396 +  void load_klass(Register dst, Register src);
  1.1397 +  void store_klass(Register dst, Register src);
  1.1398 +
  1.1399 +  void load_prototype_header(Register dst, Register src);*/
  1.1400 +
  1.1401 +#ifdef _LP64
  1.1402 +  void store_klass_gap(Register dst, Register src);
  1.1403 +
  1.1404 +  void load_heap_oop(Register dst, Address src);
  1.1405 +  void store_heap_oop(Address dst, Register src);
  1.1406 +  void encode_heap_oop(Register r);
  1.1407 +  void decode_heap_oop(Register r);
  1.1408 +  void encode_heap_oop_not_null(Register r);
  1.1409 +  void decode_heap_oop_not_null(Register r);
  1.1410 +  void encode_heap_oop_not_null(Register dst, Register src);
  1.1411 +  void decode_heap_oop_not_null(Register dst, Register src);
  1.1412 +
  1.1413 +  void encode_klass_not_null(Register r);
  1.1414 +  void decode_klass_not_null(Register r);
  1.1415 +  void encode_klass_not_null(Register dst, Register src);
  1.1416 +  void decode_klass_not_null(Register dst, Register src);
  1.1417 +
  1.1418 +  //void set_narrow_oop(Register dst, jobject obj);
  1.1419 +
  1.1420 +  // Returns the byte size of the instructions generated by decode_klass_not_null()
  1.1421 +  // when compressed klass pointers are being used.
  1.1422 +  static int instr_size_for_decode_klass_not_null();
  1.1423 +
  1.1424 +  // if heap base register is used - reinit it with the correct value
  1.1425 +  void reinit_heapbase();
  1.1426 +  DEBUG_ONLY(void verify_heapbase(const char* msg);)
  1.1427 +
  1.1428 +#endif // _LP64
  1.1429 +
  1.1430 +  void incrementl(Register reg, int value = 1);
  1.1431 +
  1.1432 +  void decrementl(Register reg, int value = 1);
  1.1433 +
  1.1434 +/*
  1.1435 +  // Int division/remainder for Java
  1.1436 +  // (as idivl, but checks for special case as described in JVM spec.)
  1.1437 +  // returns idivl instruction offset for implicit exception handling
  1.1438 +  int corrected_idivl(Register reg);
  1.1439 +
  1.1440 +  // Long division/remainder for Java
  1.1441 +  // (as idivq, but checks for special case as described in JVM spec.)
  1.1442 +  // returns idivq instruction offset for implicit exception handling
  1.1443 +  int corrected_idivq(Register reg);
  1.1444 +*/
  1.1445 +
  1.1446 +  void int3();
  1.1447 +/*
  1.1448 +  // Long operation macros for a 32bit cpu
  1.1449 +  // Long negation for Java
  1.1450 +  void lneg(Register hi, Register lo);
  1.1451 +
  1.1452 +  // Long multiplication for Java
  1.1453 +  // (destroys contents of eax, ebx, ecx and edx)
  1.1454 +  void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y
  1.1455 +
  1.1456 +  // Long shifts for Java
  1.1457 +  // (semantics as described in JVM spec.)
  1.1458 +  void lshl(Register hi, Register lo);                               // hi:lo << (rcx & 0x3f)
  1.1459 +  void lshr(Register hi, Register lo, bool sign_extension = false);  // hi:lo >> (rcx & 0x3f)
  1.1460 +
  1.1461 +  // Long compare for Java
  1.1462 +  // (semantics as described in JVM spec.)
  1.1463 +  void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y)
  1.1464 +
  1.1465 +
  1.1466 +  // misc
  1.1467 +*/
  1.1468 +  // Sign extension
  1.1469 +#ifdef _LP64
  1.1470 +  void sign_extend_short(Register reg) 	{ dsll32(reg, reg, 16); dsra32(reg, reg, 16); }
  1.1471 +  void sign_extend_byte(Register reg)	{ dsll32(reg, reg, 24); dsra32(reg, reg, 24); }
  1.1472 +#else
  1.1473 +  void sign_extend_short(Register reg) 	{ sll(reg, reg, 16); sra(reg, reg, 16); }
  1.1474 +  void sign_extend_byte(Register reg)	{ sll(reg, reg, 24); sra(reg, reg, 24); }
  1.1475 +#endif
  1.1476 +  void rem_s(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
  1.1477 +	void rem_d(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
  1.1478 +
  1.1479 +  // Inlined sin/cos generator for Java; must not use CPU instruction
  1.1480 +  // directly on Intel as it does not have high enough precision
  1.1481 +  // outside of the range [-pi/4, pi/4]. Extra argument indicate the
  1.1482 +  // number of FPU stack slots in use; all but the topmost will
  1.1483 +  // require saving if a slow case is necessary. Assumes argument is
  1.1484 +  // on FP TOS; result is on FP TOS.  No cpu registers are changed by
  1.1485 +  // this code.
  1.1486 +  void trigfunc(char trig, int num_fpu_regs_in_use = 1);
  1.1487 +/*
  1.1488 +  // branch to L if FPU flag C2 is set/not set
  1.1489 +  // tmp is a temporary register, if none is available use noreg
  1.1490 +  void jC2 (Register tmp, Label& L);
  1.1491 +  void jnC2(Register tmp, Label& L);
  1.1492 +
  1.1493 +  // Pop ST (ffree & fincstp combined)
  1.1494 +  void fpop();
  1.1495 +
  1.1496 +  // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
  1.1497 +  void push_fTOS();
  1.1498 +
  1.1499 +  // pops double TOS element from CPU stack and pushes on FPU stack
  1.1500 +  void pop_fTOS();
  1.1501 +
  1.1502 +  void empty_FPU_stack();
  1.1503 +
  1.1504 +  void push_IU_state();
  1.1505 +  void pop_IU_state();
  1.1506 +
  1.1507 +  void push_FPU_state();
  1.1508 +  void pop_FPU_state();
  1.1509 +
  1.1510 +  void push_CPU_state();
  1.1511 +  void pop_CPU_state();
  1.1512 +
  1.1513 +  // Round up to a power of two
  1.1514 +  void round_to(Register reg, int modulus);
  1.1515 +
  1.1516 +  // Callee saved registers handling
  1.1517 +  void push_callee_saved_registers();
  1.1518 +  void pop_callee_saved_registers();
  1.1519 +*/
  1.1520 +  // allocation
  1.1521 +  void eden_allocate(
  1.1522 +    Register obj,                      // result: pointer to object after successful allocation
  1.1523 +    Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
  1.1524 +    int      con_size_in_bytes,        // object size in bytes if   known at compile time
  1.1525 +    Register t1,                       // temp register
  1.1526 +    Register t2,
  1.1527 +    Label&   slow_case                 // continuation point if fast allocation fails
  1.1528 +  );
  1.1529 +  void tlab_allocate(
  1.1530 +    Register obj,                      // result: pointer to object after successful allocation
  1.1531 +    Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
  1.1532 +    int      con_size_in_bytes,        // object size in bytes if   known at compile time
  1.1533 +    Register t1,                       // temp register
  1.1534 +    Register t2,                       // temp register
  1.1535 +    Label&   slow_case                 // continuation point if fast allocation fails
  1.1536 +    );
  1.1537 +  void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
  1.1538 +
  1.1539 +  //----
  1.1540 +  //  void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
  1.1541 +
  1.1542 +
  1.1543 +  // Debugging
  1.1544 +
  1.1545 +  // only if +VerifyOops
  1.1546 +  void verify_oop(Register reg, const char* s = "broken oop");
  1.1547 +  void verify_oop_addr(Address addr, const char * s = "broken oop addr");
  1.1548 +  void verify_oop_subroutine();
  1.1549 +  // TODO: verify method and klass metadata (compare against vptr?)
  1.1550 +  void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {}
  1.1551 +  void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line){}
  1.1552 +  
  1.1553 +  #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
  1.1554 +  #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
  1.1555 + 
  1.1556 +  // only if +VerifyFPU
  1.1557 +  void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
  1.1558 +
  1.1559 +  // prints msg, dumps registers and stops execution
  1.1560 +  void stop(const char* msg);
  1.1561 +
  1.1562 +  // prints msg and continues
  1.1563 +  void warn(const char* msg);
  1.1564 +
  1.1565 +  static void debug(char* msg/*, RegistersForDebugging* regs*/);
  1.1566 +  static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
  1.1567 +  static void debug64(char* msg, int64_t pc, int64_t regs[]);
  1.1568 +
  1.1569 +  void print_reg(Register reg);
  1.1570 +  void print_reg(FloatRegister reg);
  1.1571 +  //void os_breakpoint();
  1.1572 +
  1.1573 +  void untested()                                { stop("untested"); }
  1.1574 +
  1.1575 +  void unimplemented(const char* what = "")      { char* b = new char[1024];  jio_snprintf(b, sizeof(b), "unimplemented: %s", what);  stop(b); }
  1.1576 +
  1.1577 +  void should_not_reach_here()                   { stop("should not reach here"); }
  1.1578 +
  1.1579 +  void print_CPU_state();
  1.1580 +
  1.1581 +  // Stack overflow checking
  1.1582 +  void bang_stack_with_offset(int offset) {
  1.1583 +    // stack grows down, caller passes positive offset
  1.1584 +    assert(offset > 0, "must bang with negative offset");
  1.1585 +    if (offset <= 32768) {
  1.1586 +      sw(A0, SP, -offset);
  1.1587 +    } else {
  1.1588 +#ifdef _LP64
  1.1589 +      li(AT, offset);
  1.1590 +      dsub(AT, SP, AT);
  1.1591 +#else
  1.1592 +      move(AT, offset);
  1.1593 +      sub(AT, SP, AT);
  1.1594 +#endif
  1.1595 +      sw(A0, AT, 0);
  1.1596 +    }
  1.1597 +  }
  1.1598 +
  1.1599 +  	// Writes to stack successive pages until offset reached to check for
  1.1600 +  	// stack overflow + shadow pages.  Also, clobbers tmp
  1.1601 +  	void bang_stack_size(Register size, Register tmp);
  1.1602 +        virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
  1.1603 +                                                       Register tmp,
  1.1604 +                                                       int offset);
  1.1605 +
  1.1606 +  	// Support for serializing memory accesses between threads
  1.1607 +  	void serialize_memory(Register thread, Register tmp);
  1.1608 +
  1.1609 +  	//void verify_tlab();
  1.1610 +  	void verify_tlab(Register t1, Register t2);
  1.1611 +
  1.1612 +  	// Biased locking support
  1.1613 +  	// lock_reg and obj_reg must be loaded up with the appropriate values.
  1.1614 +  	// swap_reg must be rax, and is killed.
  1.1615 +  	// tmp_reg is optional. If it is supplied (i.e., != noreg) it will
  1.1616 +  	// be killed; if not supplied, push/pop will be used internally to
  1.1617 +  	// allocate a temporary (inefficient, avoid if possible).
  1.1618 +  	// Optional slow case is for implementations (interpreter and C1) which branch to
  1.1619 +  	// slow case directly. Leaves condition codes set for C2's Fast_Lock node.
  1.1620 +  	// Returns offset of first potentially-faulting instruction for null
  1.1621 +  	// check info (currently consumed only by C1). If
  1.1622 +  	// swap_reg_contains_mark is true then returns -1 as it is assumed
  1.1623 +  	// the calling code has already passed any potential faults.
  1.1624 +  	int biased_locking_enter(Register lock_reg, Register obj_reg,
  1.1625 +			  Register swap_reg, Register tmp_reg,
  1.1626 +			  bool swap_reg_contains_mark,
  1.1627 +			  Label& done, Label* slow_case = NULL,
  1.1628 +			  BiasedLockingCounters* counters = NULL);
  1.1629 +	void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
  1.1630 +
  1.1631 +
  1.1632 +  // Calls
  1.1633 +
  1.1634 +	void call(address entry);
  1.1635 +	void call(address entry, relocInfo::relocType rtype); 
  1.1636 +	void call(address entry, RelocationHolder& rh); 
  1.1637 +	// Emit the CompiledIC call idiom
  1.1638 +	void ic_call(address entry);
  1.1639 +
  1.1640 +	void jmp(address entry);
  1.1641 +	void jmp(address entry, relocInfo::relocType rtype);
  1.1642 +
  1.1643 +	// Argument ops
  1.1644 +	/*inline void store_int_argument(Register s, Argument& a);
  1.1645 +	inline void store_long_argument(Register s, Argument& a);
  1.1646 +	inline void store_float_argument(FloatRegister s, Argument& a);
  1.1647 +	inline void store_double_argument(FloatRegister s, Argument& a);
  1.1648 +	inline void store_ptr_argument(Register s, Argument& a);*/
  1.1649 +inline void store_int_argument(Register s, Argument &a) {
  1.1650 +        if(a.is_Register()) {
  1.1651 +                move(a.as_Register(), s);
  1.1652 +        } else {
  1.1653 +                sw(s, a.as_caller_address());
  1.1654 +        }
  1.1655 +}
  1.1656 +
  1.1657 +inline void store_long_argument(Register s, Argument &a) {
  1.1658 +        Argument a1 = a.successor();
  1.1659 +        if(a.is_Register() && a1.is_Register()) {
  1.1660 +                move(a.as_Register(), s);
  1.1661 +                move(a.as_Register(), s);
  1.1662 +        } else {
  1.1663 +                sd(s, a.as_caller_address());
  1.1664 +        }
  1.1665 +}
  1.1666 +
  1.1667 +inline void store_float_argument(FloatRegister s, Argument &a) {
  1.1668 +        if(a.is_Register()) {
  1.1669 +                mov_s(a.as_FloatRegister(), s);
  1.1670 +        } else {
  1.1671 +                swc1(s, a.as_caller_address());
  1.1672 +        }
  1.1673 +}
  1.1674 +inline void store_double_argument(FloatRegister s, Argument &a) {
  1.1675 +        if(a.is_Register()) {
  1.1676 +                mov_d(a.as_FloatRegister(), s);
  1.1677 +        } else {
  1.1678 +                sdc1(s, a.as_caller_address());
  1.1679 +        }
  1.1680 +}
  1.1681 +
  1.1682 +inline void store_ptr_argument(Register s, Argument &a) {
  1.1683 +  if(a.is_Register()) {
  1.1684 +    move(a.as_Register(), s);
  1.1685 +  } else {
  1.1686 +    st_ptr(s, a.as_caller_address());
  1.1687 +  }
  1.1688 +}
  1.1689 +
  1.1690 +  // Load and store values by size and signed-ness
  1.1691 +  void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
  1.1692 +  void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
  1.1693 +
  1.1694 +  // interface method calling
  1.1695 +  void lookup_interface_method(Register recv_klass,
  1.1696 +                               Register intf_klass,
  1.1697 +                               RegisterOrConstant itable_index,
  1.1698 +                               Register method_result,
  1.1699 +                               Register scan_temp,
  1.1700 +                               Label& no_such_interface);
  1.1701 +  // virtual method calling
  1.1702 +  void lookup_virtual_method(Register recv_klass,
  1.1703 +                             RegisterOrConstant vtable_index,
  1.1704 +                             Register method_result);
  1.1705 +
  1.1706 +	// ld_ptr will perform lw for 32 bit VMs and ld for 64 bit VMs
  1.1707 +	// st_ptr will perform sw for 32 bit VMs and sd for 64 bit VMs
  1.1708 +	inline void ld_ptr(Register rt, Address a){
  1.1709 +         #ifdef _LP64
  1.1710 +         ld(rt, a.base(), a.disp());
  1.1711 +         #else
  1.1712 +         lw(rt, a.base(), a.disp());
  1.1713 +         #endif
  1.1714 +        }
  1.1715 +	inline void ld_ptr(Register rt, Register base, int offset16){
  1.1716 +         #ifdef _LP64
  1.1717 +         ld(rt, base, offset16);
  1.1718 +         #else
  1.1719 +         lw(rt, base, offset16);
  1.1720 +         #endif
  1.1721 +
  1.1722 +        }
  1.1723 +	inline void st_ptr(Register rt, Address a){
  1.1724 +        #ifdef _LP64
  1.1725 +         sd(rt, a.base(), a.disp());
  1.1726 +        #else
  1.1727 +         sw(rt, a.base(), a.disp());
  1.1728 +        #endif
  1.1729 +        }
  1.1730 +	inline void st_ptr(Register rt, Register base, int offset16) {
  1.1731 +        #ifdef _LP64
  1.1732 +          sd(rt, base, offset16);
  1.1733 +        #else
  1.1734 +          sw(rt, base, offset16);
  1.1735 +        #endif
  1.1736 +
  1.1737 +        }
  1.1738 +
  1.1739 +	void ld_ptr(Register rt, Register offset, Register base);
  1.1740 +	void st_ptr(Register rt, Register offset, Register base);
  1.1741 +
  1.1742 +	// ld_long will perform lw for 32 bit VMs and ld for 64 bit VMs
  1.1743 +	// st_long will perform sw for 32 bit VMs and sd for 64 bit VMs
  1.1744 +	inline void ld_long(Register rt, Register base, int offset16);
  1.1745 +	inline void st_long(Register rt, Register base, int offset16);
  1.1746 +	inline void ld_long(Register rt, Address a);
  1.1747 +	inline void st_long(Register rt, Address a);
  1.1748 +
  1.1749 +
  1.1750 +	void ld_long(Register rt, Register offset, Register base);
  1.1751 +	void st_long(Register rt, Register offset, Register base);
  1.1752 +	// Regular vs. d* versions
  1.1753 +	inline void addu_long(Register rd, Register rs, Register rt) {
  1.1754 +        #ifdef _LP64
  1.1755 +         daddu(rd, rs, rt);
  1.1756 +        #else
  1.1757 +         addu(rd, rs, rt);
  1.1758 +        #endif
  1.1759 +        }
  1.1760 +	inline void addu_long(Register rd, Register rs, long imm32_64) {
  1.1761 +        #ifdef _LP64
  1.1762 +         daddiu(rd, rs, imm32_64);
  1.1763 +        #else
  1.1764 +         addiu(rd, rs, imm32_64);
  1.1765 +        #endif
  1.1766 +
  1.1767 +        }
  1.1768 +
  1.1769 +	// Floating
  1.1770 + public:
  1.1771 +	// swap the two byte of the low 16-bit halfword
  1.1772 +	// this directive will use AT, be sure the high 16-bit of reg is zero
  1.1773 +	// by yjl 6/28/2005
  1.1774 +	void hswap(Register reg);
  1.1775 +  	void huswap(Register reg);
  1.1776 +
  1.1777 +	// convert big endian integer to little endian integer
  1.1778 +  // by yjl 6/29/2005
  1.1779 +  	void swap(Register reg);
  1.1780 + 
  1.1781 +  // implement the x86 instruction semantic
  1.1782 +  // if c_reg == *dest then *dest <= x_reg
  1.1783 +	// else c_reg <= *dest
  1.1784 +	// the AT indicate if xchg occurred, 1 for xchged, else  0
  1.1785 +	// by yjl 6/28/2005
  1.1786 +	void cmpxchg(Register x_reg, Address dest, Register c_reg);
  1.1787 +#ifdef _LP64
  1.1788 +	void cmpxchg32(Register x_reg, Address dest, Register c_reg);
  1.1789 +#endif
  1.1790 +	void cmpxchg8(Register x_regLo, Register x_regHi, Address dest, Register c_regLo, Register c_regHi);
  1.1791 +
  1.1792 +
  1.1793 +	
  1.1794 +	void round_to(Register reg, int modulus) {
  1.1795 +		assert_different_registers(reg, AT);
  1.1796 +		increment(reg, modulus - 1);
  1.1797 +		move(AT, - modulus);
  1.1798 +		andr(reg, reg, AT);
  1.1799 +	}
  1.1800 +
  1.1801 +	//pop & push, added by aoqi
  1.1802 +#ifdef _LP64
  1.1803 +	void extend_sign(Register rh, Register rl) { stop("extend_sign"); }
  1.1804 +	void neg(Register reg) { dsubu(reg, R0, reg); }
  1.1805 +	void push (Register reg)      { sd  (reg, SP, -8); daddi(SP, SP, -8); }
  1.1806 +	void push (FloatRegister reg) { sdc1(reg, SP, -8); daddi(SP, SP, -8); }
  1.1807 +	void pop  (Register reg)      { ld  (reg, SP, 0);  daddi(SP, SP, 8); }
  1.1808 +	void pop  (FloatRegister reg) { ldc1(reg, SP, 0);  daddi(SP, SP, 8); }
  1.1809 +	void pop  ()                  { daddi(SP, SP, 8); }
  1.1810 +	void pop2 ()                  { daddi(SP, SP, 16); }
  1.1811 +#else
  1.1812 +	void extend_sign(Register rh, Register rl) { sra(rh, rl, 31); }
  1.1813 +	void neg(Register reg) { subu(reg, R0, reg); }
  1.1814 +	void push (Register reg)      { sw  (reg, SP, -4); addi(SP, SP, -4); }
  1.1815 +	void push (FloatRegister reg) { swc1(reg, SP, -4); addi(SP, SP, -4); }
  1.1816 +	void pop  (Register reg)      { lw  (reg, SP, 0);  addi(SP, SP, 4); }
  1.1817 +	void pop  (FloatRegister reg) { lwc1(reg, SP, 0);  addi(SP, SP, 4); }
  1.1818 +	void pop  ()                  { addi(SP, SP, 4); }
  1.1819 +	void pop2 ()                  { addi(SP, SP, 8); }
  1.1820 +#endif
  1.1821 +	void push2(Register reg1, Register reg2);
  1.1822 +	void pop2 (Register reg1, Register reg2);
  1.1823 +	void dpush (Register reg)     { sd  (reg, SP, -8); daddi(SP, SP, -8); }
  1.1824 +	void dpop  (Register reg)     { ld  (reg, SP, 0);  daddi(SP, SP, 8); }
  1.1825 +
  1.1826 +	/* branches may exceed 16-bit offset */
  1.1827 +	void b_far(address entry);
  1.1828 +	void b_far(Label& L);
  1.1829 +	
  1.1830 +	void bne_far    (Register rs, Register rt, address entry);
  1.1831 +	void bne_far    (Register rs, Register rt, Label& L);
  1.1832 +
  1.1833 +	void beq_far    (Register rs, Register rt, address entry);
  1.1834 +	void beq_far    (Register rs, Register rt, Label& L);
  1.1835 +
  1.1836 +	//move an 32-bit immediate to Register
  1.1837 +	void move(Register reg, int imm32)  { li32(reg, imm32); }
  1.1838 +	void li	(Register rd, long imm);
  1.1839 +	void li	(Register rd, address addr) { li(rd, (long)addr); }
  1.1840 +	//replace move(Register reg, int imm)
  1.1841 +	void li32(Register rd, int imm32); // sign-extends to 64 bits on mips64
  1.1842 +#ifdef _LP64
  1.1843 +	void dli(Register rd, long imm) { li(rd, imm); }
  1.1844 +	void li64(Register rd, long imm);
  1.1845 +	void li48(Register rd, long imm);
  1.1846 +#endif
  1.1847 +
  1.1848 +#ifdef _LP64
  1.1849 +	void move(Register rd, Register rs)   { dadd(rd, rs, R0); }
  1.1850 +	void move_u32(Register rd, Register rs)   { addu32(rd, rs, R0); }
  1.1851 +#else
  1.1852 +	void move(Register rd, Register rs)   { add(rd, rs, R0); }
  1.1853 +#endif
  1.1854 +	void dmove(Register rd, Register rs)  { dadd(rd, rs, R0); }
  1.1855 +
  1.1856 +#ifdef _LP64
  1.1857 +  	void shl(Register reg, int sa)        { dsll(reg, reg, sa); }
  1.1858 +  	void shr(Register reg, int sa)        { dsrl(reg, reg, sa); }
  1.1859 +  	void sar(Register reg, int sa)        { dsra(reg, reg, sa); }
  1.1860 +#else
  1.1861 +  	void shl(Register reg, int sa)        { sll(reg, reg, sa); }
  1.1862 +  	void shr(Register reg, int sa)        { srl(reg, reg, sa); }
  1.1863 +  	void sar(Register reg, int sa)        { sra(reg, reg, sa); }
  1.1864 +#endif
  1.1865 +
  1.1866 +#ifndef PRODUCT
  1.1867 +  static void pd_print_patched_instruction(address branch) {
  1.1868 +  jint stub_inst = *(jint*) branch;
  1.1869 +  print_instruction(stub_inst);
  1.1870 +  ::tty->print("%s", " (unresolved)");
  1.1871 +
  1.1872 +  }
  1.1873 +#endif
  1.1874 +
  1.1875 +	// the follow two might use AT register, be sure you have no meanful data in AT before you call them
  1.1876 +	// by yjl 6/23/2005
  1.1877 +	void increment(Register reg, int imm);
  1.1878 +	void decrement(Register reg, int imm);
  1.1879 +
  1.1880 +	//FIXME 
  1.1881 +  	void empty_FPU_stack(){/*need implemented*/};
  1.1882 +
  1.1883 +//we need 2 fun to save and resotre general register
  1.1884 +	void pushad();
  1.1885 +	void popad();
  1.1886 +
  1.1887 +	void  load_two_bytes_from_at_bcp(Register reg, Register tmp, int offset);
  1.1888 +	void  store_two_byts_to_at_bcp(Register reg, Register tmp, int offset);
  1.1889 +  // Test sub_klass against super_klass, with fast and slow paths.
  1.1890 +
  1.1891 +  // The fast path produces a tri-state answer: yes / no / maybe-slow.
  1.1892 +  // One of the three labels can be NULL, meaning take the fall-through.
  1.1893 +  // If super_check_offset is -1, the value is loaded up from super_klass.
  1.1894 +  // No registers are killed, except temp_reg.
  1.1895 +  void check_klass_subtype_fast_path(Register sub_klass,
  1.1896 +                                     Register super_klass,
  1.1897 +                                     Register temp_reg,
  1.1898 +                                     Label* L_success,
  1.1899 +                                     Label* L_failure,
  1.1900 +                                     Label* L_slow_path,
  1.1901 +                RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
  1.1902 +
  1.1903 +  // The rest of the type check; must be wired to a corresponding fast path.
  1.1904 +  // It does not repeat the fast path logic, so don't use it standalone.
  1.1905 +  // The temp_reg and temp2_reg can be noreg, if no temps are available.
  1.1906 +  // Updates the sub's secondary super cache as necessary.
  1.1907 +  // If set_cond_codes, condition codes will be Z on success, NZ on failure.
  1.1908 +  void check_klass_subtype_slow_path(Register sub_klass,
  1.1909 +                                     Register super_klass,
  1.1910 +                                     Register temp_reg,
  1.1911 +                                     Register temp2_reg,
  1.1912 +                                     Label* L_success,
  1.1913 +                                     Label* L_failure,
  1.1914 +                                     bool set_cond_codes = false);
  1.1915 +
  1.1916 +   // Simplified, combined version, good for typical uses.
  1.1917 +   // Falls through on failure.
  1.1918 +   void check_klass_subtype(Register sub_klass,
  1.1919 +                            Register super_klass,
  1.1920 +                            Register temp_reg,
  1.1921 +                            Label& L_success);
  1.1922 +
  1.1923 +  // method handles (JSR 292)
  1.1924 +  Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
  1.1925 +
  1.1926 +  void get_vm_result  (Register oop_result, Register thread);
  1.1927 +  void get_vm_result_2(Register metadata_result, Register thread);
  1.1928 +#undef VIRTUAL
  1.1929 +
  1.1930 +};
  1.1931 +
  1.1932 +/**
  1.1933 + * class SkipIfEqual:
  1.1934 + *
  1.1935 + * Instantiating this class will result in assembly code being output that will
  1.1936 + * jump around any code emitted between the creation of the instance and it's
  1.1937 + * automatic destruction at the end of a scope block, depending on the value of
  1.1938 + * the flag passed to the constructor, which will be checked at run-time.
  1.1939 + */
  1.1940 +class SkipIfEqual {
  1.1941 + private:
  1.1942 +  MacroAssembler* _masm;
  1.1943 +  Label _label;
  1.1944 +
  1.1945 + public:
  1.1946 +   SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value);
  1.1947 +   ~SkipIfEqual();
  1.1948 +};
  1.1949 +
  1.1950 +#ifdef ASSERT
  1.1951 +inline bool AbstractAssembler::pd_check_instruction_mark() { return true; }
  1.1952 +#endif
  1.1953 +
  1.1954 +#endif // CPU_MIPS_VM_ASSEMBLER_MIPS_HPP

mercurial