5842 // memory is used to define read/write location for load/store
5843 // instruction defs. we can turn a memory op into an Address
5844
5845 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5846 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5847
5848 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5849 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5850
5851 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5852 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5853
5854 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5855 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5856
5857 // All of the memory operands. For the pipeline description.
5858 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5859 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5860 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5861
5862
5863 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5864 // operations. it allows the src to be either an iRegI or a (ConvL2I
5865 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5866 // can be elided because the 32-bit instruction will just employ the
5867 // lower 32 bits anyway.
5868 //
5869 // n.b. this does not elide all L2I conversions. if the truncated
5870 // value is consumed by more than one operation then the ConvL2I
5871 // cannot be bundled into the consuming nodes so an l2i gets planted
5872 // (actually a movw $dst $src) and the downstream instructions consume
5873 // the result of the l2i as an iRegI input. That's a shame since the
5874 // movw is actually redundant but its not too costly.
5875
5876 opclass iRegIorL2I(iRegI, iRegL2I);
5877 opclass iRegPorL2P(iRegP, iRegL2P);
5878
5879 //----------PIPELINE-----------------------------------------------------------
5880 // Rules which define the behavior of the target architectures pipeline.
5881
6776
6777 ins_encode(aarch64_enc_ldr(dst, mem));
6778
6779 ins_pipe(iload_reg_mem);
6780 %}
6781
6782 // Load Narrow Klass Pointer
6783 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6784 %{
6785 match(Set dst (LoadNKlass mem));
6786 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6787
6788 ins_cost(4 * INSN_COST);
6789 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6790
6791 ins_encode(aarch64_enc_ldrw(dst, mem));
6792
6793 ins_pipe(iload_reg_mem);
6794 %}
6795
6796 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6797 %{
6798 match(Set dst (LoadNKlass mem));
6799 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6800
6801 ins_cost(4 * INSN_COST);
6802 format %{
6803 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6804 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6805 %}
6806 ins_encode %{
6807 // inlined aarch64_enc_ldrw
6808 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6809 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6810 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6811 %}
6812 ins_pipe(iload_reg_mem);
6813 %}
6814
6815 // Load Float
6816 instruct loadF(vRegF dst, memory4 mem)
6817 %{
6818 match(Set dst (LoadF mem));
6819 predicate(!needs_acquiring_load(n));
6820
6821 ins_cost(4 * INSN_COST);
6822 format %{ "ldrs $dst, $mem\t# float" %}
6823
6824 ins_encode( aarch64_enc_ldrs(dst, mem) );
6825
6826 ins_pipe(pipe_class_memory);
6827 %}
6828
6829 // Load Double
6830 instruct loadD(vRegD dst, memory8 mem)
|
5842 // memory is used to define read/write location for load/store
5843 // instruction defs. we can turn a memory op into an Address
5844
5845 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5846 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5847
5848 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5849 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5850
5851 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5852 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5853
5854 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5855 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5856
5857 // All of the memory operands. For the pipeline description.
5858 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5859 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5860 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5861
5862 opclass memory_noindex(indirect,
5863 indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5864 indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5865
5866 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5867 // operations. it allows the src to be either an iRegI or a (ConvL2I
5868 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5869 // can be elided because the 32-bit instruction will just employ the
5870 // lower 32 bits anyway.
5871 //
5872 // n.b. this does not elide all L2I conversions. if the truncated
5873 // value is consumed by more than one operation then the ConvL2I
5874 // cannot be bundled into the consuming nodes so an l2i gets planted
5875 // (actually a movw $dst $src) and the downstream instructions consume
5876 // the result of the l2i as an iRegI input. That's a shame since the
5877 // movw is actually redundant but its not too costly.
5878
5879 opclass iRegIorL2I(iRegI, iRegL2I);
5880 opclass iRegPorL2P(iRegP, iRegL2P);
5881
5882 //----------PIPELINE-----------------------------------------------------------
5883 // Rules which define the behavior of the target architectures pipeline.
5884
6779
6780 ins_encode(aarch64_enc_ldr(dst, mem));
6781
6782 ins_pipe(iload_reg_mem);
6783 %}
6784
6785 // Load Narrow Klass Pointer
6786 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6787 %{
6788 match(Set dst (LoadNKlass mem));
6789 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6790
6791 ins_cost(4 * INSN_COST);
6792 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6793
6794 ins_encode(aarch64_enc_ldrw(dst, mem));
6795
6796 ins_pipe(iload_reg_mem);
6797 %}
6798
6799 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem)
6800 %{
6801 match(Set dst (LoadNKlass mem));
6802 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6803
6804 ins_cost(4 * INSN_COST);
6805 format %{
6806 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6807 "lsrw $dst, $dst, markWord::klass_shift"
6808 %}
6809 ins_encode %{
6810 assert($mem$$index$$Register == noreg, "must not have indexed address");
6811 // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
6812 // obj-start, so that we can load from the object's mark-word instead.
6813 __ ldrw($dst$$Register, Address($mem$$base$$Register, $mem$$disp - Type::klass_offset()));
6814 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift);
6815 %}
6816 ins_pipe(iload_reg_mem);
6817 %}
6818
6819 // Load Float
6820 instruct loadF(vRegF dst, memory4 mem)
6821 %{
6822 match(Set dst (LoadF mem));
6823 predicate(!needs_acquiring_load(n));
6824
6825 ins_cost(4 * INSN_COST);
6826 format %{ "ldrs $dst, $mem\t# float" %}
6827
6828 ins_encode( aarch64_enc_ldrs(dst, mem) );
6829
6830 ins_pipe(pipe_class_memory);
6831 %}
6832
6833 // Load Double
6834 instruct loadD(vRegD dst, memory8 mem)
|