145 |
145 |
146 |
146 |
147 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, |
147 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, |
148 int shift, int disp, BasicType type) { |
148 int shift, int disp, BasicType type) { |
149 assert(base->is_register(), "must be"); |
149 assert(base->is_register(), "must be"); |
|
150 intx large_disp = disp; |
150 |
151 |
151 // accumulate fixed displacements |
152 // accumulate fixed displacements |
152 if (index->is_constant()) { |
153 if (index->is_constant()) { |
153 disp += index->as_constant_ptr()->as_jint() << shift; |
154 large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift; |
154 index = LIR_OprFact::illegalOpr; |
155 index = LIR_OprFact::illegalOpr; |
155 } |
156 } |
156 |
157 |
157 if (index->is_register()) { |
158 if (index->is_register()) { |
158 // apply the shift and accumulate the displacement |
159 // apply the shift and accumulate the displacement |
159 if (shift > 0) { |
160 if (shift > 0) { |
160 LIR_Opr tmp = new_pointer_register(); |
161 LIR_Opr tmp = new_pointer_register(); |
161 __ shift_left(index, shift, tmp); |
162 __ shift_left(index, shift, tmp); |
162 index = tmp; |
163 index = tmp; |
163 } |
164 } |
164 if (disp != 0) { |
165 if (large_disp != 0) { |
165 LIR_Opr tmp = new_pointer_register(); |
166 LIR_Opr tmp = new_pointer_register(); |
166 if (Assembler::is_simm13(disp)) { |
167 if (Assembler::is_simm13(large_disp)) { |
167 __ add(tmp, LIR_OprFact::intptrConst(disp), tmp); |
168 __ add(tmp, LIR_OprFact::intptrConst(large_disp), tmp); |
168 index = tmp; |
169 index = tmp; |
169 } else { |
170 } else { |
170 __ move(LIR_OprFact::intptrConst(disp), tmp); |
171 __ move(LIR_OprFact::intptrConst(large_disp), tmp); |
171 __ add(tmp, index, tmp); |
172 __ add(tmp, index, tmp); |
172 index = tmp; |
173 index = tmp; |
173 } |
174 } |
174 disp = 0; |
175 large_disp = 0; |
175 } |
176 } |
176 } else if (disp != 0 && !Assembler::is_simm13(disp)) { |
177 } else if (large_disp != 0 && !Assembler::is_simm13(large_disp)) { |
177 // index is illegal so replace it with the displacement loaded into a register |
178 // index is illegal so replace it with the displacement loaded into a register |
178 index = new_pointer_register(); |
179 index = new_pointer_register(); |
179 __ move(LIR_OprFact::intptrConst(disp), index); |
180 __ move(LIR_OprFact::intptrConst(large_disp), index); |
180 disp = 0; |
181 large_disp = 0; |
181 } |
182 } |
182 |
183 |
183 // at this point we either have base + index or base + displacement |
184 // at this point we either have base + index or base + displacement |
184 if (disp == 0) { |
185 if (large_disp == 0) { |
185 return new LIR_Address(base, index, type); |
186 return new LIR_Address(base, index, type); |
186 } else { |
187 } else { |
187 assert(Assembler::is_simm13(disp), "must be"); |
188 assert(Assembler::is_simm13(large_disp), "must be"); |
188 return new LIR_Address(base, disp, type); |
189 return new LIR_Address(base, large_disp, type); |
189 } |
190 } |
190 } |
191 } |
191 |
192 |
192 |
193 |
193 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, |
194 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, |
194 BasicType type, bool needs_card_mark) { |
195 BasicType type, bool needs_card_mark) { |
195 int elem_size = type2aelembytes(type); |
196 int elem_size = type2aelembytes(type); |
196 int shift = exact_log2(elem_size); |
197 int shift = exact_log2(elem_size); |
197 |
198 |
198 LIR_Opr base_opr; |
199 LIR_Opr base_opr; |
199 int offset = arrayOopDesc::base_offset_in_bytes(type); |
200 intx offset = arrayOopDesc::base_offset_in_bytes(type); |
200 |
201 |
201 if (index_opr->is_constant()) { |
202 if (index_opr->is_constant()) { |
202 int i = index_opr->as_constant_ptr()->as_jint(); |
203 intx i = index_opr->as_constant_ptr()->as_jint(); |
203 int array_offset = i * elem_size; |
204 intx array_offset = i * elem_size; |
204 if (Assembler::is_simm13(array_offset + offset)) { |
205 if (Assembler::is_simm13(array_offset + offset)) { |
205 base_opr = array_opr; |
206 base_opr = array_opr; |
206 offset = array_offset + offset; |
207 offset = array_offset + offset; |
207 } else { |
208 } else { |
208 base_opr = new_pointer_register(); |
209 base_opr = new_pointer_register(); |