5889 // memory is used to define read/write location for load/store
5890 // instruction defs. we can turn a memory op into an Address
5891
5892 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5893 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5894
5895 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5896 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5897
5898 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5899 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5900
5901 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5902 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5903
5904 // All of the memory operands. For the pipeline description.
5905 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5906 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5907 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5908
5909
5910 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5911 // operations. it allows the src to be either an iRegI or a (ConvL2I
5912 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5913 // can be elided because the 32-bit instruction will just employ the
5914 // lower 32 bits anyway.
5915 //
5916 // n.b. this does not elide all L2I conversions. if the truncated
5917 // value is consumed by more than one operation then the ConvL2I
5918 // cannot be bundled into the consuming nodes so an l2i gets planted
5919 // (actually a movw $dst $src) and the downstream instructions consume
5920 // the result of the l2i as an iRegI input. That's a shame since the
5921 // movw is actually redundant but its not too costly.
5922
5923 opclass iRegIorL2I(iRegI, iRegL2I);
5924 opclass iRegPorL2P(iRegP, iRegL2P);
5925
5926 //----------PIPELINE-----------------------------------------------------------
5927 // Rules which define the behavior of the target architectures pipeline.
5928
6823
6824 ins_encode(aarch64_enc_ldr(dst, mem));
6825
6826 ins_pipe(iload_reg_mem);
6827 %}
6828
6829 // Load Narrow Klass Pointer
6830 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6831 %{
6832 match(Set dst (LoadNKlass mem));
6833 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6834
6835 ins_cost(4 * INSN_COST);
6836 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6837
6838 ins_encode(aarch64_enc_ldrw(dst, mem));
6839
6840 ins_pipe(iload_reg_mem);
6841 %}
6842
6843 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6844 %{
6845 match(Set dst (LoadNKlass mem));
6846 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6847
6848 ins_cost(4 * INSN_COST);
6849 format %{
6850 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6851 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6852 %}
6853 ins_encode %{
6854 // inlined aarch64_enc_ldrw
6855 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6856 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6857 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6858 %}
6859 ins_pipe(iload_reg_mem);
6860 %}
6861
6862 // Load Float
6863 instruct loadF(vRegF dst, memory4 mem)
6864 %{
6865 match(Set dst (LoadF mem));
6866 predicate(!needs_acquiring_load(n));
6867
6868 ins_cost(4 * INSN_COST);
6869 format %{ "ldrs $dst, $mem\t# float" %}
6870
6871 ins_encode( aarch64_enc_ldrs(dst, mem) );
6872
6873 ins_pipe(pipe_class_memory);
6874 %}
6875
6876 // Load Double
6877 instruct loadD(vRegD dst, memory8 mem)
|
5889 // memory is used to define read/write location for load/store
5890 // instruction defs. we can turn a memory op into an Address
5891
5892 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5893 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5894
5895 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5896 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5897
5898 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5899 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5900
5901 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5902 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5903
5904 // All of the memory operands. For the pipeline description.
5905 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5906 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5907 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5908
5909 opclass memory_noindex(indirect,
5910 indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5911 indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5912
5913 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5914 // operations. it allows the src to be either an iRegI or a (ConvL2I
5915 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5916 // can be elided because the 32-bit instruction will just employ the
5917 // lower 32 bits anyway.
5918 //
5919 // n.b. this does not elide all L2I conversions. if the truncated
5920 // value is consumed by more than one operation then the ConvL2I
5921 // cannot be bundled into the consuming nodes so an l2i gets planted
5922 // (actually a movw $dst $src) and the downstream instructions consume
5923 // the result of the l2i as an iRegI input. That's a shame since the
5924 // movw is actually redundant but its not too costly.
5925
5926 opclass iRegIorL2I(iRegI, iRegL2I);
5927 opclass iRegPorL2P(iRegP, iRegL2P);
5928
5929 //----------PIPELINE-----------------------------------------------------------
5930 // Rules which define the behavior of the target architectures pipeline.
5931
6826
6827 ins_encode(aarch64_enc_ldr(dst, mem));
6828
6829 ins_pipe(iload_reg_mem);
6830 %}
6831
6832 // Load Narrow Klass Pointer
6833 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6834 %{
6835 match(Set dst (LoadNKlass mem));
6836 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6837
6838 ins_cost(4 * INSN_COST);
6839 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6840
6841 ins_encode(aarch64_enc_ldrw(dst, mem));
6842
6843 ins_pipe(iload_reg_mem);
6844 %}
6845
6846 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem)
6847 %{
6848 match(Set dst (LoadNKlass mem));
6849 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6850
6851 ins_cost(4 * INSN_COST);
6852 format %{
6853 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6854 "lsrw $dst, $dst, markWord::klass_shift"
6855 %}
6856 ins_encode %{
6857 assert($mem$$index$$Register == noreg, "must not have indexed address");
6858 // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
6859 // obj-start, so that we can load from the object's mark-word instead.
6860 __ ldrw($dst$$Register, Address($mem$$base$$Register, $mem$$disp - Type::klass_offset()));
6861 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift);
6862 %}
6863 ins_pipe(iload_reg_mem);
6864 %}
6865
6866 // Load Float
6867 instruct loadF(vRegF dst, memory4 mem)
6868 %{
6869 match(Set dst (LoadF mem));
6870 predicate(!needs_acquiring_load(n));
6871
6872 ins_cost(4 * INSN_COST);
6873 format %{ "ldrs $dst, $mem\t# float" %}
6874
6875 ins_encode( aarch64_enc_ldrs(dst, mem) );
6876
6877 ins_pipe(pipe_class_memory);
6878 %}
6879
6880 // Load Double
6881 instruct loadD(vRegD dst, memory8 mem)
|