From 622cef17d779063b9c2340342ca5e0bf93654949 Mon Sep 17 00:00:00 2001 From: never Date: Mon, 26 Apr 2010 11:27:21 -0700 Subject: [PATCH] 6946040: add intrinsic for short and char reverseBytes Reviewed-by: never, twisti Contributed-by: Hiroshi Yamauchi --- make/linux/makefiles/adlc.make | 5 +- make/solaris/makefiles/adlc.make | 5 +- src/cpu/sparc/vm/assembler_sparc.hpp | 3 - src/cpu/sparc/vm/sparc.ad | 184 ++++++++++++------ src/cpu/x86/vm/x86_32.ad | 26 ++- src/cpu/x86/vm/x86_64.ad | 26 ++- src/share/vm/adlc/formssel.cpp | 4 +- src/share/vm/classfile/vmSymbols.hpp | 8 +- src/share/vm/opto/classes.hpp | 4 +- src/share/vm/opto/library_call.cpp | 22 ++- src/share/vm/opto/subnode.hpp | 22 ++- test/compiler/6431242/Test.java | 176 +++++++++++++++++ .../6946040/TestCharShortByteSwap.java | 88 +++++++++ 13 files changed, 495 insertions(+), 78 deletions(-) create mode 100644 test/compiler/6431242/Test.java create mode 100644 test/compiler/6946040/TestCharShortByteSwap.java diff --git a/make/linux/makefiles/adlc.make b/make/linux/makefiles/adlc.make index 927462967..daea95559 100644 --- a/make/linux/makefiles/adlc.make +++ b/make/linux/makefiles/adlc.make @@ -127,6 +127,9 @@ $(GENERATEDFILES): refresh_adfiles # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) +# Debuggable by default +CFLAGS += -g + # Pass -D flags into ADLC. ADLCFLAGS += $(SYSDEFS) @@ -135,7 +138,7 @@ ADLCFLAGS += -q -T # Normally, debugging is done directly on the ad_*.cpp files. # But -g will put #line directives in those files pointing back to .ad. -#ADLCFLAGS += -g +ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 diff --git a/make/solaris/makefiles/adlc.make b/make/solaris/makefiles/adlc.make index e2f848c26..47c521538 100644 --- a/make/solaris/makefiles/adlc.make +++ b/make/solaris/makefiles/adlc.make @@ -147,6 +147,9 @@ $(GENERATEDFILES): refresh_adfiles # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) +# Debuggable by default +CFLAGS += -g + # Pass -D flags into ADLC. ADLCFLAGS += $(SYSDEFS) @@ -155,7 +158,7 @@ ADLCFLAGS += -q -T # Normally, debugging is done directly on the ad_*.cpp files. # But -g will put #line directives in those files pointing back to .ad. -#ADLCFLAGS += -g +ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 diff --git a/src/cpu/sparc/vm/assembler_sparc.hpp b/src/cpu/sparc/vm/assembler_sparc.hpp index 1e184bd45..f053ec577 100644 --- a/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/src/cpu/sparc/vm/assembler_sparc.hpp @@ -661,9 +661,6 @@ class Assembler : public AbstractAssembler { stx_op3 = 0x0e, swap_op3 = 0x0f, - lduwa_op3 = 0x10, - ldxa_op3 = 0x1b, - stwa_op3 = 0x14, stxa_op3 = 0x1e, diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad index 7f495a956..899101559 100644 --- a/src/cpu/sparc/vm/sparc.ad +++ b/src/cpu/sparc/vm/sparc.ad @@ -923,38 +923,6 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int te #endif } -void emit_form3_mem_reg_asi(CodeBuffer &cbuf, const MachNode* n, int primary, int tertiary, - int src1_enc, int disp32, int src2_enc, int dst_enc, int asi) { - - uint instr; - instr = (Assembler::ldst_op << 30) - | (dst_enc << 25) - | (primary << 19) - | (src1_enc << 14); - - int disp = disp32; - int index = src2_enc; - - if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) - disp += STACK_BIAS; - - // We should have a compiler bailout here rather than a guarantee. - // Better yet would be some mechanism to handle variable-size matches correctly. - guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" ); - - if( disp != 0 ) { - // use reg-reg form - // set src2=R_O7 contains offset - index = R_O7_enc; - emit3_simm13( cbuf, Assembler::arith_op, index, Assembler::or_op3, 0, disp); - } - instr |= (asi << 5); - instr |= index; - uint *code = (uint*)cbuf.code_end(); - *code = instr; - cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); -} - void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) { // The method which records debug information at every safepoint // expects the call to be the first instruction in the snippet as @@ -1954,11 +1922,6 @@ encode %{ $mem$$base, $mem$$disp, $mem$$index, $dst$$reg); %} - enc_class form3_mem_reg_little( memory mem, iRegI dst) %{ - emit_form3_mem_reg_asi(cbuf, this, $primary, -1, - $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE); - %} - enc_class form3_mem_prefetch_read( memory mem ) %{ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/); @@ -4311,8 +4274,8 @@ operand cmpOp_commute() %{ // instructions for every form of operand when the instruction accepts // multiple operand types with the same basic encoding and format. The classic // case of this is memory operands. -// Indirect is not included since its use is limited to Compare & Swap opclass memory( indirect, indOffset13, indIndex ); +opclass indIndexMemory( indIndex ); //----------PIPELINE----------------------------------------------------------- pipeline %{ @@ -9666,84 +9629,179 @@ instruct popCountL(iRegI dst, iRegL src) %{ instruct bytes_reverse_int(iRegI dst, stackSlotI src) %{ match(Set dst (ReverseBytesI src)); - effect(DEF dst, USE src); // Op cost is artificially doubled to make sure that load or store // instructions are preferred over this one which requires a spill // onto a stack slot. ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); - size(8); format %{ "LDUWA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::lduwa_op3); - ins_encode( form3_mem_reg_little(src, dst) ); + + ins_encode %{ + __ set($src$$disp + STACK_BIAS, O7); + __ lduwa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} ins_pipe( iload_mem ); %} instruct bytes_reverse_long(iRegL dst, stackSlotL src) %{ match(Set dst (ReverseBytesL src)); - effect(DEF dst, USE src); // Op cost is artificially doubled to make sure that load or store // instructions are preferred over this one which requires a spill // onto a stack slot. ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); - size(8); format %{ "LDXA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::ldxa_op3); - ins_encode( form3_mem_reg_little(src, dst) ); + ins_encode %{ + __ set($src$$disp + STACK_BIAS, O7); + __ ldxa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} + ins_pipe( iload_mem ); +%} + +instruct bytes_reverse_unsigned_short(iRegI dst, stackSlotI src) %{ + match(Set dst (ReverseBytesUS src)); + + // Op cost is artificially doubled to make sure that load or store + // instructions are preferred over this one which requires a spill + // onto a stack slot. + ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); + format %{ "LDUHA $src, $dst\t!asi=primary_little\n\t" %} + + ins_encode %{ + // the value was spilled as an int so bias the load + __ set($src$$disp + STACK_BIAS + 2, O7); + __ lduha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} + ins_pipe( iload_mem ); +%} + +instruct bytes_reverse_short(iRegI dst, stackSlotI src) %{ + match(Set dst (ReverseBytesS src)); + + // Op cost is artificially doubled to make sure that load or store + // instructions are preferred over this one which requires a spill + // onto a stack slot. + ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); + format %{ "LDSHA $src, $dst\t!asi=primary_little\n\t" %} + + ins_encode %{ + // the value was spilled as an int so bias the load + __ set($src$$disp + STACK_BIAS + 2, O7); + __ ldsha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} ins_pipe( iload_mem ); %} // Load Integer reversed byte order -instruct loadI_reversed(iRegI dst, memory src) %{ +instruct loadI_reversed(iRegI dst, indIndexMemory src) %{ match(Set dst (ReverseBytesI (LoadI src))); ins_cost(DEFAULT_COST + MEMORY_REF_COST); - size(8); + size(4); format %{ "LDUWA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::lduwa_op3); - ins_encode( form3_mem_reg_little( src, dst) ); + ins_encode %{ + __ lduwa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} ins_pipe(iload_mem); %} // Load Long - aligned and reversed -instruct loadL_reversed(iRegL dst, memory src) %{ +instruct loadL_reversed(iRegL dst, indIndexMemory src) %{ match(Set dst (ReverseBytesL (LoadL src))); - ins_cost(DEFAULT_COST + MEMORY_REF_COST); - size(8); + ins_cost(MEMORY_REF_COST); + size(4); format %{ "LDXA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::ldxa_op3); - ins_encode( form3_mem_reg_little( src, dst ) ); + ins_encode %{ + __ ldxa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} + ins_pipe(iload_mem); +%} + +// Load unsigned short / char reversed byte order +instruct loadUS_reversed(iRegI dst, indIndexMemory src) %{ + match(Set dst (ReverseBytesUS (LoadUS src))); + + ins_cost(MEMORY_REF_COST); + size(4); + format %{ "LDUHA $src, $dst\t!asi=primary_little" %} + + ins_encode %{ + __ lduha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} + ins_pipe(iload_mem); +%} + +// Load short reversed byte order +instruct loadS_reversed(iRegI dst, indIndexMemory src) %{ + match(Set dst (ReverseBytesS (LoadS src))); + + ins_cost(MEMORY_REF_COST); + size(4); + format %{ "LDSHA $src, $dst\t!asi=primary_little" %} + + ins_encode %{ + __ ldsha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); + %} ins_pipe(iload_mem); %} // Store Integer reversed byte order -instruct storeI_reversed(memory dst, iRegI src) %{ +instruct storeI_reversed(indIndexMemory dst, iRegI src) %{ match(Set dst (StoreI dst (ReverseBytesI src))); ins_cost(MEMORY_REF_COST); - size(8); + size(4); format %{ "STWA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::stwa_op3); - ins_encode( form3_mem_reg_little( dst, src) ); + ins_encode %{ + __ stwa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); + %} ins_pipe(istore_mem_reg); %} // Store Long reversed byte order -instruct storeL_reversed(memory dst, iRegL src) %{ +instruct storeL_reversed(indIndexMemory dst, iRegL src) %{ match(Set dst (StoreL dst (ReverseBytesL src))); ins_cost(MEMORY_REF_COST); - size(8); + size(4); format %{ "STXA $src, $dst\t!asi=primary_little" %} - opcode(Assembler::stxa_op3); - ins_encode( form3_mem_reg_little( dst, src) ); + ins_encode %{ + __ stxa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); + %} + ins_pipe(istore_mem_reg); +%} + +// Store unsighed short/char reversed byte order +instruct storeUS_reversed(indIndexMemory dst, iRegI src) %{ + match(Set dst (StoreC dst (ReverseBytesUS src))); + + ins_cost(MEMORY_REF_COST); + size(4); + format %{ "STHA $src, $dst\t!asi=primary_little" %} + + ins_encode %{ + __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); + %} + ins_pipe(istore_mem_reg); +%} + +// Store short reversed byte order +instruct storeS_reversed(indIndexMemory dst, iRegI src) %{ + match(Set dst (StoreC dst (ReverseBytesS src))); + + ins_cost(MEMORY_REF_COST); + size(4); + format %{ "STHA $src, $dst\t!asi=primary_little" %} + + ins_encode %{ + __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); + %} ins_pipe(istore_mem_reg); %} diff --git a/src/cpu/x86/vm/x86_32.ad b/src/cpu/x86/vm/x86_32.ad index 4e78eb1b7..9455d15d1 100644 --- a/src/cpu/x86/vm/x86_32.ad +++ b/src/cpu/x86/vm/x86_32.ad @@ -1,5 +1,5 @@ // -// Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -6272,6 +6272,30 @@ instruct bytes_reverse_long(eRegL dst) %{ ins_pipe( ialu_reg_reg); %} +instruct bytes_reverse_unsigned_short(eRegI dst) %{ + match(Set dst (ReverseBytesUS dst)); + + format %{ "BSWAP $dst\n\t" + "SHR $dst,16\n\t" %} + ins_encode %{ + __ bswapl($dst$$Register); + __ shrl($dst$$Register, 16); + %} + ins_pipe( ialu_reg ); +%} + +instruct bytes_reverse_short(eRegI dst) %{ + match(Set dst (ReverseBytesS dst)); + + format %{ "BSWAP $dst\n\t" + "SAR $dst,16\n\t" %} + ins_encode %{ + __ bswapl($dst$$Register); + __ sarl($dst$$Register, 16); + %} + ins_pipe( ialu_reg ); +%} + //---------- Zeros Count Instructions ------------------------------------------ diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index 32e8eacee..c5eecc626 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -1,5 +1,5 @@ // -// Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -7371,6 +7371,30 @@ instruct bytes_reverse_long(rRegL dst) %{ ins_pipe( ialu_reg); %} +instruct bytes_reverse_unsigned_short(rRegI dst) %{ + match(Set dst (ReverseBytesUS dst)); + + format %{ "bswapl $dst\n\t" + "shrl $dst,16\n\t" %} + ins_encode %{ + __ bswapl($dst$$Register); + __ shrl($dst$$Register, 16); + %} + ins_pipe( ialu_reg ); +%} + +instruct bytes_reverse_short(rRegI dst) %{ + match(Set dst (ReverseBytesS dst)); + + format %{ "bswapl $dst\n\t" + "sar $dst,16\n\t" %} + ins_encode %{ + __ bswapl($dst$$Register); + __ sarl($dst$$Register, 16); + %} + ins_pipe( ialu_reg ); +%} + instruct loadI_reversed(rRegI dst, memory src) %{ match(Set dst (ReverseBytesI (LoadI src))); diff --git a/src/share/vm/adlc/formssel.cpp b/src/share/vm/adlc/formssel.cpp index 2ec20c661..5791248f3 100644 --- a/src/share/vm/adlc/formssel.cpp +++ b/src/share/vm/adlc/formssel.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3861,6 +3861,8 @@ int MatchRule::is_expensive() const { strcmp(opType,"RoundFloat")==0 || strcmp(opType,"ReverseBytesI")==0 || strcmp(opType,"ReverseBytesL")==0 || + strcmp(opType,"ReverseBytesUS")==0 || + strcmp(opType,"ReverseBytesS")==0 || strcmp(opType,"Replicate16B")==0 || strcmp(opType,"Replicate8B")==0 || strcmp(opType,"Replicate4B")==0 || diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp index 0b4652157..a7ee43ee6 100644 --- a/src/share/vm/classfile/vmSymbols.hpp +++ b/src/share/vm/classfile/vmSymbols.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -357,6 +357,8 @@ template(void_double_signature, "()D") \ template(int_void_signature, "(I)V") \ template(int_int_signature, "(I)I") \ + template(char_char_signature, "(C)C") \ + template(short_short_signature, "(S)S") \ template(int_bool_signature, "(I)Z") \ template(float_int_signature, "(F)I") \ template(double_long_signature, "(D)J") \ @@ -584,6 +586,10 @@ do_intrinsic(_reverseBytes_i, java_lang_Integer, reverseBytes_name, int_int_signature, F_S) \ do_name( reverseBytes_name, "reverseBytes") \ do_intrinsic(_reverseBytes_l, java_lang_Long, reverseBytes_name, long_long_signature, F_S) \ + /* (symbol reverseBytes_name defined above) */ \ + do_intrinsic(_reverseBytes_c, java_lang_Character, reverseBytes_name, char_char_signature, F_S) \ + /* (symbol reverseBytes_name defined above) */ \ + do_intrinsic(_reverseBytes_s, java_lang_Short, reverseBytes_name, short_short_signature, F_S) \ /* (symbol reverseBytes_name defined above) */ \ \ do_intrinsic(_identityHashCode, java_lang_System, identityHashCode_name, object_int_signature, F_S) \ diff --git a/src/share/vm/opto/classes.hpp b/src/share/vm/opto/classes.hpp index f2320fc7e..acb4fe0e1 100644 --- a/src/share/vm/opto/classes.hpp +++ b/src/share/vm/opto/classes.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,8 @@ macro(Bool) macro(BoxLock) macro(ReverseBytesI) macro(ReverseBytesL) +macro(ReverseBytesUS) +macro(ReverseBytesS) macro(CProj) macro(CallDynamicJava) macro(CallJava) diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index 8f6920891..eaa2a06eb 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -636,6 +636,8 @@ bool LibraryCallKit::try_to_inline() { case vmIntrinsics::_reverseBytes_i: case vmIntrinsics::_reverseBytes_l: + case vmIntrinsics::_reverseBytes_s: + case vmIntrinsics::_reverseBytes_c: return inline_reverseBytes((vmIntrinsics::ID) intrinsic_id()); case vmIntrinsics::_get_AtomicLong: @@ -2010,13 +2012,19 @@ bool LibraryCallKit::inline_bitCount(vmIntrinsics::ID id) { return true; } -//----------------------------inline_reverseBytes_int/long------------------- +//----------------------------inline_reverseBytes_int/long/char/short------------------- // inline Integer.reverseBytes(int) // inline Long.reverseBytes(long) +// inline Character.reverseBytes(char) +// inline Short.reverseBytes(short) bool LibraryCallKit::inline_reverseBytes(vmIntrinsics::ID id) { - assert(id == vmIntrinsics::_reverseBytes_i || id == vmIntrinsics::_reverseBytes_l, "not reverse Bytes"); - if (id == vmIntrinsics::_reverseBytes_i && !Matcher::has_match_rule(Op_ReverseBytesI)) return false; - if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL)) return false; + assert(id == vmIntrinsics::_reverseBytes_i || id == vmIntrinsics::_reverseBytes_l || + id == vmIntrinsics::_reverseBytes_c || id == vmIntrinsics::_reverseBytes_s, + "not reverse Bytes"); + if (id == vmIntrinsics::_reverseBytes_i && !Matcher::has_match_rule(Op_ReverseBytesI)) return false; + if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL)) return false; + if (id == vmIntrinsics::_reverseBytes_c && !Matcher::has_match_rule(Op_ReverseBytesUS)) return false; + if (id == vmIntrinsics::_reverseBytes_s && !Matcher::has_match_rule(Op_ReverseBytesS)) return false; _sp += arg_size(); // restore stack pointer switch (id) { case vmIntrinsics::_reverseBytes_i: @@ -2025,6 +2033,12 @@ bool LibraryCallKit::inline_reverseBytes(vmIntrinsics::ID id) { case vmIntrinsics::_reverseBytes_l: push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0, pop_pair()))); break; + case vmIntrinsics::_reverseBytes_c: + push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop()))); + break; + case vmIntrinsics::_reverseBytes_s: + push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop()))); + break; default: ; } diff --git a/src/share/vm/opto/subnode.hpp b/src/share/vm/opto/subnode.hpp index ecdd10e1e..071570892 100644 --- a/src/share/vm/opto/subnode.hpp +++ b/src/share/vm/opto/subnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -509,3 +509,23 @@ public: const Type *bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } }; + +//-------------------------------ReverseBytesUSNode-------------------------------- +// reverse bytes of an unsigned short / char +class ReverseBytesUSNode : public Node { +public: + ReverseBytesUSNode(Node *c, Node *in1) : Node(c, in1) {} + virtual int Opcode() const; + const Type *bottom_type() const { return TypeInt::CHAR; } + virtual uint ideal_reg() const { return Op_RegI; } +}; + +//-------------------------------ReverseBytesSNode-------------------------------- +// reverse bytes of a short +class ReverseBytesSNode : public Node { +public: + ReverseBytesSNode(Node *c, Node *in1) : Node(c, in1) {} + virtual int Opcode() const; + const Type *bottom_type() const { return TypeInt::SHORT; } + virtual uint ideal_reg() const { return Op_RegI; } +}; diff --git a/test/compiler/6431242/Test.java b/test/compiler/6431242/Test.java new file mode 100644 index 000000000..4ad22b8a7 --- /dev/null +++ b/test/compiler/6431242/Test.java @@ -0,0 +1,176 @@ +/* + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/* + * @test + * @bug 6431242 + * @run main/othervm -server -XX:+PrintCompilation Test + */ + +public class Test{ + + int _len = 8; + int[] _arr_i = new int[_len]; + long[] _arr_l = new long[_len]; + + int[] _arr_i_cp = new int [_len]; + long[] _arr_l_cp = new long [_len]; + + int _k = 0x12345678; + int _j = 0; + int _ir = 0x78563412; + int _ir1 = 0x78563413; + int _ir2 = 0x79563412; + + long _m = 0x123456789abcdef0L; + long _l = 0L; + long _lr = 0xf0debc9a78563412L; + long _lr1 = 0xf0debc9a78563413L; + long _lr2 = 0xf1debc9a78563412L; + + void init() { + for (int i=0; i<_arr_i.length; i++) { + _arr_i[i] = _k; + _arr_l[i] = _m; + } + } + + public int test_int_reversed(int i) { + return Integer.reverseBytes(i); + } + + public long test_long_reversed(long i) { + return Long.reverseBytes(i); + } + + public void test_copy_ints(int[] dst, int[] src) { + for(int i=0; i 0) { + try { + return (short) Integer.valueOf(args[0]).intValue(); + } catch (NumberFormatException e) { } + } + return v; + } + + private static char initChar(String[] args, char v) { + if (args.length > 0) { + try { + return (char) Integer.valueOf(args[0]).intValue(); + } catch (NumberFormatException e) { } + } + return v; + } + + private static void testChar(char a, char b) { + if (a != Character.reverseBytes(b)) { + throw new RuntimeException("FAIL: " + (int)a + " != Character.reverseBytes(" + (int)b + ")"); + } + if (b != Character.reverseBytes(a)) { + throw new RuntimeException("FAIL: " + (int)b + " != Character.reverseBytes(" + (int)a + ")"); + } + } + + private static void testShort(short a, short b) { + if (a != Short.reverseBytes(b)) { + throw new RuntimeException("FAIL: " + (int)a + " != Short.reverseBytes(" + (int)b + ")"); + } + if (b != Short.reverseBytes(a)) { + throw new RuntimeException("FAIL: " + (int)b + " != Short.reverseBytes(" + (int)a + ")"); + } + } + + public static void main(String[] args) { + for (int i = 0; i < 100000; ++i) { // Trigger compilation + char c1 = initChar(args, (char) 0x0123); + char c2 = initChar(args, (char) 0x2301); + char c3 = initChar(args, (char) 0xaabb); + char c4 = initChar(args, (char) 0xbbaa); + short s1 = initShort(args, (short) 0x0123); + short s2 = initShort(args, (short) 0x2301); + short s3 = initShort(args, (short) 0xaabb); + short s4 = initShort(args, (short) 0xbbaa); + testChar(c1, c2); + testChar(c3, c4); + testShort(s1, s2); + testShort(s3, s4); + } + } +} -- GitLab