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

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 5695 matching lines...) Expand 10 before | Expand all | Expand 10 after
5706 if (!is_smi()) { 5706 if (!is_smi()) {
5707 summary->set_temp(0, Location::RequiresRegister()); 5707 summary->set_temp(0, Location::RequiresRegister());
5708 } 5708 }
5709 summary->set_out(0, Location::RequiresRegister()); 5709 summary->set_out(0, Location::RequiresRegister());
5710 return summary; 5710 return summary;
5711 } 5711 }
5712 5712
5713 5713
5714 class BoxIntegerSlowPath : public SlowPathCode { 5714 class BoxIntegerSlowPath : public SlowPathCode {
5715 public: 5715 public:
5716 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5716 explicit BoxIntegerSlowPath(Definition* instruction)
5717 : instruction_(instruction) { } 5717 : instruction_(instruction) { }
5718 5718
5719 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5719 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5720 __ Comment("BoxIntegerSlowPath"); 5720 __ Comment("BoxIntegerSlowPath");
5721 __ Bind(entry_label()); 5721 __ Bind(entry_label());
5722 Isolate* isolate = compiler->isolate(); 5722 Isolate* isolate = compiler->isolate();
5723 StubCode* stub_code = isolate->stub_code(); 5723 StubCode* stub_code = isolate->stub_code();
5724 const Class& mint_class = 5724 const Class& mint_class =
5725 Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); 5725 Class::ZoneHandle(isolate, isolate->object_store()->mint_class());
5726 const Code& stub = 5726 const Code& stub =
5727 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5727 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5728 const ExternalLabel label(stub.EntryPoint()); 5728 const ExternalLabel label(stub.EntryPoint());
5729 5729
5730 LocationSummary* locs = instruction_->locs(); 5730 LocationSummary* locs = instruction_->locs();
5731 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 5731 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
5732 5732
5733 compiler->SaveLiveRegisters(locs); 5733 compiler->SaveLiveRegisters(locs);
5734 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5734 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5735 &label, 5735 &label,
5736 RawPcDescriptors::kOther, 5736 RawPcDescriptors::kOther,
5737 locs); 5737 locs);
5738 __ MoveRegister(locs->out(0).reg(), EAX); 5738 __ MoveRegister(locs->out(0).reg(), EAX);
5739 compiler->RestoreLiveRegisters(locs); 5739 compiler->RestoreLiveRegisters(locs);
5740 5740
5741 __ jmp(exit_label()); 5741 __ jmp(exit_label());
5742 } 5742 }
5743 5743
5744 private: 5744 private:
5745 BoxIntegerInstr* instruction_; 5745 Definition* instruction_;
5746 }; 5746 };
5747 5747
5748 5748
5749 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5749 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5750 if (is_smi()) { 5750 if (is_smi()) {
5751 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 5751 PairLocation* value_pair = locs()->in(0).AsPairLocation();
5752 Register value_lo = value_pair->At(0).reg(); 5752 Register value_lo = value_pair->At(0).reg();
5753 Register out_reg = locs()->out(0).reg(); 5753 Register out_reg = locs()->out(0).reg();
5754 __ movl(out_reg, value_lo); 5754 __ movl(out_reg, value_lo);
5755 __ SmiTag(out_reg); 5755 __ SmiTag(out_reg);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
6045 6045
6046 __ notl(left_lo); 6046 __ notl(left_lo);
6047 __ notl(left_hi); 6047 __ notl(left_hi);
6048 6048
6049 if (FLAG_throw_on_javascript_int_overflow) { 6049 if (FLAG_throw_on_javascript_int_overflow) {
6050 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6050 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6051 } 6051 }
6052 } 6052 }
6053 6053
6054 6054
6055 CompileType BinaryUint32OpInstr::ComputeType() const {
6056 return CompileType::Int();
6057 }
6058
6059
6060 CompileType ShiftUint32OpInstr::ComputeType() const {
6061 return CompileType::Int();
6062 }
6063
6064
6065 CompileType UnaryUint32OpInstr::ComputeType() const {
6066 return CompileType::Int();
6067 }
6068
6069
6070 CompileType BoxUint32Instr::ComputeType() const {
6071 return CompileType::Int();
6072 }
6073
6074
6075 CompileType UnboxUint32Instr::ComputeType() const {
6076 return CompileType::Int();
6077 }
6078
6079
6080 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6081 bool opt) const {
6082 const intptr_t kNumInputs = 2;
6083 const intptr_t kNumTemps = 0;
6084 LocationSummary* summary = new(isolate) LocationSummary(
6085 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6086 summary->set_in(0, Location::RequiresRegister());
6087 summary->set_in(1, Location::RequiresRegister());
6088 summary->set_out(0, Location::SameAsFirstInput());
6089 return summary;
6090 }
6091
6092
6093 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6094 Register left = locs()->in(0).reg();
6095 Register right = locs()->in(1).reg();
6096 Register out = locs()->out(0).reg();
6097 ASSERT(out == left);
6098 switch (op_kind()) {
6099 case Token::kBIT_AND:
6100 __ andl(out, right);
6101 break;
6102 case Token::kBIT_OR:
6103 __ orl(out, right);
6104 break;
6105 case Token::kBIT_XOR:
6106 __ xorl(out, right);
6107 break;
6108 case Token::kADD:
6109 __ addl(out, right);
6110 break;
6111 case Token::kSUB:
6112 __ subl(out, right);
6113 break;
6114 default:
6115 UNREACHABLE();
6116 }
6117 }
6118
6119
6120 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6121 bool opt) const {
6122 const intptr_t kNumInputs = 2;
6123 const intptr_t kNumTemps = 0;
6124 LocationSummary* summary = new(isolate) LocationSummary(
6125 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6126 summary->set_in(0, Location::RequiresRegister());
6127 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6128 summary->set_out(0, Location::SameAsFirstInput());
6129 return summary;
6130 }
6131
6132
6133 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6134 const intptr_t kShifterLimit = 31;
6135
6136 Register left = locs()->in(0).reg();
6137 Register out = locs()->out(0).reg();
6138 ASSERT(left == out);
6139
6140
6141 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6142
6143 if (locs()->in(1).IsConstant()) {
6144 // Shifter is constant.
6145
6146 const Object& constant = locs()->in(1).constant();
6147 ASSERT(constant.IsSmi());
6148 const intptr_t shift_value = Smi::Cast(constant).Value();
6149
6150 // Check constant shift value.
6151 if (shift_value == 0) {
6152 // Nothing to do.
6153 } else if (shift_value < 0) {
6154 // Invalid shift value.
6155 __ jmp(deopt);
6156 } else if (shift_value > kShifterLimit) {
6157 // Result is 0.
6158 __ xorl(left, left);
6159 } else {
6160 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6161 switch (op_kind()) {
6162 case Token::kSHR:
6163 __ shrl(left, Immediate(shift_value));
6164 break;
6165 case Token::kSHL:
6166 __ shll(left, Immediate(shift_value));
6167 break;
6168 default:
6169 UNREACHABLE();
6170 }
6171 }
6172 return;
6173 }
6174
6175 // Non constant shift value.
6176
6177 Register shifter = locs()->in(1).reg();
6178 ASSERT(shifter == ECX);
6179
6180 Label done;
6181 Label zero;
6182
6183 // TODO(johnmccutchan): Use range information to avoid these checks.
6184 __ SmiUntag(shifter);
6185 __ cmpl(shifter, Immediate(0));
6186 // If shift value is < 0, deoptimize.
6187 __ j(NEGATIVE, deopt);
6188 __ cmpl(shifter, Immediate(kShifterLimit));
6189 // If shift value is >= 32, return zero.
6190 __ j(ABOVE, &zero);
6191
6192 // Do the shift.
6193 switch (op_kind()) {
6194 case Token::kSHR:
6195 __ shrl(left, shifter);
6196 __ jmp(&done);
6197 break;
6198 case Token::kSHL:
6199 __ shll(left, shifter);
6200 __ jmp(&done);
6201 break;
6202 default:
6203 UNREACHABLE();
6204 }
6205
6206 __ Bind(&zero);
6207 // Shift was greater than 31 bits, just return zero.
6208 __ xorl(left, left);
6209
6210 // Exit path.
6211 __ Bind(&done);
6212 }
6213
6214
6215 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6216 bool opt) const {
6217 const intptr_t kNumInputs = 1;
6218 const intptr_t kNumTemps = 0;
6219 LocationSummary* summary = new(isolate) LocationSummary(
6220 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6221 summary->set_in(0, Location::RequiresRegister());
6222 summary->set_out(0, Location::SameAsFirstInput());
6223 return summary;
6224 }
6225
6226
6227 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6228 Register out = locs()->out(0).reg();
6229 ASSERT(locs()->in(0).reg() == out);
6230
6231 ASSERT(op_kind() == Token::kBIT_NOT);
6232
6233 __ notl(out);
6234 }
6235
6236
6237 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6238 bool opt) const {
6239 const intptr_t kNumInputs = 1;
6240 const intptr_t kNumTemps = 0;
6241 LocationSummary* summary = new(isolate) LocationSummary(
6242 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6243 summary->set_in(0, Location::RequiresRegister());
6244 summary->set_out(0, Location::RequiresRegister());
6245 return summary;
6246 }
6247
6248
6249 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6250 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6251 compiler->AddSlowPathCode(slow_path);
6252 Register value = locs()->in(0).reg();
6253 Register out = locs()->out(0).reg();
6254 ASSERT(value != out);
6255
6256 Label not_smi, done;
6257
6258 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing.
6259 // Test if this value is <= kSmiMax.
6260 __ cmpl(value, Immediate(kSmiMax));
6261 __ j(ABOVE, &not_smi);
6262 // Smi.
6263 __ movl(out, value);
6264 __ SmiTag(out);
6265 __ jmp(&done);
6266 __ Bind(&not_smi);
6267 // Allocate a mint.
6268 __ TryAllocate(
6269 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6270 slow_path->entry_label(),
6271 Assembler::kFarJump,
6272 out,
6273 kNoRegister);
6274 __ Bind(slow_path->exit_label());
6275 // Copy low word into mint.
6276 __ movl(FieldAddress(out, Mint::value_offset()), value);
6277 // Zero high word.
6278 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0));
6279 __ Bind(&done);
6280 }
6281
6282
6283 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6284 bool opt) const {
6285 const intptr_t value_cid = value()->Type()->ToCid();
6286 const intptr_t kNumInputs = 1;
6287 const intptr_t kNumTemps =
6288 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6289 LocationSummary* summary = new(isolate) LocationSummary(
6290 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6291 summary->set_in(0, Location::RequiresRegister());
6292 if (kNumTemps > 0) {
6293 summary->set_temp(0, Location::RequiresRegister());
6294 }
6295 summary->set_out(0, Location::SameAsFirstInput());
6296 return summary;
6297 }
6298
6299
6300 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6301 const intptr_t value_cid = value()->Type()->ToCid();
6302 const Register value = locs()->in(0).reg();
6303 ASSERT(value == locs()->out(0).reg());
6304
6305 // TODO(johnmccutchan): Emit better code for constant inputs.
6306 if (value_cid == kMintCid) {
6307 __ movl(value, FieldAddress(value, Mint::value_offset()));
6308 } else if (value_cid == kSmiCid) {
6309 __ SmiUntag(value);
6310 } else {
6311 Register temp = locs()->temp(0).reg();
6312 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6313 ICData::kDeoptUnboxInteger);
6314 Label is_smi, done;
6315 __ testl(value, Immediate(kSmiTagMask));
6316 __ j(ZERO, &is_smi);
6317 __ CompareClassId(value, kMintCid, temp);
6318 __ j(NOT_EQUAL, deopt);
6319 __ movl(value, FieldAddress(value, Mint::value_offset()));
6320 __ jmp(&done);
6321 __ Bind(&is_smi);
6322 __ SmiUntag(value);
6323 __ Bind(&done);
6324 }
6325 }
6326
6327
6328 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6329 bool opt) const {
6330 const intptr_t kNumInputs = 1;
6331 const intptr_t kNumTemps = 0;
6332 LocationSummary* summary = new(isolate) LocationSummary(
6333 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6334 if (from() == kUnboxedMint) {
6335 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6336 Location::RequiresRegister()));
6337 summary->set_out(0, Location::RequiresRegister());
6338 } else {
6339 ASSERT(from() == kUnboxedUint32);
6340 summary->set_in(0, Location::RequiresRegister());
6341 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6342 Location::RequiresRegister()));
6343 }
6344 return summary;
6345 }
6346
6347
6348 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6349 if (from() == kUnboxedMint) {
6350 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6351 Register in_lo = in_pair->At(0).reg();
6352 Register out = locs()->out(0).reg();
6353 // Copy low word.
6354 __ movl(out, in_lo);
6355 } else {
6356 ASSERT(from() == kUnboxedUint32);
6357 Register in = locs()->in(0).reg();
6358 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6359 Register out_lo = out_pair->At(0).reg();
6360 Register out_hi = out_pair->At(1).reg();
6361 // Copy low word.
6362 __ movl(out_lo, in);
6363 // Zero upper word.
6364 __ xorl(out_hi, out_hi);
6365 }
6366 }
6367
6368
6055 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6369 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6056 bool opt) const { 6370 bool opt) const {
6057 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6371 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6058 } 6372 }
6059 6373
6060 6374
6061 6375
6062 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6376 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6063 compiler->GenerateRuntimeCall(token_pos(), 6377 compiler->GenerateRuntimeCall(token_pos(),
6064 deopt_id(), 6378 deopt_id(),
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
6406 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6720 __ movl(EDX, Immediate(kInvalidObjectPointer));
6407 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6721 __ movl(EDX, Immediate(kInvalidObjectPointer));
6408 #endif 6722 #endif
6409 } 6723 }
6410 6724
6411 } // namespace dart 6725 } // namespace dart
6412 6726
6413 #undef __ 6727 #undef __
6414 6728
6415 #endif // defined TARGET_ARCH_IA32 6729 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698