6814842: Load shortening optimizations

Wed, 13 May 2009 00:45:22 -0700

author
twisti
date
Wed, 13 May 2009 00:45:22 -0700
changeset 1220
2056494941db
parent 1219
b2934faac289
child 1221
27d660246893

6814842: Load shortening optimizations
Summary: 6797305 handles load widening but no shortening which should be covered here.
Reviewed-by: never, kvn

src/cpu/sparc/vm/sparc.ad file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_32.ad file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_64.ad file | annotate | diff | comparison | revisions
src/share/vm/adlc/output_c.cpp file | annotate | diff | comparison | revisions
test/compiler/6814842/Test6814842.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/sparc.ad	Mon May 11 18:30:13 2009 -0700
     1.2 +++ b/src/cpu/sparc/vm/sparc.ad	Wed May 13 00:45:22 2009 -0700
     1.3 @@ -1891,15 +1891,17 @@
     1.4  // The intptr_t operand types, defined by textual substitution.
     1.5  // (Cf. opto/type.hpp.  This lets us avoid many, many other ifdefs.)
     1.6  #ifdef _LP64
     1.7 -#define immX    immL
     1.8 -#define immX13  immL13
     1.9 -#define iRegX   iRegL
    1.10 -#define g1RegX  g1RegL
    1.11 +#define immX     immL
    1.12 +#define immX13   immL13
    1.13 +#define immX13m7 immL13m7
    1.14 +#define iRegX    iRegL
    1.15 +#define g1RegX   g1RegL
    1.16  #else
    1.17 -#define immX    immI
    1.18 -#define immX13  immI13
    1.19 -#define iRegX   iRegI
    1.20 -#define g1RegX  g1RegI
    1.21 +#define immX     immI
    1.22 +#define immX13   immI13
    1.23 +#define immX13m7 immI13m7
    1.24 +#define iRegX    iRegI
    1.25 +#define g1RegX   g1RegI
    1.26  #endif
    1.27  
    1.28  //----------ENCODING BLOCK-----------------------------------------------------
    1.29 @@ -3454,6 +3456,16 @@
    1.30    interface(CONST_INTER);
    1.31  %}
    1.32  
    1.33 +// Integer Immediate: 13-bit minus 7
    1.34 +operand immI13m7() %{
    1.35 +  predicate((-4096 < n->get_int()) && ((n->get_int() + 7) <= 4095));
    1.36 +  match(ConI);
    1.37 +  op_cost(0);
    1.38 +
    1.39 +  format %{ %}
    1.40 +  interface(CONST_INTER);
    1.41 +%}
    1.42 +
    1.43  // Unsigned (positive) Integer Immediate: 13-bit
    1.44  operand immU13() %{
    1.45    predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
    1.46 @@ -3532,6 +3544,28 @@
    1.47    interface(CONST_INTER);
    1.48  %}
    1.49  
    1.50 +// Immediates for special shifts (sign extend)
    1.51 +
    1.52 +// Integer Immediate: the value 16
    1.53 +operand immI_16() %{
    1.54 +  predicate(n->get_int() == 16);
    1.55 +  match(ConI);
    1.56 +  op_cost(0);
    1.57 +
    1.58 +  format %{ %}
    1.59 +  interface(CONST_INTER);
    1.60 +%}
    1.61 +
    1.62 +// Integer Immediate: the value 24
    1.63 +operand immI_24() %{
    1.64 +  predicate(n->get_int() == 24);
    1.65 +  match(ConI);
    1.66 +  op_cost(0);
    1.67 +
    1.68 +  format %{ %}
    1.69 +  interface(CONST_INTER);
    1.70 +%}
    1.71 +
    1.72  // Integer Immediate: the value 255
    1.73  operand immI_255() %{
    1.74    predicate( n->get_int() == 255 );
    1.75 @@ -3542,6 +3576,16 @@
    1.76    interface(CONST_INTER);
    1.77  %}
    1.78  
    1.79 +// Integer Immediate: the value 65535
    1.80 +operand immI_65535() %{
    1.81 +  predicate(n->get_int() == 65535);
    1.82 +  match(ConI);
    1.83 +  op_cost(0);
    1.84 +
    1.85 +  format %{ %}
    1.86 +  interface(CONST_INTER);
    1.87 +%}
    1.88 +
    1.89  // Long Immediate: the value FF
    1.90  operand immL_FF() %{
    1.91    predicate( n->get_long() == 0xFFL );
    1.92 @@ -3647,6 +3691,16 @@
    1.93    interface(CONST_INTER);
    1.94  %}
    1.95  
    1.96 +// Long Immediate: 13-bit minus 7
    1.97 +operand immL13m7() %{
    1.98 +  predicate((-4096L < n->get_long()) && ((n->get_long() + 7L) <= 4095L));
    1.99 +  match(ConL);
   1.100 +  op_cost(0);
   1.101 +
   1.102 +  format %{ %}
   1.103 +  interface(CONST_INTER);
   1.104 +%}
   1.105 +
   1.106  // Long Immediate: low 32-bit mask
   1.107  operand immL_32bits() %{
   1.108    predicate(n->get_long() == 0xFFFFFFFFL);
   1.109 @@ -4084,7 +4138,7 @@
   1.110    %}
   1.111  %}
   1.112  
   1.113 -// Indirect with Offset
   1.114 +// Indirect with simm13 Offset
   1.115  operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{
   1.116    constraint(ALLOC_IN_RC(sp_ptr_reg));
   1.117    match(AddP reg offset);
   1.118 @@ -4099,6 +4153,21 @@
   1.119    %}
   1.120  %}
   1.121  
   1.122 +// Indirect with simm13 Offset minus 7
   1.123 +operand indOffset13m7(sp_ptr_RegP reg, immX13m7 offset) %{
   1.124 +  constraint(ALLOC_IN_RC(sp_ptr_reg));
   1.125 +  match(AddP reg offset);
   1.126 +
   1.127 +  op_cost(100);
   1.128 +  format %{ "[$reg + $offset]" %}
   1.129 +  interface(MEMORY_INTER) %{
   1.130 +    base($reg);
   1.131 +    index(0x0);
   1.132 +    scale(0x0);
   1.133 +    disp($offset);
   1.134 +  %}
   1.135 +%}
   1.136 +
   1.137  // Note:  Intel has a swapped version also, like this:
   1.138  //operand indOffsetX(iRegI reg, immP offset) %{
   1.139  //  constraint(ALLOC_IN_RC(int_reg));
   1.140 @@ -5504,6 +5573,20 @@
   1.141    ins_pipe(iload_mask_mem);
   1.142  %}
   1.143  
   1.144 +// Load Short (16 bit signed) to Byte (8 bit signed)
   1.145 +instruct loadS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
   1.146 +  match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
   1.147 +  ins_cost(MEMORY_REF_COST);
   1.148 +
   1.149 +  size(4);
   1.150 +
   1.151 +  format %{ "LDSB   $mem+1,$dst\t! short -> byte" %}
   1.152 +  ins_encode %{
   1.153 +    __ ldsb($mem$$Address, $dst$$Register, 1);
   1.154 +  %}
   1.155 +  ins_pipe(iload_mask_mem);
   1.156 +%}
   1.157 +
   1.158  // Load Short (16bit signed) into a Long Register
   1.159  instruct loadS2L(iRegL dst, memory mem) %{
   1.160    match(Set dst (ConvI2L (LoadS mem)));
   1.161 @@ -5530,6 +5613,19 @@
   1.162    ins_pipe(iload_mask_mem);
   1.163  %}
   1.164  
   1.165 +// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
   1.166 +instruct loadUS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
   1.167 +  match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
   1.168 +  ins_cost(MEMORY_REF_COST);
   1.169 +
   1.170 +  size(4);
   1.171 +  format %{ "LDSB   $mem+1,$dst\t! ushort -> byte" %}
   1.172 +  ins_encode %{
   1.173 +    __ ldsb($mem$$Address, $dst$$Register, 1);
   1.174 +  %}
   1.175 +  ins_pipe(iload_mask_mem);
   1.176 +%}
   1.177 +
   1.178  // Load Unsigned Short/Char (16bit UNsigned) into a Long Register
   1.179  instruct loadUS2L(iRegL dst, memory mem) %{
   1.180    match(Set dst (ConvI2L (LoadUS mem)));
   1.181 @@ -5556,6 +5652,62 @@
   1.182    ins_pipe(iload_mem);
   1.183  %}
   1.184  
   1.185 +// Load Integer to Byte (8 bit signed)
   1.186 +instruct loadI2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
   1.187 +  match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
   1.188 +  ins_cost(MEMORY_REF_COST);
   1.189 +
   1.190 +  size(4);
   1.191 +
   1.192 +  format %{ "LDSB   $mem+3,$dst\t! int -> byte" %}
   1.193 +  ins_encode %{
   1.194 +    __ ldsb($mem$$Address, $dst$$Register, 3);
   1.195 +  %}
   1.196 +  ins_pipe(iload_mask_mem);
   1.197 +%}
   1.198 +
   1.199 +// Load Integer to Unsigned Byte (8 bit UNsigned)
   1.200 +instruct loadI2UB(iRegI dst, indOffset13m7 mem, immI_255 mask) %{
   1.201 +  match(Set dst (AndI (LoadI mem) mask));
   1.202 +  ins_cost(MEMORY_REF_COST);
   1.203 +
   1.204 +  size(4);
   1.205 +
   1.206 +  format %{ "LDUB   $mem+3,$dst\t! int -> ubyte" %}
   1.207 +  ins_encode %{
   1.208 +    __ ldub($mem$$Address, $dst$$Register, 3);
   1.209 +  %}
   1.210 +  ins_pipe(iload_mask_mem);
   1.211 +%}
   1.212 +
   1.213 +// Load Integer to Short (16 bit signed)
   1.214 +instruct loadI2S(iRegI dst, indOffset13m7 mem, immI_16 sixteen) %{
   1.215 +  match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
   1.216 +  ins_cost(MEMORY_REF_COST);
   1.217 +
   1.218 +  size(4);
   1.219 +
   1.220 +  format %{ "LDSH   $mem+2,$dst\t! int -> short" %}
   1.221 +  ins_encode %{
   1.222 +    __ ldsh($mem$$Address, $dst$$Register, 2);
   1.223 +  %}
   1.224 +  ins_pipe(iload_mask_mem);
   1.225 +%}
   1.226 +
   1.227 +// Load Integer to Unsigned Short (16 bit UNsigned)
   1.228 +instruct loadI2US(iRegI dst, indOffset13m7 mem, immI_65535 mask) %{
   1.229 +  match(Set dst (AndI (LoadI mem) mask));
   1.230 +  ins_cost(MEMORY_REF_COST);
   1.231 +
   1.232 +  size(4);
   1.233 +
   1.234 +  format %{ "LDUH   $mem+2,$dst\t! int -> ushort/char" %}
   1.235 +  ins_encode %{
   1.236 +    __ lduh($mem$$Address, $dst$$Register, 2);
   1.237 +  %}
   1.238 +  ins_pipe(iload_mask_mem);
   1.239 +%}
   1.240 +
   1.241  // Load Integer into a Long Register
   1.242  instruct loadI2L(iRegL dst, memory mem) %{
   1.243    match(Set dst (ConvI2L (LoadI mem)));
     2.1 --- a/src/cpu/x86/vm/x86_32.ad	Mon May 11 18:30:13 2009 -0700
     2.2 +++ b/src/cpu/x86/vm/x86_32.ad	Wed May 13 00:45:22 2009 -0700
     2.3 @@ -5240,6 +5240,15 @@
     2.4    interface(CONST_INTER);
     2.5  %}
     2.6  
     2.7 +// Constant for short-wide masking
     2.8 +operand immI_65535() %{
     2.9 +  predicate(n->get_int() == 65535);
    2.10 +  match(ConI);
    2.11 +
    2.12 +  format %{ %}
    2.13 +  interface(CONST_INTER);
    2.14 +%}
    2.15 +
    2.16  // Register Operands
    2.17  // Integer Register
    2.18  operand eRegI() %{
    2.19 @@ -6938,6 +6947,18 @@
    2.20    ins_pipe(ialu_reg_mem);
    2.21  %}
    2.22  
    2.23 +// Load Short (16 bit signed) to Byte (8 bit signed)
    2.24 +instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
    2.25 +  match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
    2.26 +
    2.27 +  ins_cost(125);
    2.28 +  format %{ "MOVSX  $dst, $mem\t# short -> byte" %}
    2.29 +  ins_encode %{
    2.30 +    __ movsbl($dst$$Register, $mem$$Address);
    2.31 +  %}
    2.32 +  ins_pipe(ialu_reg_mem);
    2.33 +%}
    2.34 +
    2.35  // Load Short (16bit signed) into Long Register
    2.36  instruct loadS2L(eRegL dst, memory mem) %{
    2.37    match(Set dst (ConvI2L (LoadS mem)));
    2.38 @@ -6970,9 +6991,20 @@
    2.39    ins_pipe(ialu_reg_mem);
    2.40  %}
    2.41  
    2.42 +// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
    2.43 +instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
    2.44 +  match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
    2.45 +
    2.46 +  ins_cost(125);
    2.47 +  format %{ "MOVSX  $dst, $mem\t# ushort -> byte" %}
    2.48 +  ins_encode %{
    2.49 +    __ movsbl($dst$$Register, $mem$$Address);
    2.50 +  %}
    2.51 +  ins_pipe(ialu_reg_mem);
    2.52 +%}
    2.53 +
    2.54  // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
    2.55 -instruct loadUS2L(eRegL dst, memory mem)
    2.56 -%{
    2.57 +instruct loadUS2L(eRegL dst, memory mem) %{
    2.58    match(Set dst (ConvI2L (LoadUS mem)));
    2.59  
    2.60    ins_cost(250);
    2.61 @@ -7001,6 +7033,54 @@
    2.62    ins_pipe(ialu_reg_mem);
    2.63  %}
    2.64  
    2.65 +// Load Integer (32 bit signed) to Byte (8 bit signed)
    2.66 +instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
    2.67 +  match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
    2.68 +
    2.69 +  ins_cost(125);
    2.70 +  format %{ "MOVSX  $dst, $mem\t# int -> byte" %}
    2.71 +  ins_encode %{
    2.72 +    __ movsbl($dst$$Register, $mem$$Address);
    2.73 +  %}
    2.74 +  ins_pipe(ialu_reg_mem);
    2.75 +%}
    2.76 +
    2.77 +// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
    2.78 +instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
    2.79 +  match(Set dst (AndI (LoadI mem) mask));
    2.80 +
    2.81 +  ins_cost(125);
    2.82 +  format %{ "MOVZX  $dst, $mem\t# int -> ubyte" %}
    2.83 +  ins_encode %{
    2.84 +    __ movzbl($dst$$Register, $mem$$Address);
    2.85 +  %}
    2.86 +  ins_pipe(ialu_reg_mem);
    2.87 +%}
    2.88 +
    2.89 +// Load Integer (32 bit signed) to Short (16 bit signed)
    2.90 +instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
    2.91 +  match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
    2.92 +
    2.93 +  ins_cost(125);
    2.94 +  format %{ "MOVSX  $dst, $mem\t# int -> short" %}
    2.95 +  ins_encode %{
    2.96 +    __ movswl($dst$$Register, $mem$$Address);
    2.97 +  %}
    2.98 +  ins_pipe(ialu_reg_mem);
    2.99 +%}
   2.100 +
   2.101 +// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
   2.102 +instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
   2.103 +  match(Set dst (AndI (LoadI mem) mask));
   2.104 +
   2.105 +  ins_cost(125);
   2.106 +  format %{ "MOVZX  $dst, $mem\t# int -> ushort/char" %}
   2.107 +  ins_encode %{
   2.108 +    __ movzwl($dst$$Register, $mem$$Address);
   2.109 +  %}
   2.110 +  ins_pipe(ialu_reg_mem);
   2.111 +%}
   2.112 +
   2.113  // Load Integer into Long Register
   2.114  instruct loadI2L(eRegL dst, memory mem) %{
   2.115    match(Set dst (ConvI2L (LoadI mem)));
   2.116 @@ -9034,28 +9114,28 @@
   2.117  
   2.118  // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
   2.119  // This idiom is used by the compiler for the i2b bytecode.
   2.120 -instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
   2.121 +instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
   2.122    match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
   2.123 -  effect(KILL cr);
   2.124  
   2.125    size(3);
   2.126    format %{ "MOVSX  $dst,$src :8" %}
   2.127 -  opcode(0xBE, 0x0F);
   2.128 -  ins_encode( OpcS, OpcP, RegReg( dst, src));
   2.129 -  ins_pipe( ialu_reg_reg );
   2.130 +  ins_encode %{
   2.131 +    __ movsbl($dst$$Register, $src$$Register);
   2.132 +  %}
   2.133 +  ins_pipe(ialu_reg_reg);
   2.134  %}
   2.135  
   2.136  // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
   2.137  // This idiom is used by the compiler the i2s bytecode.
   2.138 -instruct i2s(eRegI dst, xRegI src, immI_16 sixteen, eFlagsReg cr) %{
   2.139 +instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
   2.140    match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
   2.141 -  effect(KILL cr);
   2.142  
   2.143    size(3);
   2.144    format %{ "MOVSX  $dst,$src :16" %}
   2.145 -  opcode(0xBF, 0x0F);
   2.146 -  ins_encode( OpcS, OpcP, RegReg( dst, src));
   2.147 -  ins_pipe( ialu_reg_reg );
   2.148 +  ins_encode %{
   2.149 +    __ movswl($dst$$Register, $src$$Register);
   2.150 +  %}
   2.151 +  ins_pipe(ialu_reg_reg);
   2.152  %}
   2.153  
   2.154  
     3.1 --- a/src/cpu/x86/vm/x86_64.ad	Mon May 11 18:30:13 2009 -0700
     3.2 +++ b/src/cpu/x86/vm/x86_64.ad	Wed May 13 00:45:22 2009 -0700
     3.3 @@ -6459,6 +6459,18 @@
     3.4    ins_pipe(ialu_reg_mem);
     3.5  %}
     3.6  
     3.7 +// Load Short (16 bit signed) to Byte (8 bit signed)
     3.8 +instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
     3.9 +  match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
    3.10 +
    3.11 +  ins_cost(125);
    3.12 +  format %{ "movsbl $dst, $mem\t# short -> byte" %}
    3.13 +  ins_encode %{
    3.14 +    __ movsbl($dst$$Register, $mem$$Address);
    3.15 +  %}
    3.16 +  ins_pipe(ialu_reg_mem);
    3.17 +%}
    3.18 +
    3.19  // Load Short (16 bit signed) into Long Register
    3.20  instruct loadS2L(rRegL dst, memory mem)
    3.21  %{
    3.22 @@ -6489,6 +6501,18 @@
    3.23    ins_pipe(ialu_reg_mem);
    3.24  %}
    3.25  
    3.26 +// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
    3.27 +instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
    3.28 +  match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
    3.29 +
    3.30 +  ins_cost(125);
    3.31 +  format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
    3.32 +  ins_encode %{
    3.33 +    __ movsbl($dst$$Register, $mem$$Address);
    3.34 +  %}
    3.35 +  ins_pipe(ialu_reg_mem);
    3.36 +%}
    3.37 +
    3.38  // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
    3.39  instruct loadUS2L(rRegL dst, memory mem)
    3.40  %{
    3.41 @@ -6519,6 +6543,54 @@
    3.42    ins_pipe(ialu_reg_mem);
    3.43  %}
    3.44  
    3.45 +// Load Integer (32 bit signed) to Byte (8 bit signed)
    3.46 +instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
    3.47 +  match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
    3.48 +
    3.49 +  ins_cost(125);
    3.50 +  format %{ "movsbl  $dst, $mem\t# int -> byte" %}
    3.51 +  ins_encode %{
    3.52 +    __ movsbl($dst$$Register, $mem$$Address);
    3.53 +  %}
    3.54 +  ins_pipe(ialu_reg_mem);
    3.55 +%}
    3.56 +
    3.57 +// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
    3.58 +instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
    3.59 +  match(Set dst (AndI (LoadI mem) mask));
    3.60 +
    3.61 +  ins_cost(125);
    3.62 +  format %{ "movzbl  $dst, $mem\t# int -> ubyte" %}
    3.63 +  ins_encode %{
    3.64 +    __ movzbl($dst$$Register, $mem$$Address);
    3.65 +  %}
    3.66 +  ins_pipe(ialu_reg_mem);
    3.67 +%}
    3.68 +
    3.69 +// Load Integer (32 bit signed) to Short (16 bit signed)
    3.70 +instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
    3.71 +  match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
    3.72 +
    3.73 +  ins_cost(125);
    3.74 +  format %{ "movswl  $dst, $mem\t# int -> short" %}
    3.75 +  ins_encode %{
    3.76 +    __ movswl($dst$$Register, $mem$$Address);
    3.77 +  %}
    3.78 +  ins_pipe(ialu_reg_mem);
    3.79 +%}
    3.80 +
    3.81 +// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
    3.82 +instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
    3.83 +  match(Set dst (AndI (LoadI mem) mask));
    3.84 +
    3.85 +  ins_cost(125);
    3.86 +  format %{ "movzwl  $dst, $mem\t# int -> ushort/char" %}
    3.87 +  ins_encode %{
    3.88 +    __ movzwl($dst$$Register, $mem$$Address);
    3.89 +  %}
    3.90 +  ins_pipe(ialu_reg_mem);
    3.91 +%}
    3.92 +
    3.93  // Load Integer into Long Register
    3.94  instruct loadI2L(rRegL dst, memory mem)
    3.95  %{
     4.1 --- a/src/share/vm/adlc/output_c.cpp	Mon May 11 18:30:13 2009 -0700
     4.2 +++ b/src/share/vm/adlc/output_c.cpp	Wed May 13 00:45:22 2009 -0700
     4.3 @@ -1745,6 +1745,7 @@
     4.4        fprintf(fp,"    del_req(i);\n");
     4.5        fprintf(fp,"  }\n");
     4.6        fprintf(fp,"  _num_opnds = %d;\n", new_num_opnds);
     4.7 +      assert(new_num_opnds == node->num_unique_opnds(), "what?");
     4.8      }
     4.9    }
    4.10  
    4.11 @@ -3761,6 +3762,12 @@
    4.12      if ( this->captures_bottom_type() ) {
    4.13        fprintf(fp_cpp, "  node->_bottom_type = bottom_type();\n");
    4.14      }
    4.15 +
    4.16 +    uint cur_num_opnds = num_opnds();
    4.17 +    if (cur_num_opnds > 1 && cur_num_opnds != num_unique_opnds()) {
    4.18 +      fprintf(fp_cpp,"  node->_num_opnds = %d;\n", num_unique_opnds());
    4.19 +    }
    4.20 +
    4.21      fprintf(fp_cpp, "\n");
    4.22      fprintf(fp_cpp, "  // Copy _idx, inputs and operands to new node\n");
    4.23      fprintf(fp_cpp, "  fill_new_machnode(node, C);\n");
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/compiler/6814842/Test6814842.java	Wed May 13 00:45:22 2009 -0700
     5.3 @@ -0,0 +1,104 @@
     5.4 +/*
     5.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    5.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    5.24 + * have any questions.
    5.25 + */
    5.26 +
    5.27 +/**
    5.28 + * @test
    5.29 + * @bug 6814842
    5.30 + * @summary Load shortening optimizations
    5.31 + *
    5.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6814842.loadS2B,Test6814842.loadS2Bmask255,Test6814842.loadUS2B,Test6814842.loadUS2Bmask255,Test6814842.loadI2B,Test6814842.loadI2Bmask255,Test6814842.loadI2S,Test6814842.loadI2Smask255,Test6814842.loadI2Smask65535,Test6814842.loadI2US,Test6814842.loadI2USmask255,Test6814842.loadI2USmask65535 Test6814842
    5.33 + */
    5.34 +
    5.35 +public class Test6814842 {
    5.36 +    static final short[] sa = new short[] { (short) 0xF1F2 };
    5.37 +    static final char[]  ca = new char[]  { (char) 0xF3F4  };
    5.38 +    static final int[]   ia = new int[]   { 0xF1F2F3F4     };
    5.39 +
    5.40 +    public static void main(String[] args)
    5.41 +    {
    5.42 +        byte s2b = loadS2B(sa);
    5.43 +        if (s2b != (byte) 0xF2)
    5.44 +            throw new InternalError("loadS2B failed: " + s2b + " != " + (byte) 0xF2);
    5.45 +
    5.46 +        byte s2bmask255 = loadS2Bmask255(sa);
    5.47 +        if (s2bmask255 != (byte) 0xF2)
    5.48 +            throw new InternalError("loadS2Bmask255 failed: " + s2bmask255 + " != " + (byte) 0xF2);
    5.49 +
    5.50 +        byte us2b = loadUS2B(ca);
    5.51 +        if (us2b != (byte) 0xF4)
    5.52 +            throw new InternalError("loadUS2B failed: " + us2b + " != " + (byte) 0xF4);
    5.53 +
    5.54 +        byte us2bmask255 = loadUS2Bmask255(ca);
    5.55 +        if (us2bmask255 != (byte) 0xF4)
    5.56 +            throw new InternalError("loadUS2Bmask255 failed: " + us2bmask255 + " != " + (byte) 0xF4);
    5.57 +
    5.58 +        byte i2b = loadI2B(ia);
    5.59 +        if (i2b != (byte) 0xF4)
    5.60 +            throw new InternalError("loadI2B failed: " + i2b + " != " + (byte) 0xF4);
    5.61 +
    5.62 +        byte i2bmask255 = loadI2Bmask255(ia);
    5.63 +        if (i2bmask255 != (byte) 0xF4)
    5.64 +            throw new InternalError("loadI2Bmask255 failed: " + i2bmask255 + " != " + (byte) 0xF4);
    5.65 +
    5.66 +        short i2s = loadI2S(ia);
    5.67 +        if (i2s != (short) 0xF3F4)
    5.68 +            throw new InternalError("loadI2S failed: " + i2s + " != " + (short) 0xF3F4);
    5.69 +
    5.70 +        short i2smask255 = loadI2Smask255(ia);
    5.71 +        if (i2smask255 != (short) 0xF4)
    5.72 +            throw new InternalError("loadI2Smask255 failed: " + i2smask255 + " != " + (short) 0xF4);
    5.73 +
    5.74 +        short i2smask65535 = loadI2Smask65535(ia);
    5.75 +        if (i2smask65535 != (short) 0xF3F4)
    5.76 +            throw new InternalError("loadI2Smask65535 failed: " + i2smask65535 + " != " + (short) 0xF3F4);
    5.77 +
    5.78 +        char i2us = loadI2US(ia);
    5.79 +        if (i2us != (char) 0xF3F4)
    5.80 +            throw new InternalError("loadI2US failed: " + (int) i2us + " != " + (char) 0xF3F4);
    5.81 +
    5.82 +        char i2usmask255 = loadI2USmask255(ia);
    5.83 +        if (i2usmask255 != (char) 0xF4)
    5.84 +            throw new InternalError("loadI2USmask255 failed: " + (int) i2usmask255 + " != " + (char) 0xF4);
    5.85 +
    5.86 +        char i2usmask65535 = loadI2USmask65535(ia);
    5.87 +        if (i2usmask65535 != (char) 0xF3F4)
    5.88 +            throw new InternalError("loadI2USmask65535 failed: " + (int) i2usmask65535 + " != " + (char) 0xF3F4);
    5.89 +    }
    5.90 +
    5.91 +    static byte  loadS2B          (short[] sa) { return (byte)  (sa[0]         ); }
    5.92 +    static byte  loadS2Bmask255   (short[] sa) { return (byte)  (sa[0] & 0xFF  ); }
    5.93 +
    5.94 +    static byte  loadUS2B         (char[]  ca) { return (byte)  (ca[0]         ); }
    5.95 +    static byte  loadUS2Bmask255  (char[]  ca) { return (byte)  (ca[0] & 0xFF  ); }
    5.96 +
    5.97 +    static byte  loadI2B          (int[]   ia) { return (byte)  (ia[0]         ); }
    5.98 +    static byte  loadI2Bmask255   (int[]   ia) { return (byte)  (ia[0] & 0xFF  ); }
    5.99 +
   5.100 +    static short loadI2S          (int[]   ia) { return (short) (ia[0]         ); }
   5.101 +    static short loadI2Smask255   (int[]   ia) { return (short) (ia[0] & 0xFF  ); }
   5.102 +    static short loadI2Smask65535 (int[]   ia) { return (short) (ia[0] & 0xFFFF); }
   5.103 +
   5.104 +    static char  loadI2US         (int[]   ia) { return (char)  (ia[0]         ); }
   5.105 +    static char  loadI2USmask255  (int[]   ia) { return (char)  (ia[0] & 0xFF  ); }
   5.106 +    static char  loadI2USmask65535(int[]   ia) { return (char)  (ia[0] & 0xFFFF); }
   5.107 +}

mercurial