< prev index next >

src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp

Print this page


   1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  53   LIR_Opr r = value()->operand();
  54   if (_gen->can_inline_as_constant(value())) {
  55     if (!r->is_constant()) {
  56       r = LIR_OprFact::value_type(value()->type());
  57     }
  58     _result = r;
  59   } else {
  60     load_item();
  61   }
  62 }
  63 
  64 
  65 //--------------------------------------------------------------
  66 //               LIRGenerator
  67 //--------------------------------------------------------------
  68 
  69 LIR_Opr LIRGenerator::exceptionOopOpr()              { return FrameMap::Oexception_opr;  }
  70 LIR_Opr LIRGenerator::exceptionPcOpr()               { return FrameMap::Oissuing_pc_opr; }
  71 LIR_Opr LIRGenerator::syncLockOpr()                  { return new_register(T_INT); }
  72 LIR_Opr LIRGenerator::syncTempOpr()                  { return new_register(T_OBJECT); }
  73 LIR_Opr LIRGenerator::getThreadTemp()                { return rlock_callee_saved(NOT_LP64(T_INT) LP64_ONLY(T_LONG)); }
  74 
  75 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {
  76   LIR_Opr opr;
  77   switch (type->tag()) {
  78   case intTag:     opr = callee ? FrameMap::I0_opr      : FrameMap::O0_opr;       break;
  79   case objectTag:  opr = callee ? FrameMap::I0_oop_opr  : FrameMap::O0_oop_opr;   break;
  80   case longTag:    opr = callee ? FrameMap::in_long_opr : FrameMap::out_long_opr; break;
  81   case floatTag:   opr = FrameMap::F0_opr;                                        break;
  82   case doubleTag:  opr = FrameMap::F0_double_opr;                                 break;
  83 
  84   case addressTag:
  85   default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
  86   }
  87 
  88   assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
  89   return opr;
  90 }
  91 
  92 LIR_Opr LIRGenerator::rlock_callee_saved(BasicType type) {
  93   LIR_Opr reg = new_register(type);


 198 
 199   LIR_Opr base_opr;
 200   intx offset = arrayOopDesc::base_offset_in_bytes(type);
 201 
 202   if (index_opr->is_constant()) {
 203     intx i = index_opr->as_constant_ptr()->as_jint();
 204     intx array_offset = i * elem_size;
 205     if (Assembler::is_simm13(array_offset + offset)) {
 206       base_opr = array_opr;
 207       offset = array_offset + offset;
 208     } else {
 209       base_opr = new_pointer_register();
 210       if (Assembler::is_simm13(array_offset)) {
 211         __ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr);
 212       } else {
 213         __ move(LIR_OprFact::intptrConst(array_offset), base_opr);
 214         __ add(base_opr, array_opr, base_opr);
 215       }
 216     }
 217   } else {
 218 #ifdef _LP64
 219     if (index_opr->type() == T_INT) {
 220       LIR_Opr tmp = new_register(T_LONG);
 221       __ convert(Bytecodes::_i2l, index_opr, tmp);
 222       index_opr = tmp;
 223     }
 224 #endif
 225 
 226     base_opr = new_pointer_register();
 227     assert (index_opr->is_register(), "Must be register");
 228     if (shift > 0) {
 229       __ shift_left(index_opr, shift, base_opr);
 230       __ add(base_opr, array_opr, base_opr);
 231     } else {
 232       __ add(index_opr, array_opr, base_opr);
 233     }
 234   }
 235   if (needs_card_mark) {
 236     LIR_Opr ptr = new_pointer_register();
 237     __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr);
 238     return new LIR_Address(ptr, type);
 239   } else {
 240     return new LIR_Address(base_opr, offset, type);
 241   }
 242 }
 243 
 244 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {


1293   __ jump(x->default_sux());
1294 }
1295 
1296 
1297 LIR_Opr LIRGenerator::getThreadPointer() {
1298   return FrameMap::as_pointer_opr(G2);
1299 }
1300 
1301 
1302 void LIRGenerator::trace_block_entry(BlockBegin* block) {
1303   __ move(LIR_OprFact::intConst(block->block_id()), FrameMap::O0_opr);
1304   LIR_OprList* args = new LIR_OprList(1);
1305   args->append(FrameMap::O0_opr);
1306   address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);
1307   __ call_runtime_leaf(func, rlock_callee_saved(T_INT), LIR_OprFact::illegalOpr, args);
1308 }
1309 
1310 
1311 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,
1312                                         CodeEmitInfo* info) {
1313 #ifdef _LP64
1314   __ store(value, address, info);
1315 #else
1316   __ volatile_store_mem_reg(value, address, info);
1317 #endif
1318 }
1319 
1320 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
1321                                        CodeEmitInfo* info) {
1322 #ifdef _LP64
1323   __ load(address, result, info);
1324 #else
1325   __ volatile_load_mem_reg(address, result, info);
1326 #endif
1327 }
1328 
1329 
1330 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
1331                                      BasicType type, bool is_volatile) {
1332   LIR_Opr base_op = src;
1333   LIR_Opr index_op = offset;
1334 
1335   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1336 #ifndef _LP64
1337   if (is_volatile && type == T_LONG) {
1338     __ volatile_store_unsafe_reg(data, src, offset, type, NULL, lir_patch_none);
1339   } else
1340 #endif
1341     {
1342       if (type == T_BOOLEAN) {
1343         type = T_BYTE;
1344       }
1345       LIR_Address* addr;
1346       if (type == T_ARRAY || type == T_OBJECT) {
1347         LIR_Opr tmp = new_pointer_register();
1348         __ add(base_op, index_op, tmp);
1349         addr = new LIR_Address(tmp, type);
1350       } else {
1351         addr = new LIR_Address(base_op, index_op, type);
1352       }
1353 
1354       if (is_obj) {
1355         pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1356                     true /* do_load */, false /* patch */, NULL);
1357         // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));
1358       }
1359       __ move(data, addr);
1360       if (is_obj) {
1361         // This address is precise
1362         post_barrier(LIR_OprFact::address(addr), data);
1363       }
1364     }
1365 }
1366 
1367 
1368 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
1369                                      BasicType type, bool is_volatile) {
1370 #ifndef _LP64
1371   if (is_volatile && type == T_LONG) {
1372     __ volatile_load_unsafe_reg(src, offset, dst, type, NULL, lir_patch_none);
1373   } else
1374 #endif
1375     {
1376     LIR_Address* addr = new LIR_Address(src, offset, type);
1377     __ load(addr, dst);
1378   }
1379 }
1380 
1381 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1382   BasicType type = x->basic_type();
1383   LIRItem src(x->object(), this);
1384   LIRItem off(x->offset(), this);
1385   LIRItem value(x->value(), this);
1386 
1387   src.load_item();
1388   value.load_item();
1389   off.load_nonconstant();
1390 
1391   LIR_Opr dst = rlock_result(x, type);
1392   LIR_Opr data = value.result();
1393   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1394   LIR_Opr offset = off.result();
1395 
1396   // Because we want a 2-arg form of xchg
1397   __ move(data, dst);
1398 
1399   assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type");
1400   LIR_Address* addr;
1401   if (offset->is_constant()) {
1402 
1403 #ifdef _LP64
1404     jlong l = offset->as_jlong();
1405     assert((jlong)((jint)l) == l, "offset too large for constant");
1406     jint c = (jint)l;
1407 #else
1408     jint c = offset->as_jint();
1409 #endif
1410     addr = new LIR_Address(src.result(), c, type);
1411   } else {
1412     addr = new LIR_Address(src.result(), offset, type);
1413   }
1414 
1415   LIR_Opr tmp = LIR_OprFact::illegalOpr;
1416   LIR_Opr ptr = LIR_OprFact::illegalOpr;
1417 
1418   if (is_obj) {
1419     // Do the pre-write barrier, if any.
1420     // barriers on sparc don't work with a base + index address
1421     tmp = FrameMap::G3_opr;
1422     ptr = new_pointer_register();
1423     __ add(src.result(), off.result(), ptr);
1424     pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
1425                 true /* do_load */, false /* patch */, NULL);
1426   }
1427   __ xchg(LIR_OprFact::address(addr), dst, dst, tmp);
1428   if (is_obj) {
1429     // Seems to be a precise address
   1 /*
   2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  53   LIR_Opr r = value()->operand();
  54   if (_gen->can_inline_as_constant(value())) {
  55     if (!r->is_constant()) {
  56       r = LIR_OprFact::value_type(value()->type());
  57     }
  58     _result = r;
  59   } else {
  60     load_item();
  61   }
  62 }
  63 
  64 
  65 //--------------------------------------------------------------
  66 //               LIRGenerator
  67 //--------------------------------------------------------------
  68 
  69 LIR_Opr LIRGenerator::exceptionOopOpr()              { return FrameMap::Oexception_opr;  }
  70 LIR_Opr LIRGenerator::exceptionPcOpr()               { return FrameMap::Oissuing_pc_opr; }
  71 LIR_Opr LIRGenerator::syncLockOpr()                  { return new_register(T_INT); }
  72 LIR_Opr LIRGenerator::syncTempOpr()                  { return new_register(T_OBJECT); }
  73 LIR_Opr LIRGenerator::getThreadTemp()                { return rlock_callee_saved(T_LONG); }
  74 
  75 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {
  76   LIR_Opr opr;
  77   switch (type->tag()) {
  78   case intTag:     opr = callee ? FrameMap::I0_opr      : FrameMap::O0_opr;       break;
  79   case objectTag:  opr = callee ? FrameMap::I0_oop_opr  : FrameMap::O0_oop_opr;   break;
  80   case longTag:    opr = callee ? FrameMap::in_long_opr : FrameMap::out_long_opr; break;
  81   case floatTag:   opr = FrameMap::F0_opr;                                        break;
  82   case doubleTag:  opr = FrameMap::F0_double_opr;                                 break;
  83 
  84   case addressTag:
  85   default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
  86   }
  87 
  88   assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
  89   return opr;
  90 }
  91 
  92 LIR_Opr LIRGenerator::rlock_callee_saved(BasicType type) {
  93   LIR_Opr reg = new_register(type);


 198 
 199   LIR_Opr base_opr;
 200   intx offset = arrayOopDesc::base_offset_in_bytes(type);
 201 
 202   if (index_opr->is_constant()) {
 203     intx i = index_opr->as_constant_ptr()->as_jint();
 204     intx array_offset = i * elem_size;
 205     if (Assembler::is_simm13(array_offset + offset)) {
 206       base_opr = array_opr;
 207       offset = array_offset + offset;
 208     } else {
 209       base_opr = new_pointer_register();
 210       if (Assembler::is_simm13(array_offset)) {
 211         __ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr);
 212       } else {
 213         __ move(LIR_OprFact::intptrConst(array_offset), base_opr);
 214         __ add(base_opr, array_opr, base_opr);
 215       }
 216     }
 217   } else {

 218     if (index_opr->type() == T_INT) {
 219       LIR_Opr tmp = new_register(T_LONG);
 220       __ convert(Bytecodes::_i2l, index_opr, tmp);
 221       index_opr = tmp;
 222     }

 223 
 224     base_opr = new_pointer_register();
 225     assert (index_opr->is_register(), "Must be register");
 226     if (shift > 0) {
 227       __ shift_left(index_opr, shift, base_opr);
 228       __ add(base_opr, array_opr, base_opr);
 229     } else {
 230       __ add(index_opr, array_opr, base_opr);
 231     }
 232   }
 233   if (needs_card_mark) {
 234     LIR_Opr ptr = new_pointer_register();
 235     __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr);
 236     return new LIR_Address(ptr, type);
 237   } else {
 238     return new LIR_Address(base_opr, offset, type);
 239   }
 240 }
 241 
 242 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {


1291   __ jump(x->default_sux());
1292 }
1293 
1294 
1295 LIR_Opr LIRGenerator::getThreadPointer() {
1296   return FrameMap::as_pointer_opr(G2);
1297 }
1298 
1299 
1300 void LIRGenerator::trace_block_entry(BlockBegin* block) {
1301   __ move(LIR_OprFact::intConst(block->block_id()), FrameMap::O0_opr);
1302   LIR_OprList* args = new LIR_OprList(1);
1303   args->append(FrameMap::O0_opr);
1304   address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);
1305   __ call_runtime_leaf(func, rlock_callee_saved(T_INT), LIR_OprFact::illegalOpr, args);
1306 }
1307 
1308 
1309 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,
1310                                         CodeEmitInfo* info) {

1311   __ store(value, address, info);



1312 }
1313 
1314 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
1315                                        CodeEmitInfo* info) {

1316   __ load(address, result, info);



1317 }
1318 
1319 
1320 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
1321                                      BasicType type, bool is_volatile) {
1322   LIR_Opr base_op = src;
1323   LIR_Opr index_op = offset;
1324 
1325   bool is_obj = (type == T_ARRAY || type == T_OBJECT);





1326     {
1327       if (type == T_BOOLEAN) {
1328         type = T_BYTE;
1329       }
1330       LIR_Address* addr;
1331       if (type == T_ARRAY || type == T_OBJECT) {
1332         LIR_Opr tmp = new_pointer_register();
1333         __ add(base_op, index_op, tmp);
1334         addr = new LIR_Address(tmp, type);
1335       } else {
1336         addr = new LIR_Address(base_op, index_op, type);
1337       }
1338 
1339       if (is_obj) {
1340         pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1341                     true /* do_load */, false /* patch */, NULL);
1342         // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));
1343       }
1344       __ move(data, addr);
1345       if (is_obj) {
1346         // This address is precise
1347         post_barrier(LIR_OprFact::address(addr), data);
1348       }
1349     }
1350 }
1351 
1352 
1353 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
1354                                      BasicType type, bool is_volatile) {





1355     {
1356     LIR_Address* addr = new LIR_Address(src, offset, type);
1357     __ load(addr, dst);
1358   }
1359 }
1360 
1361 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1362   BasicType type = x->basic_type();
1363   LIRItem src(x->object(), this);
1364   LIRItem off(x->offset(), this);
1365   LIRItem value(x->value(), this);
1366 
1367   src.load_item();
1368   value.load_item();
1369   off.load_nonconstant();
1370 
1371   LIR_Opr dst = rlock_result(x, type);
1372   LIR_Opr data = value.result();
1373   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1374   LIR_Opr offset = off.result();
1375 
1376   // Because we want a 2-arg form of xchg
1377   __ move(data, dst);
1378 
1379   assert (!x->is_add() && (type == T_INT || (is_obj && UseCompressedOops)), "unexpected type"); 
1380   LIR_Address* addr;
1381   if (offset->is_constant()) {
1382 

1383     jlong l = offset->as_jlong();
1384     assert((jlong)((jint)l) == l, "offset too large for constant");
1385     jint c = (jint)l;



1386     addr = new LIR_Address(src.result(), c, type);
1387   } else {
1388     addr = new LIR_Address(src.result(), offset, type);
1389   }
1390 
1391   LIR_Opr tmp = LIR_OprFact::illegalOpr;
1392   LIR_Opr ptr = LIR_OprFact::illegalOpr;
1393 
1394   if (is_obj) {
1395     // Do the pre-write barrier, if any.
1396     // barriers on sparc don't work with a base + index address
1397     tmp = FrameMap::G3_opr;
1398     ptr = new_pointer_register();
1399     __ add(src.result(), off.result(), ptr);
1400     pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
1401                 true /* do_load */, false /* patch */, NULL);
1402   }
1403   __ xchg(LIR_OprFact::address(addr), dst, dst, tmp);
1404   if (is_obj) {
1405     // Seems to be a precise address
< prev index next >