Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 304:dc7f315e41f7
5108146: Merge i486 and amd64 cpu directories
6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up
Reviewed-by: kvn
author | never |
---|---|
date | Wed, 27 Aug 2008 00:21:55 -0700 |
parents | d1605aabd0a1 |
children | f8199438385b |
comparison
equal
deleted
inserted
replaced
303:fa4d1d240383 | 304:dc7f315e41f7 |
---|---|
75 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { | 75 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { |
76 LIR_Opr opr; | 76 LIR_Opr opr; |
77 switch (type->tag()) { | 77 switch (type->tag()) { |
78 case intTag: opr = FrameMap::rax_opr; break; | 78 case intTag: opr = FrameMap::rax_opr; break; |
79 case objectTag: opr = FrameMap::rax_oop_opr; break; | 79 case objectTag: opr = FrameMap::rax_oop_opr; break; |
80 case longTag: opr = FrameMap::rax_rdx_long_opr; break; | 80 case longTag: opr = FrameMap::long0_opr; break; |
81 case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; | 81 case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; |
82 case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; | 82 case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; |
83 | 83 |
84 case addressTag: | 84 case addressTag: |
85 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; | 85 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; |
115 return false; | 115 return false; |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 bool LIRGenerator::can_inline_as_constant(Value v) const { | 119 bool LIRGenerator::can_inline_as_constant(Value v) const { |
120 if (v->type()->tag() == longTag) return false; | |
120 return v->type()->tag() != objectTag || | 121 return v->type()->tag() != objectTag || |
121 (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object()); | 122 (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object()); |
122 } | 123 } |
123 | 124 |
124 | 125 |
125 bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { | 126 bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { |
127 if (c->type() == T_LONG) return false; | |
126 return c->type() != T_OBJECT || c->as_jobject() == NULL; | 128 return c->type() != T_OBJECT || c->as_jobject() == NULL; |
127 } | 129 } |
128 | 130 |
129 | 131 |
130 LIR_Opr LIRGenerator::safepoint_poll_register() { | 132 LIR_Opr LIRGenerator::safepoint_poll_register() { |
153 if (index_opr->is_constant()) { | 155 if (index_opr->is_constant()) { |
154 int elem_size = type2aelembytes(type); | 156 int elem_size = type2aelembytes(type); |
155 addr = new LIR_Address(array_opr, | 157 addr = new LIR_Address(array_opr, |
156 offset_in_bytes + index_opr->as_jint() * elem_size, type); | 158 offset_in_bytes + index_opr->as_jint() * elem_size, type); |
157 } else { | 159 } else { |
160 #ifdef _LP64 | |
161 if (index_opr->type() == T_INT) { | |
162 LIR_Opr tmp = new_register(T_LONG); | |
163 __ convert(Bytecodes::_i2l, index_opr, tmp); | |
164 index_opr = tmp; | |
165 } | |
166 #endif // _LP64 | |
158 addr = new LIR_Address(array_opr, | 167 addr = new LIR_Address(array_opr, |
159 index_opr, | 168 index_opr, |
160 LIR_Address::scale(type), | 169 LIR_Address::scale(type), |
161 offset_in_bytes, type); | 170 offset_in_bytes, type); |
162 } | 171 } |
163 if (needs_card_mark) { | 172 if (needs_card_mark) { |
164 // This store will need a precise card mark, so go ahead and | 173 // This store will need a precise card mark, so go ahead and |
165 // compute the full adddres instead of computing once for the | 174 // compute the full adddres instead of computing once for the |
166 // store and again for the card mark. | 175 // store and again for the card mark. |
167 LIR_Opr tmp = new_register(T_INT); | 176 LIR_Opr tmp = new_pointer_register(); |
168 __ leal(LIR_OprFact::address(addr), tmp); | 177 __ leal(LIR_OprFact::address(addr), tmp); |
169 return new LIR_Address(tmp, 0, type); | 178 return new LIR_Address(tmp, 0, type); |
170 } else { | 179 } else { |
171 return addr; | 180 return addr; |
172 } | 181 } |
173 } | 182 } |
174 | 183 |
175 | 184 |
176 void LIRGenerator::increment_counter(address counter, int step) { | 185 void LIRGenerator::increment_counter(address counter, int step) { |
177 LIR_Opr temp = new_register(T_INT); | 186 LIR_Opr pointer = new_pointer_register(); |
178 LIR_Opr pointer = new_register(T_INT); | 187 __ move(LIR_OprFact::intptrConst(counter), pointer); |
179 __ move(LIR_OprFact::intConst((int)counter), pointer); | |
180 LIR_Address* addr = new LIR_Address(pointer, 0, T_INT); | 188 LIR_Address* addr = new LIR_Address(pointer, 0, T_INT); |
181 increment_counter(addr, step); | 189 increment_counter(addr, step); |
182 } | 190 } |
183 | 191 |
184 | 192 |
479 right.set_destroys_register(); | 487 right.set_destroys_register(); |
480 | 488 |
481 left.load_item(); | 489 left.load_item(); |
482 right.load_item(); | 490 right.load_item(); |
483 | 491 |
484 LIR_Opr reg = FrameMap::rax_rdx_long_opr; | 492 LIR_Opr reg = FrameMap::long0_opr; |
485 arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL); | 493 arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL); |
486 LIR_Opr result = rlock_result(x); | 494 LIR_Opr result = rlock_result(x); |
487 __ move(reg, result); | 495 __ move(reg, result); |
488 } else { | 496 } else { |
489 // missing test if instr is commutative and if we should swap | 497 // missing test if instr is commutative and if we should swap |
688 LIRItem obj (x->argument_at(0), this); // AtomicLong object | 696 LIRItem obj (x->argument_at(0), this); // AtomicLong object |
689 LIRItem cmp_value (x->argument_at(1), this); // value to compare with field | 697 LIRItem cmp_value (x->argument_at(1), this); // value to compare with field |
690 LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value | 698 LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value |
691 | 699 |
692 // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction | 700 // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction |
693 cmp_value.load_item_force(FrameMap::rax_rdx_long_opr); | 701 cmp_value.load_item_force(FrameMap::long0_opr); |
694 | 702 |
695 // new value must be in rcx,ebx (hi,lo) | 703 // new value must be in rcx,ebx (hi,lo) |
696 new_value.load_item_force(FrameMap::rbx_rcx_long_opr); | 704 new_value.load_item_force(FrameMap::long1_opr); |
697 | 705 |
698 // object pointer register is overwritten with field address | 706 // object pointer register is overwritten with field address |
699 obj.load_item(); | 707 obj.load_item(); |
700 | 708 |
701 // generate compare-and-swap; produces zero condition if swap occurs | 709 // generate compare-and-swap; produces zero condition if swap occurs |
718 LIRItem offset(x->argument_at(1), this); // offset of field | 726 LIRItem offset(x->argument_at(1), this); // offset of field |
719 LIRItem cmp (x->argument_at(2), this); // value to compare with field | 727 LIRItem cmp (x->argument_at(2), this); // value to compare with field |
720 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp | 728 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp |
721 | 729 |
722 assert(obj.type()->tag() == objectTag, "invalid type"); | 730 assert(obj.type()->tag() == objectTag, "invalid type"); |
723 assert(offset.type()->tag() == intTag, "invalid type"); | 731 |
732 // In 64bit the type can be long, sparc doesn't have this assert | |
733 // assert(offset.type()->tag() == intTag, "invalid type"); | |
734 | |
724 assert(cmp.type()->tag() == type->tag(), "invalid type"); | 735 assert(cmp.type()->tag() == type->tag(), "invalid type"); |
725 assert(val.type()->tag() == type->tag(), "invalid type"); | 736 assert(val.type()->tag() == type->tag(), "invalid type"); |
726 | 737 |
727 // get address of field | 738 // get address of field |
728 obj.load_item(); | 739 obj.load_item(); |
733 val.load_item(); | 744 val.load_item(); |
734 } else if (type == intType) { | 745 } else if (type == intType) { |
735 cmp.load_item_force(FrameMap::rax_opr); | 746 cmp.load_item_force(FrameMap::rax_opr); |
736 val.load_item(); | 747 val.load_item(); |
737 } else if (type == longType) { | 748 } else if (type == longType) { |
738 cmp.load_item_force(FrameMap::rax_rdx_long_opr); | 749 cmp.load_item_force(FrameMap::long0_opr); |
739 val.load_item_force(FrameMap::rbx_rcx_long_opr); | 750 val.load_item_force(FrameMap::long1_opr); |
740 } else { | 751 } else { |
741 ShouldNotReachHere(); | 752 ShouldNotReachHere(); |
742 } | 753 } |
743 | 754 |
744 LIR_Opr addr = new_pointer_register(); | 755 LIR_Opr addr = new_pointer_register(); |
831 LIRItem length(x->argument_at(4), this); | 842 LIRItem length(x->argument_at(4), this); |
832 | 843 |
833 // operands for arraycopy must use fixed registers, otherwise | 844 // operands for arraycopy must use fixed registers, otherwise |
834 // LinearScan will fail allocation (because arraycopy always needs a | 845 // LinearScan will fail allocation (because arraycopy always needs a |
835 // call) | 846 // call) |
847 | |
848 #ifndef _LP64 | |
836 src.load_item_force (FrameMap::rcx_oop_opr); | 849 src.load_item_force (FrameMap::rcx_oop_opr); |
837 src_pos.load_item_force (FrameMap::rdx_opr); | 850 src_pos.load_item_force (FrameMap::rdx_opr); |
838 dst.load_item_force (FrameMap::rax_oop_opr); | 851 dst.load_item_force (FrameMap::rax_oop_opr); |
839 dst_pos.load_item_force (FrameMap::rbx_opr); | 852 dst_pos.load_item_force (FrameMap::rbx_opr); |
840 length.load_item_force (FrameMap::rdi_opr); | 853 length.load_item_force (FrameMap::rdi_opr); |
841 LIR_Opr tmp = (FrameMap::rsi_opr); | 854 LIR_Opr tmp = (FrameMap::rsi_opr); |
855 #else | |
856 | |
857 // The java calling convention will give us enough registers | |
858 // so that on the stub side the args will be perfect already. | |
859 // On the other slow/special case side we call C and the arg | |
860 // positions are not similar enough to pick one as the best. | |
861 // Also because the java calling convention is a "shifted" version | |
862 // of the C convention we can process the java args trivially into C | |
863 // args without worry of overwriting during the xfer | |
864 | |
865 src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); | |
866 src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); | |
867 dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); | |
868 dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); | |
869 length.load_item_force (FrameMap::as_opr(j_rarg4)); | |
870 | |
871 LIR_Opr tmp = FrameMap::as_opr(j_rarg5); | |
872 #endif // LP64 | |
873 | |
842 set_no_result(x); | 874 set_no_result(x); |
843 | 875 |
844 int flags; | 876 int flags; |
845 ciArrayKlass* expected_type; | 877 ciArrayKlass* expected_type; |
846 arraycopy_helper(x, &flags, &expected_type); | 878 arraycopy_helper(x, &flags, &expected_type); |
855 LIR_Opr fixed_register_for(BasicType type) { | 887 LIR_Opr fixed_register_for(BasicType type) { |
856 switch (type) { | 888 switch (type) { |
857 case T_FLOAT: return FrameMap::fpu0_float_opr; | 889 case T_FLOAT: return FrameMap::fpu0_float_opr; |
858 case T_DOUBLE: return FrameMap::fpu0_double_opr; | 890 case T_DOUBLE: return FrameMap::fpu0_double_opr; |
859 case T_INT: return FrameMap::rax_opr; | 891 case T_INT: return FrameMap::rax_opr; |
860 case T_LONG: return FrameMap::rax_rdx_long_opr; | 892 case T_LONG: return FrameMap::long0_opr; |
861 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; | 893 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; |
862 } | 894 } |
863 } | 895 } |
864 | 896 |
865 void LIRGenerator::do_Convert(Convert* x) { | 897 void LIRGenerator::do_Convert(Convert* x) { |
1159 __ jump(x->default_sux()); | 1191 __ jump(x->default_sux()); |
1160 } | 1192 } |
1161 | 1193 |
1162 | 1194 |
1163 LIR_Opr LIRGenerator::getThreadPointer() { | 1195 LIR_Opr LIRGenerator::getThreadPointer() { |
1196 #ifdef _LP64 | |
1197 return FrameMap::as_pointer_opr(r15_thread); | |
1198 #else | |
1164 LIR_Opr result = new_register(T_INT); | 1199 LIR_Opr result = new_register(T_INT); |
1165 __ get_thread(result); | 1200 __ get_thread(result); |
1166 return result; | 1201 return result; |
1202 #endif // | |
1167 } | 1203 } |
1168 | 1204 |
1169 void LIRGenerator::trace_block_entry(BlockBegin* block) { | 1205 void LIRGenerator::trace_block_entry(BlockBegin* block) { |
1170 store_stack_parameter(LIR_OprFact::intConst(block->block_id()), in_ByteSize(0)); | 1206 store_stack_parameter(LIR_OprFact::intConst(block->block_id()), in_ByteSize(0)); |
1171 LIR_OprList* args = new LIR_OprList(); | 1207 LIR_OprList* args = new LIR_OprList(); |