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