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