comparison src/cpu/sparc/vm/sparc.ad @ 1396:d7f654633cfe

6946040: add intrinsic for short and char reverseBytes Reviewed-by: never, twisti Contributed-by: Hiroshi Yamauchi <yamauchi@google.com>
author never
date Mon, 26 Apr 2010 11:27:21 -0700
parents 9e321dcfa5b7
children c18cbe5936b8 110501f54a99
comparison
equal deleted inserted replaced
1385:bc32f286fae0 1396:d7f654633cfe
921 } 921 }
922 } 922 }
923 #endif 923 #endif
924 } 924 }
925 925
926 void emit_form3_mem_reg_asi(CodeBuffer &cbuf, const MachNode* n, int primary, int tertiary,
927 int src1_enc, int disp32, int src2_enc, int dst_enc, int asi) {
928
929 uint instr;
930 instr = (Assembler::ldst_op << 30)
931 | (dst_enc << 25)
932 | (primary << 19)
933 | (src1_enc << 14);
934
935 int disp = disp32;
936 int index = src2_enc;
937
938 if (src1_enc == R_SP_enc || src1_enc == R_FP_enc)
939 disp += STACK_BIAS;
940
941 // We should have a compiler bailout here rather than a guarantee.
942 // Better yet would be some mechanism to handle variable-size matches correctly.
943 guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" );
944
945 if( disp != 0 ) {
946 // use reg-reg form
947 // set src2=R_O7 contains offset
948 index = R_O7_enc;
949 emit3_simm13( cbuf, Assembler::arith_op, index, Assembler::or_op3, 0, disp);
950 }
951 instr |= (asi << 5);
952 instr |= index;
953 uint *code = (uint*)cbuf.code_end();
954 *code = instr;
955 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord);
956 }
957
958 void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) { 926 void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) {
959 // The method which records debug information at every safepoint 927 // The method which records debug information at every safepoint
960 // expects the call to be the first instruction in the snippet as 928 // expects the call to be the first instruction in the snippet as
961 // it creates a PcDesc structure which tracks the offset of a call 929 // it creates a PcDesc structure which tracks the offset of a call
962 // from the start of the codeBlob. This offset is computed as 930 // from the start of the codeBlob. This offset is computed as
1950 %} 1918 %}
1951 1919
1952 enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{ 1920 enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
1953 emit_form3_mem_reg(cbuf, this, $primary, -1, 1921 emit_form3_mem_reg(cbuf, this, $primary, -1,
1954 $mem$$base, $mem$$disp, $mem$$index, $dst$$reg); 1922 $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
1955 %}
1956
1957 enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
1958 emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
1959 $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
1960 %} 1923 %}
1961 1924
1962 enc_class form3_mem_prefetch_read( memory mem ) %{ 1925 enc_class form3_mem_prefetch_read( memory mem ) %{
1963 emit_form3_mem_reg(cbuf, this, $primary, -1, 1926 emit_form3_mem_reg(cbuf, this, $primary, -1,
1964 $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/); 1927 $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
4309 // Operand Classes are groups of operands that are used to simplify 4272 // Operand Classes are groups of operands that are used to simplify
4310 // instruction definitions by not requiring the AD writer to specify separate 4273 // instruction definitions by not requiring the AD writer to specify separate
4311 // instructions for every form of operand when the instruction accepts 4274 // instructions for every form of operand when the instruction accepts
4312 // multiple operand types with the same basic encoding and format. The classic 4275 // multiple operand types with the same basic encoding and format. The classic
4313 // case of this is memory operands. 4276 // case of this is memory operands.
4314 // Indirect is not included since its use is limited to Compare & Swap
4315 opclass memory( indirect, indOffset13, indIndex ); 4277 opclass memory( indirect, indOffset13, indIndex );
4278 opclass indIndexMemory( indIndex );
4316 4279
4317 //----------PIPELINE----------------------------------------------------------- 4280 //----------PIPELINE-----------------------------------------------------------
4318 pipeline %{ 4281 pipeline %{
4319 4282
4320 //----------ATTRIBUTES--------------------------------------------------------- 4283 //----------ATTRIBUTES---------------------------------------------------------
9664 // ============================================================================ 9627 // ============================================================================
9665 //------------Bytes reverse-------------------------------------------------- 9628 //------------Bytes reverse--------------------------------------------------
9666 9629
9667 instruct bytes_reverse_int(iRegI dst, stackSlotI src) %{ 9630 instruct bytes_reverse_int(iRegI dst, stackSlotI src) %{
9668 match(Set dst (ReverseBytesI src)); 9631 match(Set dst (ReverseBytesI src));
9669 effect(DEF dst, USE src);
9670 9632
9671 // Op cost is artificially doubled to make sure that load or store 9633 // Op cost is artificially doubled to make sure that load or store
9672 // instructions are preferred over this one which requires a spill 9634 // instructions are preferred over this one which requires a spill
9673 // onto a stack slot. 9635 // onto a stack slot.
9674 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); 9636 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST);
9675 size(8);
9676 format %{ "LDUWA $src, $dst\t!asi=primary_little" %} 9637 format %{ "LDUWA $src, $dst\t!asi=primary_little" %}
9677 opcode(Assembler::lduwa_op3); 9638
9678 ins_encode( form3_mem_reg_little(src, dst) ); 9639 ins_encode %{
9640 __ set($src$$disp + STACK_BIAS, O7);
9641 __ lduwa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9642 %}
9679 ins_pipe( iload_mem ); 9643 ins_pipe( iload_mem );
9680 %} 9644 %}
9681 9645
9682 instruct bytes_reverse_long(iRegL dst, stackSlotL src) %{ 9646 instruct bytes_reverse_long(iRegL dst, stackSlotL src) %{
9683 match(Set dst (ReverseBytesL src)); 9647 match(Set dst (ReverseBytesL src));
9684 effect(DEF dst, USE src);
9685 9648
9686 // Op cost is artificially doubled to make sure that load or store 9649 // Op cost is artificially doubled to make sure that load or store
9687 // instructions are preferred over this one which requires a spill 9650 // instructions are preferred over this one which requires a spill
9688 // onto a stack slot. 9651 // onto a stack slot.
9689 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); 9652 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST);
9690 size(8);
9691 format %{ "LDXA $src, $dst\t!asi=primary_little" %} 9653 format %{ "LDXA $src, $dst\t!asi=primary_little" %}
9692 9654
9693 opcode(Assembler::ldxa_op3); 9655 ins_encode %{
9694 ins_encode( form3_mem_reg_little(src, dst) ); 9656 __ set($src$$disp + STACK_BIAS, O7);
9657 __ ldxa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9658 %}
9695 ins_pipe( iload_mem ); 9659 ins_pipe( iload_mem );
9696 %} 9660 %}
9697 9661
9662 instruct bytes_reverse_unsigned_short(iRegI dst, stackSlotI src) %{
9663 match(Set dst (ReverseBytesUS src));
9664
9665 // Op cost is artificially doubled to make sure that load or store
9666 // instructions are preferred over this one which requires a spill
9667 // onto a stack slot.
9668 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST);
9669 format %{ "LDUHA $src, $dst\t!asi=primary_little\n\t" %}
9670
9671 ins_encode %{
9672 // the value was spilled as an int so bias the load
9673 __ set($src$$disp + STACK_BIAS + 2, O7);
9674 __ lduha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9675 %}
9676 ins_pipe( iload_mem );
9677 %}
9678
9679 instruct bytes_reverse_short(iRegI dst, stackSlotI src) %{
9680 match(Set dst (ReverseBytesS src));
9681
9682 // Op cost is artificially doubled to make sure that load or store
9683 // instructions are preferred over this one which requires a spill
9684 // onto a stack slot.
9685 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST);
9686 format %{ "LDSHA $src, $dst\t!asi=primary_little\n\t" %}
9687
9688 ins_encode %{
9689 // the value was spilled as an int so bias the load
9690 __ set($src$$disp + STACK_BIAS + 2, O7);
9691 __ ldsha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9692 %}
9693 ins_pipe( iload_mem );
9694 %}
9695
9698 // Load Integer reversed byte order 9696 // Load Integer reversed byte order
9699 instruct loadI_reversed(iRegI dst, memory src) %{ 9697 instruct loadI_reversed(iRegI dst, indIndexMemory src) %{
9700 match(Set dst (ReverseBytesI (LoadI src))); 9698 match(Set dst (ReverseBytesI (LoadI src)));
9701 9699
9702 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 9700 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
9703 size(8); 9701 size(4);
9704 format %{ "LDUWA $src, $dst\t!asi=primary_little" %} 9702 format %{ "LDUWA $src, $dst\t!asi=primary_little" %}
9705 9703
9706 opcode(Assembler::lduwa_op3); 9704 ins_encode %{
9707 ins_encode( form3_mem_reg_little( src, dst) ); 9705 __ lduwa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9706 %}
9708 ins_pipe(iload_mem); 9707 ins_pipe(iload_mem);
9709 %} 9708 %}
9710 9709
9711 // Load Long - aligned and reversed 9710 // Load Long - aligned and reversed
9712 instruct loadL_reversed(iRegL dst, memory src) %{ 9711 instruct loadL_reversed(iRegL dst, indIndexMemory src) %{
9713 match(Set dst (ReverseBytesL (LoadL src))); 9712 match(Set dst (ReverseBytesL (LoadL src)));
9714 9713
9715 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 9714 ins_cost(MEMORY_REF_COST);
9716 size(8); 9715 size(4);
9717 format %{ "LDXA $src, $dst\t!asi=primary_little" %} 9716 format %{ "LDXA $src, $dst\t!asi=primary_little" %}
9718 9717
9719 opcode(Assembler::ldxa_op3); 9718 ins_encode %{
9720 ins_encode( form3_mem_reg_little( src, dst ) ); 9719 __ ldxa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9720 %}
9721 ins_pipe(iload_mem); 9721 ins_pipe(iload_mem);
9722 %} 9722 %}
9723 9723
9724 // Load unsigned short / char reversed byte order
9725 instruct loadUS_reversed(iRegI dst, indIndexMemory src) %{
9726 match(Set dst (ReverseBytesUS (LoadUS src)));
9727
9728 ins_cost(MEMORY_REF_COST);
9729 size(4);
9730 format %{ "LDUHA $src, $dst\t!asi=primary_little" %}
9731
9732 ins_encode %{
9733 __ lduha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9734 %}
9735 ins_pipe(iload_mem);
9736 %}
9737
9738 // Load short reversed byte order
9739 instruct loadS_reversed(iRegI dst, indIndexMemory src) %{
9740 match(Set dst (ReverseBytesS (LoadS src)));
9741
9742 ins_cost(MEMORY_REF_COST);
9743 size(4);
9744 format %{ "LDSHA $src, $dst\t!asi=primary_little" %}
9745
9746 ins_encode %{
9747 __ ldsha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register);
9748 %}
9749 ins_pipe(iload_mem);
9750 %}
9751
9724 // Store Integer reversed byte order 9752 // Store Integer reversed byte order
9725 instruct storeI_reversed(memory dst, iRegI src) %{ 9753 instruct storeI_reversed(indIndexMemory dst, iRegI src) %{
9726 match(Set dst (StoreI dst (ReverseBytesI src))); 9754 match(Set dst (StoreI dst (ReverseBytesI src)));
9727 9755
9728 ins_cost(MEMORY_REF_COST); 9756 ins_cost(MEMORY_REF_COST);
9729 size(8); 9757 size(4);
9730 format %{ "STWA $src, $dst\t!asi=primary_little" %} 9758 format %{ "STWA $src, $dst\t!asi=primary_little" %}
9731 9759
9732 opcode(Assembler::stwa_op3); 9760 ins_encode %{
9733 ins_encode( form3_mem_reg_little( dst, src) ); 9761 __ stwa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE);
9762 %}
9734 ins_pipe(istore_mem_reg); 9763 ins_pipe(istore_mem_reg);
9735 %} 9764 %}
9736 9765
9737 // Store Long reversed byte order 9766 // Store Long reversed byte order
9738 instruct storeL_reversed(memory dst, iRegL src) %{ 9767 instruct storeL_reversed(indIndexMemory dst, iRegL src) %{
9739 match(Set dst (StoreL dst (ReverseBytesL src))); 9768 match(Set dst (StoreL dst (ReverseBytesL src)));
9740 9769
9741 ins_cost(MEMORY_REF_COST); 9770 ins_cost(MEMORY_REF_COST);
9742 size(8); 9771 size(4);
9743 format %{ "STXA $src, $dst\t!asi=primary_little" %} 9772 format %{ "STXA $src, $dst\t!asi=primary_little" %}
9744 9773
9745 opcode(Assembler::stxa_op3); 9774 ins_encode %{
9746 ins_encode( form3_mem_reg_little( dst, src) ); 9775 __ stxa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE);
9776 %}
9777 ins_pipe(istore_mem_reg);
9778 %}
9779
9780 // Store unsighed short/char reversed byte order
9781 instruct storeUS_reversed(indIndexMemory dst, iRegI src) %{
9782 match(Set dst (StoreC dst (ReverseBytesUS src)));
9783
9784 ins_cost(MEMORY_REF_COST);
9785 size(4);
9786 format %{ "STHA $src, $dst\t!asi=primary_little" %}
9787
9788 ins_encode %{
9789 __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE);
9790 %}
9791 ins_pipe(istore_mem_reg);
9792 %}
9793
9794 // Store short reversed byte order
9795 instruct storeS_reversed(indIndexMemory dst, iRegI src) %{
9796 match(Set dst (StoreC dst (ReverseBytesS src)));
9797
9798 ins_cost(MEMORY_REF_COST);
9799 size(4);
9800 format %{ "STHA $src, $dst\t!asi=primary_little" %}
9801
9802 ins_encode %{
9803 __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE);
9804 %}
9747 ins_pipe(istore_mem_reg); 9805 ins_pipe(istore_mem_reg);
9748 %} 9806 %}
9749 9807
9750 //----------PEEPHOLE RULES----------------------------------------------------- 9808 //----------PEEPHOLE RULES-----------------------------------------------------
9751 // These must follow all instruction definitions as they use the names 9809 // These must follow all instruction definitions as they use the names