Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(835)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 5682 matching lines...) Expand 10 before | Expand all | Expand 10 after
5693 if (!is_smi()) { 5693 if (!is_smi()) {
5694 summary->set_temp(0, Location::RequiresRegister()); 5694 summary->set_temp(0, Location::RequiresRegister());
5695 } 5695 }
5696 summary->set_out(0, Location::RequiresRegister()); 5696 summary->set_out(0, Location::RequiresRegister());
5697 return summary; 5697 return summary;
5698 } 5698 }
5699 5699
5700 5700
5701 class BoxIntegerSlowPath : public SlowPathCode { 5701 class BoxIntegerSlowPath : public SlowPathCode {
5702 public: 5702 public:
5703 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5703 explicit BoxIntegerSlowPath(Definition* instruction)
5704 : instruction_(instruction) { } 5704 : instruction_(instruction) { }
5705 5705
5706 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5706 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5707 __ Comment("BoxIntegerSlowPath"); 5707 __ Comment("BoxIntegerSlowPath");
5708 __ Bind(entry_label()); 5708 __ Bind(entry_label());
5709 Isolate* isolate = compiler->isolate(); 5709 Isolate* isolate = compiler->isolate();
5710 StubCode* stub_code = isolate->stub_code(); 5710 StubCode* stub_code = isolate->stub_code();
5711 const Class& mint_class = 5711 const Class& mint_class =
5712 Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); 5712 Class::ZoneHandle(isolate, isolate->object_store()->mint_class());
5713 const Code& stub = 5713 const Code& stub =
5714 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5714 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5715 const ExternalLabel label(stub.EntryPoint()); 5715 const ExternalLabel label(stub.EntryPoint());
5716 5716
5717 LocationSummary* locs = instruction_->locs(); 5717 LocationSummary* locs = instruction_->locs();
5718 locs->live_registers()->Remove(locs->out(0)); 5718 locs->live_registers()->Remove(locs->out(0));
5719 5719
5720 compiler->SaveLiveRegisters(locs); 5720 compiler->SaveLiveRegisters(locs);
5721 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5721 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5722 &label, 5722 &label,
5723 RawPcDescriptors::kOther, 5723 RawPcDescriptors::kOther,
5724 locs); 5724 locs);
5725 __ MoveRegister(locs->out(0).reg(), EAX); 5725 __ MoveRegister(locs->out(0).reg(), EAX);
5726 compiler->RestoreLiveRegisters(locs); 5726 compiler->RestoreLiveRegisters(locs);
5727 5727
5728 __ jmp(exit_label()); 5728 __ jmp(exit_label());
5729 } 5729 }
5730 5730
5731 private: 5731 private:
5732 BoxIntegerInstr* instruction_; 5732 Definition* instruction_;
5733 }; 5733 };
5734 5734
5735 5735
5736 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5736 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5737 if (is_smi()) { 5737 if (is_smi()) {
5738 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 5738 PairLocation* value_pair = locs()->in(0).AsPairLocation();
5739 Register value_lo = value_pair->At(0).reg(); 5739 Register value_lo = value_pair->At(0).reg();
5740 Register out_reg = locs()->out(0).reg(); 5740 Register out_reg = locs()->out(0).reg();
5741 __ movl(out_reg, value_lo); 5741 __ movl(out_reg, value_lo);
5742 __ SmiTag(out_reg); 5742 __ SmiTag(out_reg);
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
5998 5998
5999 __ notl(left_lo); 5999 __ notl(left_lo);
6000 __ notl(left_hi); 6000 __ notl(left_hi);
6001 6001
6002 if (FLAG_throw_on_javascript_int_overflow) { 6002 if (FLAG_throw_on_javascript_int_overflow) {
6003 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6003 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6004 } 6004 }
6005 } 6005 }
6006 6006
6007 6007
6008 CompileType BinaryUint32OpInstr::ComputeType() const {
6009 return CompileType::Int();
6010 }
6011
6012
6013 CompileType ShiftUint32OpInstr::ComputeType() const {
6014 return CompileType::Int();
6015 }
6016
6017
6018 CompileType UnaryUint32OpInstr::ComputeType() const {
6019 return CompileType::Int();
6020 }
6021
6022
6023 CompileType BoxUint32Instr::ComputeType() const {
6024 return CompileType::Int();
6025 }
6026
6027
6028 CompileType UnboxUint32Instr::ComputeType() const {
6029 return CompileType::Int();
6030 }
6031
6032
6033 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6034 bool opt) const {
6035 const intptr_t kNumInputs = 2;
6036 const intptr_t kNumTemps = 0;
6037 LocationSummary* summary = new(isolate) LocationSummary(
6038 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6039 summary->set_in(0, Location::RequiresRegister());
6040 summary->set_in(1, Location::RequiresRegister());
6041 summary->set_out(0, Location::SameAsFirstInput());
6042 return summary;
6043 }
6044
6045
6046 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6047 Register left = locs()->in(0).reg();
6048 Register right = locs()->in(1).reg();
6049 Register out = locs()->out(0).reg();
6050 ASSERT(out == left);
6051 switch (op_kind()) {
6052 case Token::kBIT_AND:
6053 __ andl(out, right);
6054 break;
6055 case Token::kBIT_OR:
6056 __ orl(out, right);
6057 break;
6058 case Token::kBIT_XOR:
6059 __ xorl(out, right);
6060 break;
6061 case Token::kADD:
6062 __ addl(out, right);
6063 break;
6064 case Token::kSUB:
6065 __ subl(out, right);
6066 break;
6067 default:
6068 UNREACHABLE();
6069 }
6070 }
6071
6072
6073 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6074 bool opt) const {
6075 const intptr_t kNumInputs = 2;
6076 const intptr_t kNumTemps = 0;
6077 LocationSummary* summary = new(isolate) LocationSummary(
6078 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6079 summary->set_in(0, Location::RequiresRegister());
6080 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6081 summary->set_out(0, Location::SameAsFirstInput());
6082 return summary;
6083 }
6084
6085
6086 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6087 const intptr_t kShifterLimit = 31;
6088
6089 Register left = locs()->in(0).reg();
6090 Register out = locs()->out(0).reg();
6091 ASSERT(left == out);
6092
6093
6094 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6095
6096 if (locs()->in(1).IsConstant()) {
6097 // Shifter is constant.
6098
6099 const Object& constant = locs()->in(1).constant();
6100 ASSERT(constant.IsSmi());
6101 const intptr_t shift_value = Smi::Cast(constant).Value();
6102
6103 // Check constant shift value.
6104 if (shift_value == 0) {
6105 // Nothing to do.
6106 } else if (shift_value < 0) {
6107 // Invalid shift value.
6108 __ jmp(deopt);
6109 } else if (shift_value > kShifterLimit) {
6110 // Result is 0.
6111 __ xorl(left, left);
6112 } else {
6113 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6114 switch (op_kind()) {
6115 case Token::kSHR:
6116 __ shrl(left, Immediate(shift_value));
6117 break;
6118 case Token::kSHL:
6119 __ shll(left, Immediate(shift_value));
6120 break;
6121 default:
6122 UNREACHABLE();
6123 }
6124 }
6125 return;
6126 }
6127
6128 // Non constant shift value.
6129
6130 Register shifter = locs()->in(1).reg();
6131 ASSERT(shifter == ECX);
6132
6133 Label done;
6134 Label zero;
6135
6136 __ SmiUntag(shifter);
Vyacheslav Egorov (Google) 2014/07/08 12:39:31 You can add TODO shift code can be improved if we
6137 __ cmpl(shifter, Immediate(0));
6138 // If shift value is < 0, deoptimize.
6139 __ j(NEGATIVE, deopt);
6140 __ cmpl(shifter, Immediate(kShifterLimit));
6141 // If shift value is >= 32, return zero.
6142 __ j(ABOVE, &zero);
6143
6144 // Do the shift.
6145 switch (op_kind()) {
6146 case Token::kSHR:
6147 __ shrl(left, shifter);
6148 __ jmp(&done);
6149 break;
6150 case Token::kSHL:
6151 __ shll(left, shifter);
6152 __ jmp(&done);
6153 break;
6154 default:
6155 UNREACHABLE();
6156 }
6157
6158 __ Bind(&zero);
6159 // Shift was greater than 31 bits, just return zero.
6160 __ xorl(left, left);
6161
6162 // Exit path.
6163 __ Bind(&done);
6164 }
6165
6166
6167 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6168 bool opt) const {
6169 const intptr_t kNumInputs = 1;
6170 const intptr_t kNumTemps = 0;
6171 LocationSummary* summary = new(isolate) LocationSummary(
6172 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6173 summary->set_in(0, Location::RequiresRegister());
6174 summary->set_out(0, Location::SameAsFirstInput());
6175 return summary;
6176 }
6177
6178
6179 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6180 Register out = locs()->out(0).reg();
6181 ASSERT(locs()->in(0).reg() == out);
6182
6183 ASSERT(op_kind() == Token::kBIT_NOT);
6184
6185 __ notl(out);
6186 }
6187
6188
6189 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6190 bool opt) const {
6191 const intptr_t kNumInputs = 1;
6192 const intptr_t kNumTemps = 0;
6193 LocationSummary* summary = new(isolate) LocationSummary(
6194 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6195 summary->set_in(0, Location::RequiresRegister());
6196 summary->set_out(0, Location::RequiresRegister());
6197 return summary;
6198 }
6199
6200
6201 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6202 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6203 compiler->AddSlowPathCode(slow_path);
6204 Register value = locs()->in(0).reg();
6205 Register out = locs()->out(0).reg();
6206 ASSERT(value != out);
6207
6208 Label not_smi, done;
6209
6210 // Test if this value is <= kSmiMax.
6211 __ cmpl(value, Immediate(kSmiMax));
Vyacheslav Egorov (Google) 2014/07/08 12:39:31 TODO: take range information into account.
Cutch 2014/07/09 17:48:26 Done.
6212 __ j(ABOVE, &not_smi);
6213 // Smi.
6214 __ movl(out, value);
6215 __ SmiTag(out);
6216 __ jmp(&done);
6217 __ Bind(&not_smi);
6218 // Allocate a mint.
6219 __ TryAllocate(
6220 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6221 slow_path->entry_label(),
6222 Assembler::kFarJump,
6223 out,
6224 kNoRegister);
6225 __ Bind(slow_path->exit_label());
6226 // Copy low word into mint.
6227 __ movl(FieldAddress(out, Mint::value_offset()), value);
6228 // Zero high word.
6229 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0));
6230 __ Bind(&done);
6231 }
6232
6233
6234 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6235 bool opt) const {
6236 const intptr_t value_cid = value()->Type()->ToCid();
6237 const intptr_t kNumInputs = 1;
6238 const intptr_t kNumTemps =
6239 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6240 LocationSummary* summary = new(isolate) LocationSummary(
6241 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6242 summary->set_in(0, Location::RequiresRegister());
6243 if (kNumTemps > 0) {
6244 summary->set_temp(0, Location::RequiresRegister());
6245 }
6246 summary->set_out(0, Location::SameAsFirstInput());
6247 return summary;
6248 }
6249
6250
6251 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6252 const intptr_t value_cid = value()->Type()->ToCid();
6253 const Register value = locs()->in(0).reg();
6254 ASSERT(value == locs()->out(0).reg());
6255
6256 // TODO(johnmccutchan): Emit better code for constant inputs.
6257 if (value_cid == kMintCid) {
6258 __ movl(value, FieldAddress(value, Mint::value_offset()));
6259 } else if (value_cid == kSmiCid) {
6260 __ SmiUntag(value);
6261 } else {
6262 Register temp = locs()->temp(0).reg();
6263 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6264 ICData::kDeoptUnboxInteger);
6265 Label is_smi, done;
6266 __ testl(value, Immediate(kSmiTagMask));
6267 __ j(ZERO, &is_smi);
6268 __ CompareClassId(value, kMintCid, temp);
6269 __ j(NOT_EQUAL, deopt);
6270 __ movl(value, FieldAddress(value, Mint::value_offset()));
6271 __ jmp(&done);
6272 __ Bind(&is_smi);
6273 __ SmiUntag(value);
6274 __ Bind(&done);
6275 }
6276 }
6277
6278
6279 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6280 bool opt) const {
6281 const intptr_t kNumInputs = 1;
6282 const intptr_t kNumTemps = 0;
6283 LocationSummary* summary = new(isolate) LocationSummary(
6284 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6285 if (from() == kUnboxedMint) {
6286 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6287 Location::RequiresRegister()));
6288 summary->set_out(0, Location::RequiresRegister());
6289 } else {
6290 ASSERT(from() == kUnboxedUint32);
6291 summary->set_in(0, Location::RequiresRegister());
6292 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6293 Location::RequiresRegister()));
6294 }
6295 return summary;
6296 }
6297
6298
6299 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6300 if (from() == kUnboxedMint) {
6301 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6302 Register in_lo = in_pair->At(0).reg();
6303 Register out = locs()->out(0).reg();
6304 // Copy low word.
6305 __ movl(out, in_lo);
6306 } else {
6307 ASSERT(from() == kUnboxedUint32);
6308 Register in = locs()->in(0).reg();
6309 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6310 Register out_lo = out_pair->At(0).reg();
6311 Register out_hi = out_pair->At(1).reg();
6312 // Copy low word.
6313 __ movl(out_lo, in);
6314 // Zero upper word.
6315 __ xorl(out_hi, out_hi);
6316 }
6317 }
6318
6319
6008 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6320 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6009 bool opt) const { 6321 bool opt) const {
6010 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6322 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6011 } 6323 }
6012 6324
6013 6325
6014 6326
6015 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6327 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6016 compiler->GenerateRuntimeCall(token_pos(), 6328 compiler->GenerateRuntimeCall(token_pos(),
6017 deopt_id(), 6329 deopt_id(),
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
6359 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6671 __ movl(EDX, Immediate(kInvalidObjectPointer));
6360 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6672 __ movl(EDX, Immediate(kInvalidObjectPointer));
6361 #endif 6673 #endif
6362 } 6674 }
6363 6675
6364 } // namespace dart 6676 } // namespace dart
6365 6677
6366 #undef __ 6678 #undef __
6367 6679
6368 #endif // defined TARGET_ARCH_IA32 6680 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698