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