5754 // memory is used to define read/write location for load/store
5755 // instruction defs. we can turn a memory op into an Address
5756
5757 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5758 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5759
5760 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5761 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5762
5763 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5764 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5765
5766 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5767 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5768
5769 // All of the memory operands. For the pipeline description.
5770 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5771 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5772 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5773
5774
5775 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5776 // operations. it allows the src to be either an iRegI or a (ConvL2I
5777 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5778 // can be elided because the 32-bit instruction will just employ the
5779 // lower 32 bits anyway.
5780 //
5781 // n.b. this does not elide all L2I conversions. if the truncated
5782 // value is consumed by more than one operation then the ConvL2I
5783 // cannot be bundled into the consuming nodes so an l2i gets planted
5784 // (actually a movw $dst $src) and the downstream instructions consume
5785 // the result of the l2i as an iRegI input. That's a shame since the
5786 // movw is actually redundant but its not too costly.
5787
5788 opclass iRegIorL2I(iRegI, iRegL2I);
5789 opclass iRegPorL2P(iRegP, iRegL2P);
5790
5791 //----------PIPELINE-----------------------------------------------------------
5792 // Rules which define the behavior of the target architectures pipeline.
5793
6691
6692 ins_encode(aarch64_enc_ldr(dst, mem));
6693
6694 ins_pipe(iload_reg_mem);
6695 %}
6696
6697 // Load Narrow Klass Pointer
6698 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6699 %{
6700 match(Set dst (LoadNKlass mem));
6701 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6702
6703 ins_cost(4 * INSN_COST);
6704 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6705
6706 ins_encode(aarch64_enc_ldrw(dst, mem));
6707
6708 ins_pipe(iload_reg_mem);
6709 %}
6710
6711 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6712 %{
6713 match(Set dst (LoadNKlass mem));
6714 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6715
6716 ins_cost(4 * INSN_COST);
6717 format %{
6718 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6719 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6720 %}
6721 ins_encode %{
6722 // inlined aarch64_enc_ldrw
6723 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6724 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6725 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6726 %}
6727 ins_pipe(iload_reg_mem);
6728 %}
6729
6730 // Load Float
6731 instruct loadF(vRegF dst, memory4 mem)
6732 %{
6733 match(Set dst (LoadF mem));
6734 predicate(!needs_acquiring_load(n));
6735
6736 ins_cost(4 * INSN_COST);
6737 format %{ "ldrs $dst, $mem\t# float" %}
6738
6739 ins_encode( aarch64_enc_ldrs(dst, mem) );
6740
6741 ins_pipe(pipe_class_memory);
6742 %}
6743
6744 // Load Double
6745 instruct loadD(vRegD dst, memory8 mem)
|
5754 // memory is used to define read/write location for load/store
5755 // instruction defs. we can turn a memory op into an Address
5756
5757 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5758 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5759
5760 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5761 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5762
5763 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5764 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5765
5766 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5767 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5768
5769 // All of the memory operands. For the pipeline description.
5770 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5771 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5772 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5773
5774 opclass memory_noindex(indirect,
5775 indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5776 indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5777
5778 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5779 // operations. it allows the src to be either an iRegI or a (ConvL2I
5780 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5781 // can be elided because the 32-bit instruction will just employ the
5782 // lower 32 bits anyway.
5783 //
5784 // n.b. this does not elide all L2I conversions. if the truncated
5785 // value is consumed by more than one operation then the ConvL2I
5786 // cannot be bundled into the consuming nodes so an l2i gets planted
5787 // (actually a movw $dst $src) and the downstream instructions consume
5788 // the result of the l2i as an iRegI input. That's a shame since the
5789 // movw is actually redundant but its not too costly.
5790
5791 opclass iRegIorL2I(iRegI, iRegL2I);
5792 opclass iRegPorL2P(iRegP, iRegL2P);
5793
5794 //----------PIPELINE-----------------------------------------------------------
5795 // Rules which define the behavior of the target architectures pipeline.
5796
6694
6695 ins_encode(aarch64_enc_ldr(dst, mem));
6696
6697 ins_pipe(iload_reg_mem);
6698 %}
6699
6700 // Load Narrow Klass Pointer
6701 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6702 %{
6703 match(Set dst (LoadNKlass mem));
6704 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6705
6706 ins_cost(4 * INSN_COST);
6707 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6708
6709 ins_encode(aarch64_enc_ldrw(dst, mem));
6710
6711 ins_pipe(iload_reg_mem);
6712 %}
6713
6714 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem)
6715 %{
6716 match(Set dst (LoadNKlass mem));
6717 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6718
6719 ins_cost(4 * INSN_COST);
6720 format %{
6721 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6722 "lsrw $dst, $dst, markWord::klass_shift"
6723 %}
6724 ins_encode %{
6725 assert($mem$$index$$Register == noreg, "must not have indexed address");
6726 // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
6727 // obj-start, so that we can load from the object's mark-word instead.
6728 __ ldrw($dst$$Register, Address($mem$$base$$Register, $mem$$disp - Type::klass_offset()));
6729 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift);
6730 %}
6731 ins_pipe(iload_reg_mem);
6732 %}
6733
6734 // Load Float
6735 instruct loadF(vRegF dst, memory4 mem)
6736 %{
6737 match(Set dst (LoadF mem));
6738 predicate(!needs_acquiring_load(n));
6739
6740 ins_cost(4 * INSN_COST);
6741 format %{ "ldrs $dst, $mem\t# float" %}
6742
6743 ins_encode( aarch64_enc_ldrs(dst, mem) );
6744
6745 ins_pipe(pipe_class_memory);
6746 %}
6747
6748 // Load Double
6749 instruct loadD(vRegD dst, memory8 mem)
|