#4784 [interpreter] Use array bounds check instructions to optimize array load and store bytecodes.

Thu, 09 Mar 2017 15:11:22 +0800

author
jiangshaofeng
date
Thu, 09 Mar 2017 15:11:22 +0800
changeset 362
e46417a01c32
parent 361
63fe053f1032
child 363
a7bf8945c6de

#4784 [interpreter] Use array bounds check instructions to optimize array load and store bytecodes.
Reviewed-by: aoqi
Contributed and tested by: jiangshaofeng, aoqi

Added Loongson EXT instructions such as gslwle/gslwgt. These instructions can check array bound automatically, throw exceptions when index is out of bound.
These instructions were used to accelerate Java byte-code in the interpreter, such as iaload, iastore.
Added UseBoundCheckInstruction to enable/disable the use of these instructions.
UseBoundCheckInstruction is under development yet:
1. C1/C2 is not supported.
2. Array index not out of bound load & store passed, but array index out of bound load & store would crash.

src/cpu/mips/vm/assembler_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/assembler_mips.hpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/globals_mips.hpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/templateTable_mips_64.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/mips/vm/assembler_mips.cpp	Thu Mar 09 10:50:10 2017 +0800
     1.2 +++ b/src/cpu/mips/vm/assembler_mips.cpp	Thu Mar 09 15:11:22 2017 +0800
     1.3 @@ -206,10 +206,11 @@
     1.4  
     1.5  
     1.6  const char* Assembler::gs_lwc2_name[] = {
     1.7 -        "",   "",   "",   "",   "",  "",   "",   "",   "",   "",
     1.8 -        "",   "",   "",   "",   "",  "",   "",   "",   "",   "",
     1.9 -        "",   "",   "",   "",   "",  /*"",   "",   "",*/   "",   "",  //LWDIR, LWPTE, LDDIR and LDPTE have the same low 6 bits.
    1.10 -        "",   "",   "",   "",   "",  "gslq",     ""
    1.11 +        "",       "",       "",       "",         "",         "",         "",         "",
    1.12 +        "",       "",       "",       "",         "",         "",         "",         "",
    1.13 +        "gslble", "gslbgt", "gslhle", "gslhgt",   "gslwle",   "gslwgt",   "gsldle",   "gsldgt",
    1.14 +        "",       "",       "",       "gslwlec1", "gslwgtc1", "gsldlec1", "gsldgtc1", "",/*LWDIR, LWPTE, LDDIR and LDPTE have the same low 6 bits.*/
    1.15 +        "gslq",   ""
    1.16  };
    1.17  
    1.18  const char* Assembler::gs_sdc2_name[] = {
    1.19 @@ -217,10 +218,11 @@
    1.20  };
    1.21  
    1.22  const char* Assembler::gs_swc2_name[] = {
    1.23 -        "",    "",    "",    "",    "",    "",    "",    "",    "",    "",
    1.24 -        "",    "",    "",    "",    "",    "",    "",    "",    "",    "",
    1.25 -        "",    "",    "",    "",    "",    "",    "",    "",    "",    "",
    1.26 -        "",    "",    "gssq",       "" 
    1.27 +        "",        "",        "",        "",        "",          "",          "",         "",
    1.28 +        "",        "",        "",        "",        "",          "",          "",         "",
    1.29 +        "gssble",  "gssbgt",  "gsshle",  "gsshgt",  "gsswle",    "gsswgt",    "gssdle",   "gssdgt",
    1.30 +        "",        "",        "",        "",        "gsswlec1",  "gsswgtc1",  "gssdlec1", "gssdgtc1",
    1.31 +        "gssq",    ""
    1.32  };
    1.33  
    1.34  //misleading name, print only branch/jump instruction 
     2.1 --- a/src/cpu/mips/vm/assembler_mips.hpp	Thu Mar 09 10:50:10 2017 +0800
     2.2 +++ b/src/cpu/mips/vm/assembler_mips.hpp	Thu Mar 09 15:11:22 2017 +0800
     2.3 @@ -750,6 +750,18 @@
     2.4  
     2.5    // lwc2/gs_lwc2 family, the opcode is in low 6 bits.
     2.6    enum gs_lwc2_ops {
     2.7 +    gslble_op       = 0x10,
     2.8 +    gslbgt_op       = 0x11,
     2.9 +    gslhle_op       = 0x12,
    2.10 +    gslhgt_op       = 0x13,
    2.11 +    gslwle_op       = 0x14,
    2.12 +    gslwgt_op       = 0x15,
    2.13 +    gsldle_op       = 0x16,
    2.14 +    gsldgt_op       = 0x17,
    2.15 +    gslwlec1_op     = 0x1c,
    2.16 +    gslwgtc1_op     = 0x1d,
    2.17 +    gsldlec1_op     = 0x1e,
    2.18 +    gsldgtc1_op     = 0x1f,
    2.19      gslq_op         = 0x20
    2.20    };
    2.21  
    2.22 @@ -769,6 +781,18 @@
    2.23  
    2.24    // swc2/gs_swc2 family, the opcode is in low 6 bits.
    2.25    enum gs_swc2_ops {
    2.26 +    gssble_op       = 0x10,
    2.27 +    gssbgt_op       = 0x11,
    2.28 +    gsshle_op       = 0x12,
    2.29 +    gsshgt_op       = 0x13,
    2.30 +    gsswle_op       = 0x14,
    2.31 +    gsswgt_op       = 0x15,
    2.32 +    gssdle_op       = 0x16,
    2.33 +    gssdgt_op       = 0x17,
    2.34 +    gsswlec1_op     = 0x1c,
    2.35 +    gsswgtc1_op     = 0x1d,
    2.36 +    gssdlec1_op     = 0x1e,
    2.37 +    gssdgtc1_op     = 0x1f,
    2.38      gssq_op         = 0x20
    2.39    };
    2.40  
    2.41 @@ -1561,12 +1585,108 @@
    2.42    /* Godson3 extension */
    2.43  
    2.44    // gssq/gslq/gssqc1/gslqc1: vAddr = sign_extend(offset << 4 ) + GPR[base]. Therefore, the off should be ">> 4".
    2.45 +  void gslble(Register rt, Register base, Register bound) {
    2.46 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslble_op);
    2.47 +  }
    2.48 +
    2.49 +  void gslbgt(Register rt, Register base, Register bound) {
    2.50 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslbgt_op);
    2.51 +  }
    2.52 +
    2.53 +  void gslhle(Register rt, Register base, Register bound) {
    2.54 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslhle_op);
    2.55 +  }
    2.56 +
    2.57 +  void gslhgt(Register rt, Register base, Register bound) {
    2.58 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslhgt_op);
    2.59 +  }
    2.60 +
    2.61 +  void gslwle(Register rt, Register base, Register bound) {
    2.62 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwle_op);
    2.63 +  }
    2.64 +
    2.65 +  void gslwgt(Register rt, Register base, Register bound) {
    2.66 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwgt_op);
    2.67 +  }
    2.68 +
    2.69 +  void gsldle(Register rt, Register base, Register bound) {
    2.70 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldle_op);
    2.71 +  }
    2.72 +
    2.73 +  void gsldgt(Register rt, Register base, Register bound) {
    2.74 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldgt_op);
    2.75 +  }
    2.76 +
    2.77 +  void gslwlec1(FloatRegister rt, Register base, Register bound) {
    2.78 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwlec1_op);
    2.79 +  }
    2.80 +
    2.81 +  void gslwgtc1(FloatRegister rt, Register base, Register bound) {
    2.82 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwgtc1_op);
    2.83 +  }
    2.84 +
    2.85 +  void gsldlec1(FloatRegister rt, Register base, Register bound) {
    2.86 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldlec1_op);
    2.87 +  }
    2.88 +
    2.89 +  void gsldgtc1(FloatRegister rt, Register base, Register bound) {
    2.90 +    emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldgtc1_op);
    2.91 +  }
    2.92 +
    2.93    void gslq(Register rq, Register rt, Register base, int off) {
    2.94      off = off >> 4;
    2.95      assert(is_simm(off, 9),"gslq: off exceeds 9 bits");
    2.96      emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | 0 << 15 | (low(off, 9) << 6) | gslq_op | (int)rq->encoding() );
    2.97    }
    2.98  
    2.99 +  void gssble(Register rt, Register base, Register bound) {
   2.100 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssble_op);
   2.101 +  }
   2.102 +
   2.103 +  void gssbgt(Register rt, Register base, Register bound) {
   2.104 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssbgt_op);
   2.105 +  }
   2.106 +
   2.107 +  void gsshle(Register rt, Register base, Register bound) {
   2.108 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsshle_op);
   2.109 +  }
   2.110 +
   2.111 +  void gsshgt(Register rt, Register base, Register bound) {
   2.112 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsshgt_op);
   2.113 +  }
   2.114 +
   2.115 +  void gsswle(Register rt, Register base, Register bound) {
   2.116 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswle_op);
   2.117 +  }
   2.118 +
   2.119 +  void gsswgt(Register rt, Register base, Register bound) {
   2.120 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswgt_op);
   2.121 +  }
   2.122 +
   2.123 +  void gssdle(Register rt, Register base, Register bound) {
   2.124 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdle_op);
   2.125 +  }
   2.126 +
   2.127 +  void gssdgt(Register rt, Register base, Register bound) {
   2.128 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdgt_op);
   2.129 +  }
   2.130 +
   2.131 +  void gsswlec1(FloatRegister rt, Register base, Register bound) {
   2.132 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswlec1_op);
   2.133 +  }
   2.134 +
   2.135 +  void gsswgtc1(FloatRegister rt, Register base, Register bound) {
   2.136 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswgtc1_op);
   2.137 +  }
   2.138 +
   2.139 +  void gssdlec1(FloatRegister rt, Register base, Register bound) {
   2.140 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdlec1_op);
   2.141 +  }
   2.142 +
   2.143 +  void gssdgtc1(FloatRegister rt, Register base, Register bound) {
   2.144 +    emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdgtc1_op);
   2.145 +  }
   2.146 +
   2.147    void gssq(Register rq, Register rt, Register base, int off) {
   2.148      off = off >> 4;
   2.149      assert(is_simm(off, 9),"gssq: off exceeds 9 bits");
     3.1 --- a/src/cpu/mips/vm/globals_mips.hpp	Thu Mar 09 10:50:10 2017 +0800
     3.2 +++ b/src/cpu/mips/vm/globals_mips.hpp	Thu Mar 09 15:11:22 2017 +0800
     3.3 @@ -98,6 +98,9 @@
     3.4                  "for GS464E, UseSyncLevel >= 2000"                          \
     3.5                  "others, UseSyncLevel <= 1000")                             \
     3.6                                                                              \
     3.7 +  develop(bool, UseBoundCheckInstruction, false,                            \
     3.8 +                "Use bound check instruction")                              \
     3.9 +                                                                            \
    3.10    product(intx, SetFSFOFN, 999,                                             \
    3.11            "Set the FS/FO/FN bits in FCSR"                                   \
    3.12            "999 means FS/FO/FN will not be changed"                          \
     4.1 --- a/src/cpu/mips/vm/templateTable_mips_64.cpp	Thu Mar 09 10:50:10 2017 +0800
     4.2 +++ b/src/cpu/mips/vm/templateTable_mips_64.cpp	Thu Mar 09 15:11:22 2017 +0800
     4.3 @@ -661,39 +661,94 @@
     4.4  void TemplateTable::iaload() {
     4.5    transition(itos, itos);
     4.6    //  __ pop(SSR);
     4.7 -  index_check(SSR, FSR);
     4.8 -  __ dsll(FSR, FSR, 2);
     4.9 -  __ dadd(FSR, SSR, FSR);
    4.10 -  //FSR: index
    4.11 -  __ lw(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
    4.12 +  if(UseBoundCheckInstruction) {  
    4.13 +    __ pop(SSR); //SSR:array    FSR: index
    4.14 +    __ dsll(FSR, FSR, 2);
    4.15 +    __ dadd(FSR, SSR, FSR);
    4.16 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
    4.17 +  
    4.18 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
    4.19 +    __ dsll(AT, AT, 2);
    4.20 +    __ dadd(AT, SSR, AT);
    4.21 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));
    4.22 +  
    4.23 +    __ gslwle(FSR, FSR, AT);
    4.24 +  } else {
    4.25 +    index_check(SSR, FSR);
    4.26 +    __ dsll(FSR, FSR, 2);
    4.27 +    __ dadd(FSR, SSR, FSR);
    4.28 +    //FSR: index
    4.29 +    __ lw(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
    4.30 +  }
    4.31  }
    4.32  
    4.33 -
    4.34  void TemplateTable::laload() {
    4.35    transition(itos, ltos);
    4.36    //  __ pop(SSR);
    4.37 -  index_check(SSR, FSR);
    4.38 -  __ dsll(AT, FSR, Address::times_8);
    4.39 -  __ dadd(AT, SSR, AT);
    4.40 -  __ ld(FSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
    4.41 +  if(UseBoundCheckInstruction) {
    4.42 +    __ pop(SSR); //SSR:array    FSR: index
    4.43 +    __ dsll(FSR, FSR, Address::times_8);
    4.44 +    __ dadd(FSR, SSR, FSR);
    4.45 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
    4.46 +  
    4.47 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
    4.48 +    __ dsll(AT, AT, Address::times_8);
    4.49 +    __ dadd(AT, SSR, AT);
    4.50 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
    4.51 +  
    4.52 +    __ gsldle(FSR, FSR, AT); 
    4.53 +  } else {
    4.54 +    index_check(SSR, FSR);
    4.55 +    __ dsll(AT, FSR, Address::times_8);
    4.56 +    __ dadd(AT, SSR, AT);
    4.57 +    __ ld(FSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
    4.58 +  }
    4.59  }
    4.60  
    4.61  void TemplateTable::faload() {
    4.62 -	transition(itos, ftos);
    4.63 -	// __ pop(SSR);
    4.64 -	index_check(SSR, FSR);  
    4.65 -	__ shl(FSR, 2);
    4.66 -	__ dadd(FSR, SSR, FSR);
    4.67 -	__ lwc1(FSF, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
    4.68 +  transition(itos, ftos);
    4.69 +  // __ pop(SSR);
    4.70 +  if(UseBoundCheckInstruction) {
    4.71 +    __ pop(SSR); //SSR:array    FSR: index
    4.72 +    __ shl(FSR, 2);
    4.73 +    __ dadd(FSR, SSR, FSR);
    4.74 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
    4.75 +  
    4.76 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
    4.77 +    __ shl(AT, 2);
    4.78 +    __ dadd(AT, SSR, AT);
    4.79 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
    4.80 +  
    4.81 +    __ gslwlec1(FSF, FSR, AT);
    4.82 +  } else {
    4.83 +    index_check(SSR, FSR);  
    4.84 +    __ shl(FSR, 2);
    4.85 +    __ dadd(FSR, SSR, FSR);
    4.86 +    __ lwc1(FSF, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
    4.87 +  }
    4.88  }
    4.89  
    4.90  void TemplateTable::daload() {
    4.91 -	transition(itos, dtos);
    4.92 -	//__ pop(SSR);
    4.93 -	index_check(SSR, FSR);  
    4.94 -	__ dsll(AT, FSR, 3);
    4.95 -	__ dadd(AT, SSR, AT);
    4.96 -	__ ldc1(FSF, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
    4.97 +  transition(itos, dtos);
    4.98 +  //__ pop(SSR);
    4.99 +  if(UseBoundCheckInstruction) {
   4.100 +    __ pop(SSR); //SSR:array    FSR: index
   4.101 +    __ dsll(FSR, FSR, 3);
   4.102 +    __ dadd(FSR, SSR, FSR);
   4.103 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   4.104 +  
   4.105 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   4.106 +    __ dsll(AT, AT, 3);
   4.107 +    __ dadd(AT, SSR, AT);
   4.108 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   4.109 +  
   4.110 +    __ gsldlec1(FSF, FSR, AT);
   4.111 +  } else {
   4.112 +    index_check(SSR, FSR);  
   4.113 +    __ dsll(AT, FSR, 3);
   4.114 +    __ dadd(AT, SSR, AT);
   4.115 +    __ ldc1(FSF, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   4.116 +  }
   4.117  }
   4.118  
   4.119  void TemplateTable::aaload() {
   4.120 @@ -709,9 +764,21 @@
   4.121  void TemplateTable::baload() {
   4.122    transition(itos, itos);
   4.123    //__ pop(SSR);
   4.124 -  index_check(SSR, FSR); 
   4.125 -  __ dadd(FSR, SSR, FSR);
   4.126 -  __ lb(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   4.127 +  if(UseBoundCheckInstruction) {
   4.128 +    __ pop(SSR); //SSR:array   FSR:index
   4.129 +    __ dadd(FSR, SSR, FSR);
   4.130 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //base
   4.131 +
   4.132 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  
   4.133 +    __ dadd(AT, SSR, AT);
   4.134 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
   4.135 +
   4.136 +    __ gslble(FSR, FSR, AT);
   4.137 +  } else {
   4.138 +    index_check(SSR, FSR); 
   4.139 +    __ dadd(FSR, SSR, FSR);
   4.140 +    __ lb(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   4.141 +  }
   4.142  }
   4.143  
   4.144  void TemplateTable::caload() {
   4.145 @@ -741,10 +808,24 @@
   4.146  void TemplateTable::saload() {
   4.147    transition(itos, itos);
   4.148    // __ pop(SSR);
   4.149 -  index_check(SSR, FSR);  
   4.150 -  __ dsll(FSR, FSR, Address::times_2);
   4.151 -  __ dadd(FSR, SSR, FSR);
   4.152 -  __ lh(FSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_SHORT));
   4.153 +  if(UseBoundCheckInstruction) {
   4.154 +    __ pop(SSR); //SSR:array    FSR: index
   4.155 +    __ dsll(FSR, FSR, Address::times_2);
   4.156 +    __ dadd(FSR, SSR, FSR);
   4.157 +    __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
   4.158 +  
   4.159 +    __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   4.160 +    __ dsll(AT, AT, Address::times_2);
   4.161 +    __ dadd(AT, SSR, AT);
   4.162 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_SHORT));
   4.163 +  
   4.164 +    __ gslhle(FSR, FSR, AT); 
   4.165 +  } else {
   4.166 +    index_check(SSR, FSR);  
   4.167 +    __ dsll(FSR, FSR, Address::times_2);
   4.168 +    __ dadd(FSR, SSR, FSR);
   4.169 +    __ lh(FSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_SHORT));
   4.170 +  }
   4.171  }
   4.172  
   4.173  void TemplateTable::iload(int n) {
   4.174 @@ -916,11 +997,25 @@
   4.175  // used register : T2
   4.176  void TemplateTable::iastore() {
   4.177    transition(itos, vtos);
   4.178 -  __ pop_i(SSR);
   4.179 -  index_check(T2, SSR);  // prefer index in ebx
   4.180 -  __ dsll(SSR, SSR, Address::times_4);
   4.181 -  __ dadd(T2, T2, SSR);
   4.182 -  __ sw(FSR, T2, arrayOopDesc::base_offset_in_bytes(T_INT));
   4.183 +  __ pop_i(SSR);   // T2: array  SSR: index
   4.184 +  if(UseBoundCheckInstruction) {
   4.185 +    __ pop_ptr(T2); 
   4.186 +    __ dsll(SSR, SSR, Address::times_4);
   4.187 +    __ dadd(SSR, T2, SSR);
   4.188 +    __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));  // base
   4.189 +    
   4.190 +    __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());  
   4.191 +    __ dsll(AT, AT, Address::times_4);
   4.192 +    __ dadd(AT, T2, AT);
   4.193 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));  //bound
   4.194 +    
   4.195 +    __ gsswle(FSR, SSR, AT);
   4.196 +  } else {
   4.197 +    index_check(T2, SSR);  // prefer index in ebx
   4.198 +    __ dsll(SSR, SSR, Address::times_4);
   4.199 +    __ dadd(T2, T2, SSR);
   4.200 +    __ sw(FSR, T2, arrayOopDesc::base_offset_in_bytes(T_INT));
   4.201 +  }
   4.202  }
   4.203  
   4.204  
   4.205 @@ -929,31 +1024,72 @@
   4.206  void TemplateTable::lastore() {
   4.207    transition(ltos, vtos);
   4.208    __ pop_i (T2);
   4.209 -  index_check(T3, T2);
   4.210 -  __ dsll(T2, T2, Address::times_8);
   4.211 -  __ dadd(T3, T3, T2);
   4.212 -  __ sd(FSR, T3, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
   4.213 +  if(UseBoundCheckInstruction) {
   4.214 +    __ pop_ptr(T3); 
   4.215 +    __ dsll(T2, T2, Address::times_8);
   4.216 +    __ dadd(T2, T3, T2);
   4.217 +    __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);  // base
   4.218 +    
   4.219 +    __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());  
   4.220 +    __ dsll(AT, AT, Address::times_8);
   4.221 +    __ dadd(AT, T3, AT);
   4.222 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);  //bound
   4.223 +    
   4.224 +    __ gssdle(FSR, T2, AT);
   4.225 +  } else {
   4.226 +    index_check(T3, T2);
   4.227 +    __ dsll(T2, T2, Address::times_8);
   4.228 +    __ dadd(T3, T3, T2);
   4.229 +    __ sd(FSR, T3, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
   4.230 +  }
   4.231  }
   4.232  
   4.233  // used register T2
   4.234  void TemplateTable::fastore() {
   4.235    transition(ftos, vtos);
   4.236    __ pop_i(SSR);	
   4.237 -  index_check(T2, SSR); 
   4.238 -  __ dsll(SSR, SSR, Address::times_4);
   4.239 -  __ dadd(T2, T2, SSR);
   4.240 -  __ swc1(FSF, T2, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   4.241 +  if(UseBoundCheckInstruction) {
   4.242 +    __ pop_ptr(T2); 
   4.243 +    __ dsll(SSR, SSR, Address::times_4);
   4.244 +    __ dadd(SSR, T2, SSR);
   4.245 +    __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));  // base
   4.246 +    
   4.247 +    __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());  
   4.248 +    __ dsll(AT, AT, Address::times_4);
   4.249 +    __ dadd(AT, T2, AT);
   4.250 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));  //bound
   4.251 +    
   4.252 +    __ gsswlec1(FSF, SSR, AT);
   4.253 +  } else {
   4.254 +    index_check(T2, SSR); 
   4.255 +    __ dsll(SSR, SSR, Address::times_4);
   4.256 +    __ dadd(T2, T2, SSR);
   4.257 +    __ swc1(FSF, T2, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   4.258 +  }
   4.259  }
   4.260  
   4.261  // used register T2, T3
   4.262  void TemplateTable::dastore() {
   4.263    transition(dtos, vtos);
   4.264    __ pop_i (T2); 
   4.265 -  index_check(T3, T2);  
   4.266 -  __ dsll(T2, T2, Address::times_8);
   4.267 -  __ daddu(T3, T3, T2);
   4.268 -  __ sdc1(FSF, T3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   4.269 -
   4.270 +  if(UseBoundCheckInstruction) {
   4.271 +    __ pop_ptr(T3); 
   4.272 +    __ dsll(T2, T2, Address::times_8);
   4.273 +    __ dadd(T2, T3, T2);
   4.274 +    __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);  // base
   4.275 +    
   4.276 +    __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());  
   4.277 +    __ dsll(AT, AT, Address::times_8);
   4.278 +    __ dadd(AT, T3, AT);
   4.279 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);  //bound
   4.280 +    
   4.281 +    __ gssdlec1(FSF, T2, AT);
   4.282 +  } else {
   4.283 +    index_check(T3, T2);  
   4.284 +    __ dsll(T2, T2, Address::times_8);
   4.285 +    __ daddu(T3, T3, T2);
   4.286 +    __ sdc1(FSF, T3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   4.287 +  }
   4.288  }
   4.289  
   4.290  // used register : T2, T3, T8
   4.291 @@ -1019,18 +1155,44 @@
   4.292  void TemplateTable::bastore() {
   4.293    transition(itos, vtos);
   4.294    __ pop_i (SSR); 
   4.295 -  index_check(T2, SSR);
   4.296 -  __ dadd(SSR, T2, SSR);
   4.297 -  __ sb(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   4.298 +  if(UseBoundCheckInstruction) {
   4.299 +    __ pop_ptr(T2); 
   4.300 +    __ dadd(SSR, T2, SSR);
   4.301 +    __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));  // base
   4.302 +    
   4.303 +    __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());  
   4.304 +    __ dadd(AT, T2, AT);
   4.305 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE));  //bound
   4.306 +    
   4.307 +    __ gssble(FSR, SSR, AT);
   4.308 +  } else {
   4.309 +    index_check(T2, SSR);
   4.310 +    __ dadd(SSR, T2, SSR);
   4.311 +    __ sb(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   4.312 +  }
   4.313  }
   4.314  
   4.315  void TemplateTable::castore() {
   4.316    transition(itos, vtos);
   4.317    __ pop_i(SSR); 
   4.318 -  index_check(T2, SSR); 
   4.319 -  __ dsll(SSR, SSR, Address::times_2);
   4.320 -  __ dadd(SSR, T2, SSR);
   4.321 -  __ sh(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
   4.322 +  if(UseBoundCheckInstruction) {
   4.323 +    __ pop_ptr(T2); 
   4.324 +    __ dsll(SSR, SSR, Address::times_2);
   4.325 +    __ dadd(SSR, T2, SSR);
   4.326 +    __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));  // base
   4.327 +    
   4.328 +    __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());  
   4.329 +    __ dsll(AT, AT, Address::times_2);
   4.330 +    __ dadd(AT, T2, AT);
   4.331 +    __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_CHAR));  //bound
   4.332 +    
   4.333 +    __ gsshle(FSR, SSR, AT);
   4.334 +  } else {
   4.335 +    index_check(T2, SSR); 
   4.336 +    __ dsll(SSR, SSR, Address::times_2);
   4.337 +    __ dadd(SSR, T2, SSR);
   4.338 +    __ sh(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
   4.339 +  }
   4.340  }
   4.341  
   4.342  void TemplateTable::sastore() {

mercurial