| Index: runtime/vm/intermediate_language_mips.cc
|
| diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
|
| index 7236c569fa6c14371eda18e81b992c0d4ca3d279..ed03d1d19a80cb81d34d5c7876f904d2a9497478 100644
|
| --- a/runtime/vm/intermediate_language_mips.cc
|
| +++ b/runtime/vm/intermediate_language_mips.cc
|
| @@ -3063,24 +3063,6 @@ void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| case Token::kBIT_XOR:
|
| __ xor_(result, left, right);
|
| break;
|
| - case Token::kEQ:
|
| - case Token::kLT:
|
| - case Token::kLTE:
|
| - case Token::kGT:
|
| - case Token::kGTE: {
|
| - Label true_label, false_label, done;
|
| - BranchLabels labels = { &true_label, &false_label, &false_label };
|
| - Condition true_condition =
|
| - EmitSmiComparisonOp(compiler, *locs(), op_kind());
|
| - EmitBranchOnCondition(compiler, true_condition, labels);
|
| - __ Bind(&false_label);
|
| - __ LoadObject(result, Bool::False());
|
| - __ b(&done);
|
| - __ Bind(&true_label);
|
| - __ LoadObject(result, Bool::True());
|
| - __ Bind(&done);
|
| - break;
|
| - }
|
| default:
|
| UNIMPLEMENTED();
|
| }
|
| @@ -3088,6 +3070,135 @@ void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| +class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
| + public:
|
| + CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction,
|
| + intptr_t try_index,
|
| + BranchLabels labels,
|
| + bool merged)
|
| + : instruction_(instruction),
|
| + try_index_(try_index),
|
| + labels_(labels),
|
| + merged_(merged) { }
|
| +
|
| + virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + if (Assembler::EmittingComments()) {
|
| + __ Comment("slow path smi operation");
|
| + }
|
| + __ Bind(entry_label());
|
| + LocationSummary* locs = instruction_->locs();
|
| + Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg();
|
| + locs->live_registers()->Remove(Location::RegisterLocation(result));
|
| +
|
| + compiler->SaveLiveRegisters(locs);
|
| + __ Push(locs->in(0).reg());
|
| + __ Push(locs->in(1).reg());
|
| + compiler->EmitMegamorphicInstanceCall(
|
| + *instruction_->call()->ic_data(),
|
| + instruction_->call()->ArgumentCount(),
|
| + instruction_->call()->deopt_id(),
|
| + instruction_->call()->token_pos(),
|
| + locs,
|
| + try_index_,
|
| + /* slow_path_argument_count = */ 2);
|
| + __ mov(result, V0);
|
| + compiler->RestoreLiveRegisters(locs);
|
| + if (merged_) {
|
| + __ BranchEqual(result, Bool::True(),
|
| + instruction_->is_negated() ? labels_.false_label : labels_.true_label);
|
| + __ b(instruction_->is_negated()
|
| + ? labels_.true_label : labels_.false_label);
|
| + } else {
|
| + __ b(exit_label());
|
| + }
|
| + }
|
| +
|
| + private:
|
| + CheckedSmiComparisonInstr* instruction_;
|
| + intptr_t try_index_;
|
| + BranchLabels labels_;
|
| + bool merged_;
|
| +};
|
| +
|
| +
|
| +LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
|
| + Zone* zone, bool opt) const {
|
| + const intptr_t kNumInputs = 2;
|
| + const intptr_t kNumTemps = 1;
|
| + LocationSummary* summary = new(zone) LocationSummary(
|
| + zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
|
| + summary->set_in(0, Location::RequiresRegister());
|
| + summary->set_in(1, Location::RequiresRegister());
|
| + summary->set_temp(0, Location::RequiresRegister());
|
| + summary->set_out(0, Location::RequiresRegister());
|
| + return summary;
|
| +}
|
| +
|
| +
|
| +Condition CheckedSmiComparisonInstr::EmitComparisonCode(
|
| + FlowGraphCompiler* compiler, BranchLabels labels) {
|
| + return EmitSmiComparisonOp(compiler, *locs(), kind());
|
| +}
|
| +
|
| +
|
| +#define EMIT_SMI_CHECK \
|
| + Register left = locs()->in(0).reg(); \
|
| + Register right = locs()->in(1).reg(); \
|
| + Register temp = locs()->temp(0).reg(); \
|
| + intptr_t left_cid = this->left()->Type()->ToCid(); \
|
| + intptr_t right_cid = this->right()->Type()->ToCid(); \
|
| + if (this->left()->definition() == this->right()->definition()) { \
|
| + __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \
|
| + } else if (left_cid == kSmiCid) { \
|
| + __ andi(CMPRES1, right, Immediate(kSmiTagMask)); \
|
| + } else if (right_cid == kSmiCid) { \
|
| + __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \
|
| + } else { \
|
| + __ or_(temp, left, right); \
|
| + __ andi(CMPRES1, temp, Immediate(kSmiTagMask)); \
|
| + } \
|
| + __ bne(CMPRES1, ZR, slow_path->entry_label()); \
|
| +
|
| +
|
| +void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
|
| + BranchInstr* branch) {
|
| + BranchLabels labels = compiler->CreateBranchLabels(branch);
|
| + CheckedSmiComparisonSlowPath* slow_path =
|
| + new CheckedSmiComparisonSlowPath(this,
|
| + compiler->CurrentTryIndex(),
|
| + labels,
|
| + /* merged = */ true);
|
| + compiler->AddSlowPathCode(slow_path);
|
| + EMIT_SMI_CHECK;
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| + __ Bind(slow_path->exit_label());
|
| +}
|
| +
|
| +
|
| +void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + Label true_label, false_label, done;
|
| + BranchLabels labels = { &true_label, &false_label, &false_label };
|
| + CheckedSmiComparisonSlowPath* slow_path =
|
| + new CheckedSmiComparisonSlowPath(this,
|
| + compiler->CurrentTryIndex(),
|
| + labels,
|
| + /* merged = */ false);
|
| + compiler->AddSlowPathCode(slow_path);
|
| + EMIT_SMI_CHECK;
|
| + Condition true_condition = EmitComparisonCode(compiler, labels);
|
| + EmitBranchOnCondition(compiler, true_condition, labels);
|
| + Register result = locs()->out(0).reg();
|
| + __ Bind(&false_label);
|
| + __ LoadObject(result, Bool::False());
|
| + __ b(&done);
|
| + __ Bind(&true_label);
|
| + __ LoadObject(result, Bool::True());
|
| + __ Bind(&done);
|
| + __ Bind(slow_path->exit_label());
|
| +}
|
| +
|
| +
|
| LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
|
| bool opt) const {
|
| const intptr_t kNumInputs = 2;
|
|
|