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