1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)interpreterRT_x86_64.cpp     1.27 07/09/17 09:26:03 JVM"
   3 #endif
   4 /*
   5  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  
  26  */
  27 
  28 #include "incls/_precompiled.incl"
  29 #include "incls/_interpreterRT_x86_64.cpp.incl"
  30 
  31 #define __ _masm->
  32 
  33 // Implementation of SignatureHandlerGenerator
  34 
  35 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
  36 Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return rsp; }
  37 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
  38 
  39 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
  40   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
  41 
  42 #ifdef _WIN64
  43   switch (_num_args) {
  44   case 0:
  45     __ movl(c_rarg1, src);
  46     _num_args++;
  47     break;
  48   case 1:
  49     __ movl(c_rarg2, src);
  50     _num_args++;
  51     break;
  52   case 2:
  53     __ movl(c_rarg3, src);
  54     _num_args++;
  55     break;
  56   default:
  57     __ movl(rax, src);
  58     __ movl(Address(to(), _stack_offset), rax);
  59     _stack_offset += wordSize;
  60     break;
  61   }
  62 #else
  63   switch (_num_int_args) {
  64   case 0:
  65     __ movl(c_rarg1, src);
  66     _num_int_args++;
  67     break;
  68   case 1:
  69     __ movl(c_rarg2, src);
  70     _num_int_args++;
  71     break;
  72   case 2:
  73     __ movl(c_rarg3, src);
  74     _num_int_args++;
  75     break;
  76   case 3:
  77     __ movl(c_rarg4, src);
  78     _num_int_args++;
  79     break;
  80   case 4:
  81     __ movl(c_rarg5, src);
  82     _num_int_args++;
  83     break;
  84   default:
  85     __ movl(rax, src);
  86     __ movl(Address(to(), _stack_offset), rax);
  87     _stack_offset += wordSize;
  88     break;
  89   }
  90 #endif
  91 }
  92 
  93 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
  94   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
  95 
  96 #ifdef _WIN64
  97   switch (_num_args) {
  98   case 0:
  99     __ movq(c_rarg1, src);
 100     _num_args++;
 101     break;
 102   case 1:
 103     __ movq(c_rarg2, src);
 104     _num_args++;
 105     break;
 106   case 2:
 107     __ movq(c_rarg3, src);
 108     _num_args++;
 109     break;
 110   case 3:
 111   default:
 112     __ movq(rax, src);
 113     __ movq(Address(to(), _stack_offset), rax);
 114     _stack_offset += wordSize;
 115     break;
 116   }
 117 #else
 118   switch (_num_int_args) {
 119   case 0:
 120     __ movq(c_rarg1, src);
 121     _num_int_args++;
 122     break;
 123   case 1:
 124     __ movq(c_rarg2, src);
 125     _num_int_args++;
 126     break;
 127   case 2:
 128     __ movq(c_rarg3, src);
 129     _num_int_args++;
 130     break;
 131   case 3:
 132     __ movq(c_rarg4, src);
 133     _num_int_args++;
 134     break;
 135   case 4:
 136     __ movq(c_rarg5, src);
 137     _num_int_args++;
 138     break;
 139   default:
 140     __ movq(rax, src);
 141     __ movq(Address(to(), _stack_offset), rax);
 142     _stack_offset += wordSize;
 143     break;
 144   }
 145 #endif
 146 }
 147 
 148 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
 149   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
 150 
 151 #ifdef _WIN64
 152   if (_num_args < Argument::n_float_register_parameters_c-1) {
 153     __ movflt(as_XMMRegister(++_num_args), src);
 154   } else {
 155     __ movl(rax, src);
 156     __ movl(Address(to(), _stack_offset), rax);
 157     _stack_offset += wordSize;
 158   }
 159 #else
 160   if (_num_fp_args < Argument::n_float_register_parameters_c) {
 161     __ movflt(as_XMMRegister(_num_fp_args++), src);
 162   } else {
 163     __ movl(rax, src);
 164     __ movl(Address(to(), _stack_offset), rax);
 165     _stack_offset += wordSize;
 166   }
 167 #endif
 168 }
 169 
 170 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
 171   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
 172 
 173 #ifdef _WIN64
 174   if (_num_args < Argument::n_float_register_parameters_c-1) {
 175     __ movdbl(as_XMMRegister(++_num_args), src);
 176   } else {
 177     __ movq(rax, src);
 178     __ movq(Address(to(), _stack_offset), rax);
 179     _stack_offset += wordSize;
 180   }
 181 #else
 182   if (_num_fp_args < Argument::n_float_register_parameters_c) {
 183     __ movdbl(as_XMMRegister(_num_fp_args++), src);
 184   } else {
 185     __ movq(rax, src);
 186     __ movq(Address(to(), _stack_offset), rax);
 187     _stack_offset += wordSize;
 188   }
 189 #endif
 190 }
 191 
 192 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
 193   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
 194 
 195 #ifdef _WIN64
 196   switch (_num_args) {
 197   case 0:
 198     assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
 199     __ leaq(c_rarg1, src);
 200     _num_args++;
 201     break;
 202   case 1:
 203     __ leaq(rax, src);
 204     __ xorl(c_rarg2, c_rarg2);
 205     __ cmpq(src, 0);
 206     __ cmovq(Assembler::notEqual, c_rarg2, rax);
 207     _num_args++;
 208     break;
 209   case 2:
 210     __ leaq(rax, src);
 211     __ xorl(c_rarg3, c_rarg3);
 212     __ cmpq(src, 0);
 213     __ cmovq(Assembler::notEqual, c_rarg3, rax);
 214     _num_args++;
 215     break;
 216   default:
 217     __ leaq(rax, src);
 218     __ xorl(temp(), temp());
 219     __ cmpq(src, 0);
 220     __ cmovq(Assembler::notEqual, temp(), rax);
 221     __ movq(Address(to(), _stack_offset), temp());
 222     _stack_offset += wordSize;
 223     break;
 224   }
 225 #else
 226   switch (_num_int_args) {
 227   case 0:
 228     assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
 229     __ leaq(c_rarg1, src);
 230     _num_int_args++;
 231     break;
 232   case 1:
 233     __ leaq(rax, src);
 234     __ xorl(c_rarg2, c_rarg2);
 235     __ cmpq(src, 0);
 236     __ cmovq(Assembler::notEqual, c_rarg2, rax);
 237     _num_int_args++;
 238     break;
 239   case 2:
 240     __ leaq(rax, src);
 241     __ xorl(c_rarg3, c_rarg3);
 242     __ cmpq(src, 0);
 243     __ cmovq(Assembler::notEqual, c_rarg3, rax);
 244     _num_int_args++;
 245     break;
 246   case 3:
 247     __ leaq(rax, src);
 248     __ xorl(c_rarg4, c_rarg4);
 249     __ cmpq(src, 0);
 250     __ cmovq(Assembler::notEqual, c_rarg4, rax);
 251     _num_int_args++;
 252     break;
 253   case 4:
 254     __ leaq(rax, src);
 255     __ xorl(c_rarg5, c_rarg5);
 256     __ cmpq(src, 0);
 257     __ cmovq(Assembler::notEqual, c_rarg5, rax);
 258     _num_int_args++;
 259     break;
 260   default:
 261     __ leaq(rax, src);
 262     __ xorl(temp(), temp());
 263     __ cmpq(src, 0);
 264     __ cmovq(Assembler::notEqual, temp(), rax);
 265     __ movq(Address(to(), _stack_offset), temp());
 266     _stack_offset += wordSize;
 267     break;
 268   }
 269 #endif
 270 }
 271 
 272 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
 273   // generate code to handle arguments
 274   iterate(fingerprint);
 275 
 276   // return result handler
 277   __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
 278   __ ret(0);
 279 
 280   __ flush();
 281 }
 282 
 283 
 284 // Implementation of SignatureHandlerLibrary
 285 
 286 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
 287 
 288 
 289 #ifdef _WIN64
 290 class SlowSignatureHandler 
 291   : public NativeSignatureIterator {
 292  private:
 293   address   _from;
 294   intptr_t* _to;
 295   intptr_t* _reg_args;
 296   intptr_t* _fp_identifiers;
 297   unsigned int _num_args;
 298 
 299 #ifdef ASSERT
 300   void verify_tag(frame::Tag t) {
 301     assert(!TaggedStackInterpreter ||
 302            *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag");
 303   }
 304 #endif // ASSERT
 305 
 306   virtual void pass_int()
 307   {
 308     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 
 309     debug_only(verify_tag(frame::TagValue));
 310     _from -= Interpreter::stackElementSize();
 311 
 312     if (_num_args < Argument::n_int_register_parameters_c-1) {
 313       *_reg_args++ = from_obj;
 314       _num_args++;
 315     } else {
 316       *_to++ = from_obj;
 317     }
 318   }
 319 
 320   virtual void pass_long()
 321   { 
 322     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 323     debug_only(verify_tag(frame::TagValue));
 324     _from -= 2*Interpreter::stackElementSize();
 325 
 326     if (_num_args < Argument::n_int_register_parameters_c-1) {
 327       *_reg_args++ = from_obj;
 328       _num_args++;
 329     } else {
 330       *_to++ = from_obj;
 331     }
 332   }
 333 
 334   virtual void pass_object()
 335   {
 336     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
 337     debug_only(verify_tag(frame::TagReference));
 338     _from -= Interpreter::stackElementSize();
 339     if (_num_args < Argument::n_int_register_parameters_c-1) {
 340       *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
 341       _num_args++;
 342     } else {
 343       *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
 344     }
 345   }
 346 
 347   virtual void pass_float()
 348   {
 349     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 
 350     debug_only(verify_tag(frame::TagValue));
 351     _from -= Interpreter::stackElementSize();
 352 
 353     if (_num_args < Argument::n_float_register_parameters_c-1) {
 354       *_reg_args++ = from_obj;
 355       *_fp_identifiers |= (0x01 << (_num_args*2)); // mark as float
 356       _num_args++;
 357     } else {
 358       *_to++ = from_obj;
 359     }
 360   }
 361 
 362   virtual void pass_double()
 363   {
 364     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 365     debug_only(verify_tag(frame::TagValue));
 366     _from -= 2*Interpreter::stackElementSize();
 367 
 368     if (_num_args < Argument::n_float_register_parameters_c-1) {
 369       *_reg_args++ = from_obj;
 370       *_fp_identifiers |= (0x3 << (_num_args*2)); // mark as double
 371       _num_args++;
 372     } else {
 373       *_to++ = from_obj;
 374     }
 375   }
 376 
 377  public:
 378   SlowSignatureHandler(methodHandle method, address from, intptr_t* to) 
 379     : NativeSignatureIterator(method)
 380   {
 381     _from = from;
 382     _to   = to;
 383 
 384     _reg_args = to - (method->is_static() ? 4 : 5);
 385     _fp_identifiers = to - 2;
 386     _to = _to + 4;  // Windows reserves stack space for register arguments
 387     *(int*) _fp_identifiers = 0;
 388     _num_args = (method->is_static() ? 1 : 0);
 389   }
 390 };
 391 #else
 392 class SlowSignatureHandler 
 393   : public NativeSignatureIterator {
 394  private:
 395   address   _from;
 396   intptr_t* _to;
 397   intptr_t* _int_args;
 398   intptr_t* _fp_args;
 399   intptr_t* _fp_identifiers;
 400   unsigned int _num_int_args;
 401   unsigned int _num_fp_args;
 402 
 403 #ifdef ASSERT
 404   void verify_tag(frame::Tag t) {
 405     assert(!TaggedStackInterpreter ||
 406            *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag");
 407   }
 408 #endif // ASSERT
 409 
 410   virtual void pass_int()
 411   {
 412     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 
 413     debug_only(verify_tag(frame::TagValue));
 414     _from -= Interpreter::stackElementSize();
 415 
 416     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
 417       *_int_args++ = from_obj;
 418       _num_int_args++;
 419     } else {
 420       *_to++ = from_obj;
 421     }
 422   }
 423 
 424   virtual void pass_long()
 425   { 
 426     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 427     debug_only(verify_tag(frame::TagValue));
 428     _from -= 2*Interpreter::stackElementSize();
 429 
 430     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
 431       *_int_args++ = from_obj;
 432       _num_int_args++;
 433     } else {
 434       *_to++ = from_obj;
 435     }
 436   }
 437 
 438   virtual void pass_object()
 439   {
 440     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
 441     debug_only(verify_tag(frame::TagReference));
 442     _from -= Interpreter::stackElementSize();
 443 
 444     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
 445       *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
 446       _num_int_args++;
 447     } else {
 448       *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
 449     }
 450   }
 451 
 452   virtual void pass_float()
 453   {
 454     jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
 455     debug_only(verify_tag(frame::TagValue));
 456     _from -= Interpreter::stackElementSize();
 457 
 458     if (_num_fp_args < Argument::n_float_register_parameters_c) {
 459       *_fp_args++ = from_obj;
 460       _num_fp_args++;
 461     } else {
 462       *_to++ = from_obj;
 463     }
 464   }
 465 
 466   virtual void pass_double()
 467   {
 468     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 469     _from -= 2*Interpreter::stackElementSize();
 470 
 471     if (_num_fp_args < Argument::n_float_register_parameters_c) {
 472       *_fp_args++ = from_obj;
 473       *_fp_identifiers |= (1 << _num_fp_args); // mark as double
 474       _num_fp_args++;
 475     } else {
 476       *_to++ = from_obj;
 477     }
 478   }
 479 
 480  public:
 481   SlowSignatureHandler(methodHandle method, address from, intptr_t* to) 
 482     : NativeSignatureIterator(method)
 483   {
 484     _from = from;
 485     _to   = to;
 486 
 487     _int_args = to - (method->is_static() ? 14 : 15);
 488     _fp_args =  to - 9;
 489     _fp_identifiers = to - 10;
 490     *(int*) _fp_identifiers = 0;
 491     _num_int_args = (method->is_static() ? 1 : 0);
 492     _num_fp_args = 0;
 493   }
 494 };
 495 #endif
 496 
 497 
 498 IRT_ENTRY(address, 
 499           InterpreterRuntime::slow_signature_handler(JavaThread* thread,
 500                                                      methodOopDesc* method,
 501                                                      intptr_t* from,
 502                                                      intptr_t* to))
 503   methodHandle m(thread, (methodOop)method);
 504   assert(m->is_native(), "sanity check");
 505 
 506   // handle arguments
 507   SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
 508 
 509   // return result handler
 510   return Interpreter::result_handler(m->result_type());
 511 IRT_END