< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page




  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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "c1/c1_Compilation.hpp"
  27 #include "c1/c1_FrameMap.hpp"
  28 #include "c1/c1_Instruction.hpp"
  29 #include "c1/c1_LIRAssembler.hpp"
  30 #include "c1/c1_LIRGenerator.hpp"
  31 #include "c1/c1_Runtime1.hpp"
  32 #include "c1/c1_ValueStack.hpp"
  33 #include "ci/ciArray.hpp"
  34 #include "ci/ciObjArrayKlass.hpp"
  35 #include "ci/ciTypeArrayKlass.hpp"

  36 #include "runtime/sharedRuntime.hpp"
  37 #include "runtime/stubRoutines.hpp"
  38 #include "vmreg_x86.inline.hpp"
  39 
  40 #ifdef ASSERT
  41 #define __ gen()->lir(__FILE__, __LINE__)->
  42 #else
  43 #define __ gen()->lir()->
  44 #endif
  45 
  46 // Item will be loaded into a byte register; Intel only
  47 void LIRItem::load_byte_item() {
  48   load_item();
  49   LIR_Opr res = result();
  50 
  51   if (!res->is_virtual() || !_gen->is_vreg_flag_set(res, LIRGenerator::byte_reg)) {
  52     // make sure that it is a byte register
  53     assert(!value()->type()->is_float() && !value()->type()->is_double(),
  54            "can't load floats in byte register");
  55     LIR_Opr reg = _gen->rlock_byte(T_BYTE);


 702     left.set_destroys_register();
 703   }
 704   left.load_item();
 705   right.load_item();
 706   LIR_Opr reg = rlock_result(x);
 707 
 708   if (x->x()->type()->is_float_kind()) {
 709     Bytecodes::Code code = x->op();
 710     __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));
 711   } else if (x->x()->type()->tag() == longTag) {
 712     __ lcmp2int(left.result(), right.result(), reg);
 713   } else {
 714     Unimplemented();
 715   }
 716 }
 717 
 718 
 719 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
 720   assert(x->number_of_arguments() == 4, "wrong type");
 721   LIRItem obj   (x->argument_at(0), this);  // object
 722   LIRItem offset(x->argument_at(1), this);  // offset of field
 723   LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
 724   LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp
 725 
 726   assert(obj.type()->tag() == objectTag, "invalid type");
 727 
 728   // In 64bit the type can be long, sparc doesn't have this assert
 729   // assert(offset.type()->tag() == intTag, "invalid type");
 730 
 731   assert(cmp.type()->tag() == type->tag(), "invalid type");
 732   assert(val.type()->tag() == type->tag(), "invalid type");
 733 
 734   // get address of field
 735   obj.load_item();
 736   offset.load_nonconstant();


 737 
 738   if (type == objectType) {
 739     cmp.load_item_force(FrameMap::rax_oop_opr);
 740     val.load_item();
 741   } else if (type == intType) {
 742     cmp.load_item_force(FrameMap::rax_opr);
 743     val.load_item();
 744   } else if (type == longType) {
 745     cmp.load_item_force(FrameMap::long0_opr);
 746     val.load_item_force(FrameMap::long1_opr);
 747   } else {
 748     ShouldNotReachHere();
 749   }
 750 
 751   LIR_Opr addr = new_pointer_register();
 752   LIR_Address* a;
 753   if(offset.result()->is_constant()) {
 754 #ifdef _LP64
 755     jlong c = offset.result()->as_jlong();
 756     if ((jlong)((jint)c) == c) {
 757       a = new LIR_Address(obj.result(),
 758                           (jint)c,
 759                           as_BasicType(type));
 760     } else {
 761       LIR_Opr tmp = new_register(T_LONG);
 762       __ move(offset.result(), tmp);
 763       a = new LIR_Address(obj.result(),
 764                           tmp,
 765                           as_BasicType(type));
 766     }
 767 #else
 768     a = new LIR_Address(obj.result(),
 769                         offset.result()->as_jint(),
 770                         as_BasicType(type));
 771 #endif
 772   } else {
 773     a = new LIR_Address(obj.result(),
 774                         offset.result(),
 775                         LIR_Address::times_1,
 776                         0,
 777                         as_BasicType(type));
 778   }
 779   __ leal(LIR_OprFact::address(a), addr);
 780 
 781   if (type == objectType) {  // Write-barrier needed for Object fields.
 782     // Do the pre-write barrier, if any.
 783     pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
 784                 true /* do_load */, false /* patch */, NULL);
 785   }
 786 
 787   LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
 788   if (type == objectType)
 789     __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
 790   else if (type == intType)
 791     __ cas_int(addr, cmp.result(), val.result(), ill, ill);
 792   else if (type == longType)
 793     __ cas_long(addr, cmp.result(), val.result(), ill, ill);
 794   else {


1416     __ move(data, spill);
1417     __ move(spill, tmp);
1418     __ move(tmp, addr);
1419   } else {
1420     LIR_Address* addr = new LIR_Address(src, offset, type);
1421     bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1422     if (is_obj) {
1423       // Do the pre-write barrier, if any.
1424       pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1425                   true /* do_load */, false /* patch */, NULL);
1426       __ move(data, addr);
1427       assert(src->is_register(), "must be register");
1428       // Seems to be a precise address
1429       post_barrier(LIR_OprFact::address(addr), data);
1430     } else {
1431       __ move(data, addr);
1432     }
1433   }
1434 }
1435 











1436 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1437   BasicType type = x->basic_type();
1438   LIRItem src(x->object(), this);
1439   LIRItem off(x->offset(), this);
1440   LIRItem value(x->value(), this);
1441 
1442   src.load_item();
1443   value.load_item();
1444   off.load_nonconstant();
1445 


1446   LIR_Opr dst = rlock_result(x, type);
1447   LIR_Opr data = value.result();
1448   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1449   LIR_Opr offset = off.result();
1450 
1451   assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
1452   LIR_Address* addr;
1453   if (offset->is_constant()) {
1454 #ifdef _LP64
1455     jlong c = offset->as_jlong();
1456     if ((jlong)((jint)c) == c) {
1457       addr = new LIR_Address(src.result(), (jint)c, type);
1458     } else {
1459       LIR_Opr tmp = new_register(T_LONG);
1460       __ move(offset, tmp);
1461       addr = new LIR_Address(src.result(), tmp, type);
1462     }
1463 #else
1464     addr = new LIR_Address(src.result(), offset->as_jint(), type);
1465 #endif
1466   } else {
1467     addr = new LIR_Address(src.result(), offset, type);
1468   }
1469 


  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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "c1/c1_Compilation.hpp"
  27 #include "c1/c1_FrameMap.hpp"
  28 #include "c1/c1_Instruction.hpp"
  29 #include "c1/c1_LIRAssembler.hpp"
  30 #include "c1/c1_LIRGenerator.hpp"
  31 #include "c1/c1_Runtime1.hpp"
  32 #include "c1/c1_ValueStack.hpp"
  33 #include "ci/ciArray.hpp"
  34 #include "ci/ciObjArrayKlass.hpp"
  35 #include "ci/ciTypeArrayKlass.hpp"
  36 #include "prims/unsafe.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/stubRoutines.hpp"
  39 #include "vmreg_x86.inline.hpp"
  40 
  41 #ifdef ASSERT
  42 #define __ gen()->lir(__FILE__, __LINE__)->
  43 #else
  44 #define __ gen()->lir()->
  45 #endif
  46 
  47 // Item will be loaded into a byte register; Intel only
  48 void LIRItem::load_byte_item() {
  49   load_item();
  50   LIR_Opr res = result();
  51 
  52   if (!res->is_virtual() || !_gen->is_vreg_flag_set(res, LIRGenerator::byte_reg)) {
  53     // make sure that it is a byte register
  54     assert(!value()->type()->is_float() && !value()->type()->is_double(),
  55            "can't load floats in byte register");
  56     LIR_Opr reg = _gen->rlock_byte(T_BYTE);


 703     left.set_destroys_register();
 704   }
 705   left.load_item();
 706   right.load_item();
 707   LIR_Opr reg = rlock_result(x);
 708 
 709   if (x->x()->type()->is_float_kind()) {
 710     Bytecodes::Code code = x->op();
 711     __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));
 712   } else if (x->x()->type()->tag() == longTag) {
 713     __ lcmp2int(left.result(), right.result(), reg);
 714   } else {
 715     Unimplemented();
 716   }
 717 }
 718 
 719 
 720 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
 721   assert(x->number_of_arguments() == 4, "wrong type");
 722   LIRItem obj   (x->argument_at(0), this);  // object
 723   LIRItem off   (x->argument_at(1), this);  // offset of field
 724   LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
 725   LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp
 726 
 727   assert(obj.type()->tag() == objectTag, "invalid type");
 728 
 729   // In 64bit the type can be long, sparc doesn't have this assert
 730   // assert(offset.type()->tag() == intTag, "invalid type");
 731 
 732   assert(cmp.type()->tag() == type->tag(), "invalid type");
 733   assert(val.type()->tag() == type->tag(), "invalid type");
 734 
 735   // get address of field
 736   obj.load_item();
 737   off.load_nonconstant();
 738 
 739   LIR_Opr offset = unpack_offset(obj.result(), off.result());
 740 
 741   if (type == objectType) {
 742     cmp.load_item_force(FrameMap::rax_oop_opr);
 743     val.load_item();
 744   } else if (type == intType) {
 745     cmp.load_item_force(FrameMap::rax_opr);
 746     val.load_item();
 747   } else if (type == longType) {
 748     cmp.load_item_force(FrameMap::long0_opr);
 749     val.load_item_force(FrameMap::long1_opr);
 750   } else {
 751     ShouldNotReachHere();
 752   }
 753 
 754   LIR_Opr addr = new_pointer_register();
 755   LIR_Address* a;
 756   if(offset->is_constant()) {
 757 #ifdef _LP64
 758     jlong c = offset->as_jlong();
 759     if ((jlong)((jint)c) == c) {
 760       a = new LIR_Address(obj.result(),
 761                           (jint)c,
 762                           as_BasicType(type));
 763     } else {
 764       LIR_Opr tmp = new_register(T_LONG);
 765       __ move(offset, tmp);
 766       a = new LIR_Address(obj.result(),
 767                           tmp,
 768                           as_BasicType(type));
 769     }
 770 #else
 771     a = new LIR_Address(obj.result(),
 772                         offset->as_jint(),
 773                         as_BasicType(type));
 774 #endif
 775   } else {
 776     a = new LIR_Address(obj.result(),
 777                         offset,
 778                         LIR_Address::times_1,
 779                         0,
 780                         as_BasicType(type));
 781   }
 782   __ leal(LIR_OprFact::address(a), addr);
 783 
 784   if (type == objectType) {  // Write-barrier needed for Object fields.
 785     // Do the pre-write barrier, if any.
 786     pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
 787                 true /* do_load */, false /* patch */, NULL);
 788   }
 789 
 790   LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
 791   if (type == objectType)
 792     __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
 793   else if (type == intType)
 794     __ cas_int(addr, cmp.result(), val.result(), ill, ill);
 795   else if (type == longType)
 796     __ cas_long(addr, cmp.result(), val.result(), ill, ill);
 797   else {


1419     __ move(data, spill);
1420     __ move(spill, tmp);
1421     __ move(tmp, addr);
1422   } else {
1423     LIR_Address* addr = new LIR_Address(src, offset, type);
1424     bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1425     if (is_obj) {
1426       // Do the pre-write barrier, if any.
1427       pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1428                   true /* do_load */, false /* patch */, NULL);
1429       __ move(data, addr);
1430       assert(src->is_register(), "must be register");
1431       // Seems to be a precise address
1432       post_barrier(LIR_OprFact::address(addr), data);
1433     } else {
1434       __ move(data, addr);
1435     }
1436   }
1437 }
1438 
1439 LIR_Opr LIRGenerator::unpack_offset(LIR_Opr src, LIR_Opr off) {
1440   LIR_Opr tmp = new_register(NOT_LP64(T_INT) LP64_ONLY(T_LONG));
1441   LabelObj* Lcont = new LabelObj();
1442   __ move(off, tmp);
1443   __ cmp(lir_cond_equal, src, LIR_OprFact::oopConst(NULL));
1444   __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
1445   __ shift_right(tmp, Unsafe::offset_shift, tmp);
1446   __ branch_destination(Lcont->label());
1447   return tmp;
1448 }
1449 
1450 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1451   BasicType type = x->basic_type();
1452   LIRItem src(x->object(), this);
1453   LIRItem off(x->offset(), this);
1454   LIRItem value(x->value(), this);
1455 
1456   src.load_item();
1457   value.load_item();
1458   off.load_nonconstant();
1459 
1460   LIR_Opr offset = unpack_offset(src.result(), off.result());
1461 
1462   LIR_Opr dst = rlock_result(x, type);
1463   LIR_Opr data = value.result();
1464   bool is_obj = (type == T_ARRAY || type == T_OBJECT);

1465 
1466   assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
1467   LIR_Address* addr;
1468   if (offset->is_constant()) {
1469 #ifdef _LP64
1470     jlong c = offset->as_jlong();
1471     if ((jlong)((jint)c) == c) {
1472       addr = new LIR_Address(src.result(), (jint)c, type);
1473     } else {
1474       LIR_Opr tmp = new_register(T_LONG);
1475       __ move(offset, tmp);
1476       addr = new LIR_Address(src.result(), tmp, type);
1477     }
1478 #else
1479     addr = new LIR_Address(src.result(), offset->as_jint(), type);
1480 #endif
1481   } else {
1482     addr = new LIR_Address(src.result(), offset, type);
1483   }
1484 
< prev index next >