421 source_hpp %{
422
423 #include "peephole_x86_64.hpp"
424
425 bool castLL_is_imm32(const Node* n);
426
427 %}
428
429 source %{
430
431 bool castLL_is_imm32(const Node* n) {
432 assert(n->is_CastLL(), "must be a CastLL");
433 const TypeLong* t = n->bottom_type()->is_long();
434 return (t->_lo == min_jlong || Assembler::is_simm32(t->_lo)) && (t->_hi == max_jlong || Assembler::is_simm32(t->_hi));
435 }
436
437 %}
438
439 // Register masks
440 source_hpp %{
441
442 extern RegMask _ANY_REG_mask;
443 extern RegMask _PTR_REG_mask;
444 extern RegMask _PTR_REG_NO_RBP_mask;
445 extern RegMask _PTR_NO_RAX_REG_mask;
446 extern RegMask _PTR_NO_RAX_RBX_REG_mask;
447 extern RegMask _LONG_REG_mask;
448 extern RegMask _LONG_NO_RAX_RDX_REG_mask;
449 extern RegMask _LONG_NO_RCX_REG_mask;
450 extern RegMask _LONG_NO_RBP_R13_REG_mask;
451 extern RegMask _INT_REG_mask;
452 extern RegMask _INT_NO_RAX_RDX_REG_mask;
453 extern RegMask _INT_NO_RCX_REG_mask;
454 extern RegMask _INT_NO_RBP_R13_REG_mask;
455 extern RegMask _FLOAT_REG_mask;
456
457 extern RegMask _STACK_OR_PTR_REG_mask;
458 extern RegMask _STACK_OR_LONG_REG_mask;
459 extern RegMask _STACK_OR_INT_REG_mask;
460
461 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; }
834 st->print("\n\t");
835 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t");
836 st->print("\n\t");
837 st->print("je fast_entry\t");
838 st->print("\n\t");
839 st->print("call #nmethod_entry_barrier_stub\t");
840 st->print("\n\tfast_entry:");
841 }
842 st->cr();
843 }
844 #endif
845
846 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
847 Compile* C = ra_->C;
848
849 int framesize = C->output()->frame_size_in_bytes();
850 int bangsize = C->output()->bang_size_in_bytes();
851
852 if (C->clinit_barrier_on_entry()) {
853 assert(VM_Version::supports_fast_class_init_checks(), "sanity");
854 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
855
856 Label L_skip_barrier;
857 Register klass = rscratch1;
858
859 __ mov_metadata(klass, C->method()->holder()->constant_encoding());
860 __ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/);
861
862 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
863
864 __ bind(L_skip_barrier);
865 }
866
867 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr);
868
869 C->output()->set_frame_complete(__ offset());
870
871 if (C->has_mach_constant_base_node()) {
872 // NOTE: We set the table base offset here because users might be
873 // emitted before MachConstantBaseNode.
874 ConstantTable& constant_table = C->output()->constant_table();
2469 // Constant for byte-wide masking
2470 operand immL_255()
2471 %{
2472 predicate(n->get_long() == 255);
2473 match(ConL);
2474
2475 format %{ %}
2476 interface(CONST_INTER);
2477 %}
2478
2479 // Constant for short-wide masking
2480 operand immL_65535()
2481 %{
2482 predicate(n->get_long() == 65535);
2483 match(ConL);
2484
2485 format %{ %}
2486 interface(CONST_INTER);
2487 %}
2488
2489 operand kReg()
2490 %{
2491 constraint(ALLOC_IN_RC(vectmask_reg));
2492 match(RegVectMask);
2493 format %{%}
2494 interface(REG_INTER);
2495 %}
2496
2497 // Register Operands
2498 // Integer Register
2499 operand rRegI()
2500 %{
2501 constraint(ALLOC_IN_RC(int_reg));
2502 match(RegI);
2503
2504 match(rax_RegI);
2505 match(rbx_RegI);
2506 match(rcx_RegI);
2507 match(rdx_RegI);
2508 match(rdi_RegI);
4429 format %{ "movlpd $dst, $mem\t# double" %}
4430 ins_encode %{
4431 __ movdbl($dst$$XMMRegister, $mem$$Address);
4432 %}
4433 ins_pipe(pipe_slow); // XXX
4434 %}
4435
4436 instruct loadD(regD dst, memory mem)
4437 %{
4438 predicate(UseXmmLoadAndClearUpper);
4439 match(Set dst (LoadD mem));
4440
4441 ins_cost(145); // XXX
4442 format %{ "movsd $dst, $mem\t# double" %}
4443 ins_encode %{
4444 __ movdbl($dst$$XMMRegister, $mem$$Address);
4445 %}
4446 ins_pipe(pipe_slow); // XXX
4447 %}
4448
4449 // max = java.lang.Math.max(float a, float b)
4450 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
4451 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
4452 match(Set dst (MaxF a b));
4453 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
4454 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
4455 ins_encode %{
4456 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit);
4457 %}
4458 ins_pipe( pipe_slow );
4459 %}
4460
4461 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{
4462 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
4463 match(Set dst (MaxF a b));
4464 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
4465
4466 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %}
4467 ins_encode %{
4468 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register,
|
421 source_hpp %{
422
423 #include "peephole_x86_64.hpp"
424
425 bool castLL_is_imm32(const Node* n);
426
427 %}
428
429 source %{
430
431 bool castLL_is_imm32(const Node* n) {
432 assert(n->is_CastLL(), "must be a CastLL");
433 const TypeLong* t = n->bottom_type()->is_long();
434 return (t->_lo == min_jlong || Assembler::is_simm32(t->_lo)) && (t->_hi == max_jlong || Assembler::is_simm32(t->_hi));
435 }
436
437 %}
438
439 // Register masks
440 source_hpp %{
441 extern RegMask _ANY_REG_mask;
442 extern RegMask _PTR_REG_mask;
443 extern RegMask _PTR_REG_NO_RBP_mask;
444 extern RegMask _PTR_NO_RAX_REG_mask;
445 extern RegMask _PTR_NO_RAX_RBX_REG_mask;
446 extern RegMask _LONG_REG_mask;
447 extern RegMask _LONG_NO_RAX_RDX_REG_mask;
448 extern RegMask _LONG_NO_RCX_REG_mask;
449 extern RegMask _LONG_NO_RBP_R13_REG_mask;
450 extern RegMask _INT_REG_mask;
451 extern RegMask _INT_NO_RAX_RDX_REG_mask;
452 extern RegMask _INT_NO_RCX_REG_mask;
453 extern RegMask _INT_NO_RBP_R13_REG_mask;
454 extern RegMask _FLOAT_REG_mask;
455
456 extern RegMask _STACK_OR_PTR_REG_mask;
457 extern RegMask _STACK_OR_LONG_REG_mask;
458 extern RegMask _STACK_OR_INT_REG_mask;
459
460 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; }
833 st->print("\n\t");
834 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t");
835 st->print("\n\t");
836 st->print("je fast_entry\t");
837 st->print("\n\t");
838 st->print("call #nmethod_entry_barrier_stub\t");
839 st->print("\n\tfast_entry:");
840 }
841 st->cr();
842 }
843 #endif
844
845 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
846 Compile* C = ra_->C;
847
848 int framesize = C->output()->frame_size_in_bytes();
849 int bangsize = C->output()->bang_size_in_bytes();
850
851 if (C->clinit_barrier_on_entry()) {
852 assert(VM_Version::supports_fast_class_init_checks(), "sanity");
853 assert(!C->method()->holder()->is_not_initialized() || C->do_clinit_barriers(), "initialization should have been started");
854
855 Label L_skip_barrier;
856 Register klass = rscratch1;
857
858 __ mov_metadata(klass, C->method()->holder()->constant_encoding());
859 __ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/);
860
861 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
862
863 __ bind(L_skip_barrier);
864 }
865
866 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr);
867
868 C->output()->set_frame_complete(__ offset());
869
870 if (C->has_mach_constant_base_node()) {
871 // NOTE: We set the table base offset here because users might be
872 // emitted before MachConstantBaseNode.
873 ConstantTable& constant_table = C->output()->constant_table();
2468 // Constant for byte-wide masking
2469 operand immL_255()
2470 %{
2471 predicate(n->get_long() == 255);
2472 match(ConL);
2473
2474 format %{ %}
2475 interface(CONST_INTER);
2476 %}
2477
2478 // Constant for short-wide masking
2479 operand immL_65535()
2480 %{
2481 predicate(n->get_long() == 65535);
2482 match(ConL);
2483
2484 format %{ %}
2485 interface(CONST_INTER);
2486 %}
2487
2488 // AOT Runtime Constants Address
2489 operand immAOTRuntimeConstantsAddress()
2490 %{
2491 // Check if the address is in the range of AOT Runtime Constants
2492 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
2493 match(ConP);
2494
2495 op_cost(0);
2496 format %{ %}
2497 interface(CONST_INTER);
2498 %}
2499
2500 operand kReg()
2501 %{
2502 constraint(ALLOC_IN_RC(vectmask_reg));
2503 match(RegVectMask);
2504 format %{%}
2505 interface(REG_INTER);
2506 %}
2507
2508 // Register Operands
2509 // Integer Register
2510 operand rRegI()
2511 %{
2512 constraint(ALLOC_IN_RC(int_reg));
2513 match(RegI);
2514
2515 match(rax_RegI);
2516 match(rbx_RegI);
2517 match(rcx_RegI);
2518 match(rdx_RegI);
2519 match(rdi_RegI);
4440 format %{ "movlpd $dst, $mem\t# double" %}
4441 ins_encode %{
4442 __ movdbl($dst$$XMMRegister, $mem$$Address);
4443 %}
4444 ins_pipe(pipe_slow); // XXX
4445 %}
4446
4447 instruct loadD(regD dst, memory mem)
4448 %{
4449 predicate(UseXmmLoadAndClearUpper);
4450 match(Set dst (LoadD mem));
4451
4452 ins_cost(145); // XXX
4453 format %{ "movsd $dst, $mem\t# double" %}
4454 ins_encode %{
4455 __ movdbl($dst$$XMMRegister, $mem$$Address);
4456 %}
4457 ins_pipe(pipe_slow); // XXX
4458 %}
4459
4460 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con)
4461 %{
4462 match(Set dst con);
4463
4464 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %}
4465
4466 ins_encode %{
4467 __ load_aotrc_address($dst$$Register, (address)$con$$constant);
4468 %}
4469
4470 ins_pipe(ialu_reg_fat);
4471 %}
4472
4473 // max = java.lang.Math.max(float a, float b)
4474 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
4475 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
4476 match(Set dst (MaxF a b));
4477 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
4478 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
4479 ins_encode %{
4480 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit);
4481 %}
4482 ins_pipe( pipe_slow );
4483 %}
4484
4485 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{
4486 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
4487 match(Set dst (MaxF a b));
4488 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
4489
4490 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %}
4491 ins_encode %{
4492 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register,
|