5782 // memory is used to define read/write location for load/store
5783 // instruction defs. we can turn a memory op into an Address
5784
5785 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5786 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5787
5788 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5789 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5790
5791 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5792 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5793
5794 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5795 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5796
5797 // All of the memory operands. For the pipeline description.
5798 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5799 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5800 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5801
5802
5803 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5804 // operations. it allows the src to be either an iRegI or a (ConvL2I
5805 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5806 // can be elided because the 32-bit instruction will just employ the
5807 // lower 32 bits anyway.
5808 //
5809 // n.b. this does not elide all L2I conversions. if the truncated
5810 // value is consumed by more than one operation then the ConvL2I
5811 // cannot be bundled into the consuming nodes so an l2i gets planted
5812 // (actually a movw $dst $src) and the downstream instructions consume
5813 // the result of the l2i as an iRegI input. That's a shame since the
5814 // movw is actually redundant but its not too costly.
5815
5816 opclass iRegIorL2I(iRegI, iRegL2I);
5817 opclass iRegPorL2P(iRegP, iRegL2P);
5818
5819 //----------PIPELINE-----------------------------------------------------------
5820 // Rules which define the behavior of the target architectures pipeline.
5821
6719
6720 ins_encode(aarch64_enc_ldr(dst, mem));
6721
6722 ins_pipe(iload_reg_mem);
6723 %}
6724
6725 // Load Narrow Klass Pointer
6726 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6727 %{
6728 match(Set dst (LoadNKlass mem));
6729 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6730
6731 ins_cost(4 * INSN_COST);
6732 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6733
6734 ins_encode(aarch64_enc_ldrw(dst, mem));
6735
6736 ins_pipe(iload_reg_mem);
6737 %}
6738
6739 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6740 %{
6741 match(Set dst (LoadNKlass mem));
6742 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6743
6744 ins_cost(4 * INSN_COST);
6745 format %{
6746 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6747 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6748 %}
6749 ins_encode %{
6750 // inlined aarch64_enc_ldrw
6751 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6752 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6753 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6754 %}
6755 ins_pipe(iload_reg_mem);
6756 %}
6757
6758 // Load Float
6759 instruct loadF(vRegF dst, memory4 mem)
6760 %{
6761 match(Set dst (LoadF mem));
6762 predicate(!needs_acquiring_load(n));
6763
6764 ins_cost(4 * INSN_COST);
6765 format %{ "ldrs $dst, $mem\t# float" %}
6766
6767 ins_encode( aarch64_enc_ldrs(dst, mem) );
6768
6769 ins_pipe(pipe_class_memory);
6770 %}
6771
6772 // Load Double
6773 instruct loadD(vRegD dst, memory8 mem)
|
5782 // memory is used to define read/write location for load/store
5783 // instruction defs. we can turn a memory op into an Address
5784
5785 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5786 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5787
5788 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5789 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5790
5791 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5792 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5793
5794 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5795 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5796
5797 // All of the memory operands. For the pipeline description.
5798 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5799 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5800 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5801
5802 opclass memory_noindex(indirect,
5803 indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5804 indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5805
5806 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5807 // operations. it allows the src to be either an iRegI or a (ConvL2I
5808 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5809 // can be elided because the 32-bit instruction will just employ the
5810 // lower 32 bits anyway.
5811 //
5812 // n.b. this does not elide all L2I conversions. if the truncated
5813 // value is consumed by more than one operation then the ConvL2I
5814 // cannot be bundled into the consuming nodes so an l2i gets planted
5815 // (actually a movw $dst $src) and the downstream instructions consume
5816 // the result of the l2i as an iRegI input. That's a shame since the
5817 // movw is actually redundant but its not too costly.
5818
5819 opclass iRegIorL2I(iRegI, iRegL2I);
5820 opclass iRegPorL2P(iRegP, iRegL2P);
5821
5822 //----------PIPELINE-----------------------------------------------------------
5823 // Rules which define the behavior of the target architectures pipeline.
5824
6722
6723 ins_encode(aarch64_enc_ldr(dst, mem));
6724
6725 ins_pipe(iload_reg_mem);
6726 %}
6727
6728 // Load Narrow Klass Pointer
6729 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6730 %{
6731 match(Set dst (LoadNKlass mem));
6732 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6733
6734 ins_cost(4 * INSN_COST);
6735 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6736
6737 ins_encode(aarch64_enc_ldrw(dst, mem));
6738
6739 ins_pipe(iload_reg_mem);
6740 %}
6741
6742 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem)
6743 %{
6744 match(Set dst (LoadNKlass mem));
6745 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6746
6747 ins_cost(4 * INSN_COST);
6748 format %{
6749 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6750 "lsrw $dst, $dst, markWord::klass_shift"
6751 %}
6752 ins_encode %{
6753 assert($mem$$index$$Register == noreg, "must not have indexed address");
6754 // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
6755 // obj-start, so that we can load from the object's mark-word instead.
6756 __ ldrw($dst$$Register, Address($mem$$base$$Register, $mem$$disp - Type::klass_offset()));
6757 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift);
6758 %}
6759 ins_pipe(iload_reg_mem);
6760 %}
6761
6762 // Load Float
6763 instruct loadF(vRegF dst, memory4 mem)
6764 %{
6765 match(Set dst (LoadF mem));
6766 predicate(!needs_acquiring_load(n));
6767
6768 ins_cost(4 * INSN_COST);
6769 format %{ "ldrs $dst, $mem\t# float" %}
6770
6771 ins_encode( aarch64_enc_ldrs(dst, mem) );
6772
6773 ins_pipe(pipe_class_memory);
6774 %}
6775
6776 // Load Double
6777 instruct loadD(vRegD dst, memory8 mem)
|