Thu, 09 Mar 2017 15:11:22 +0800
#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.
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() {