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

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

Issue 20369003: Implements far branch targets for MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
« no previous file with comments | « runtime/vm/disassembler_mips.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 __ sll(T2, T2, 1); // T2 is a Smi. 1045 __ sll(T2, T2, 1); // T2 is a Smi.
1046 1046
1047 __ Comment("Null arguments loop"); 1047 __ Comment("Null arguments loop");
1048 Label null_args_loop, null_args_loop_exit; 1048 Label null_args_loop, null_args_loop_exit;
1049 __ blez(T2, &null_args_loop_exit); 1049 __ blez(T2, &null_args_loop_exit);
1050 __ delay_slot()->addiu(T1, FP, 1050 __ delay_slot()->addiu(T1, FP,
1051 Immediate((kParamEndSlotFromFp + 1) * kWordSize)); 1051 Immediate((kParamEndSlotFromFp + 1) * kWordSize));
1052 __ Bind(&null_args_loop); 1052 __ Bind(&null_args_loop);
1053 __ addiu(T2, T2, Immediate(-kWordSize)); 1053 __ addiu(T2, T2, Immediate(-kWordSize));
1054 __ addu(T3, T1, T2); 1054 __ addu(T3, T1, T2);
1055 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null())); 1055 __ LoadImmediate(T5, reinterpret_cast<int32_t>(Object::null()));
1056 __ bgtz(T2, &null_args_loop); 1056 __ bgtz(T2, &null_args_loop);
1057 __ delay_slot()->sw(TMP, Address(T3)); 1057 __ delay_slot()->sw(T5, Address(T3));
1058 __ Bind(&null_args_loop_exit); 1058 __ Bind(&null_args_loop_exit);
1059 } 1059 }
1060 1060
1061 1061
1062 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { 1062 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
1063 // RA: return address. 1063 // RA: return address.
1064 // SP: receiver. 1064 // SP: receiver.
1065 // Sequence node has one return node, its input is load field node. 1065 // Sequence node has one return node, its input is load field node.
1066 __ lw(V0, Address(SP, 0 * kWordSize)); 1066 __ lw(V0, Address(SP, 0 * kWordSize));
1067 __ lw(V0, Address(V0, offset - kHeapObjectTag)); 1067 __ lw(V0, Address(V0, offset - kHeapObjectTag));
1068 __ Ret(); 1068 __ Ret();
1069 } 1069 }
1070 1070
1071 1071
1072 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) { 1072 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) {
1073 // RA: return address. 1073 // RA: return address.
1074 // SP+1: receiver. 1074 // SP+1: receiver.
1075 // SP+0: value. 1075 // SP+0: value.
1076 // Sequence node has one store node and one return NULL node. 1076 // Sequence node has one store node and one return NULL node.
1077 __ lw(T0, Address(SP, 1 * kWordSize)); // Receiver. 1077 __ lw(T0, Address(SP, 1 * kWordSize)); // Receiver.
1078 __ lw(T1, Address(SP, 0 * kWordSize)); // Value. 1078 __ lw(T1, Address(SP, 0 * kWordSize)); // Value.
1079 __ StoreIntoObject(T0, FieldAddress(T0, offset), T1); 1079 __ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
1080 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null())); 1080 __ LoadImmediate(V0, reinterpret_cast<int32_t>(Object::null()));
1081 __ Ret(); 1081 __ Ret();
1082 __ delay_slot()->mov(V0, TMP);
1083 } 1082 }
1084 1083
1085 1084
1086 void FlowGraphCompiler::EmitFrameEntry() { 1085 void FlowGraphCompiler::EmitFrameEntry() {
1087 const Function& function = parsed_function().function(); 1086 const Function& function = parsed_function().function();
1088 if (CanOptimizeFunction() && 1087 if (CanOptimizeFunction() &&
1089 function.is_optimizable() && 1088 function.is_optimizable() &&
1090 (!is_optimizing() || may_reoptimize())) { 1089 (!is_optimizing() || may_reoptimize())) {
1091 const Register function_reg = T0; 1090 const Register function_reg = T0;
1092 1091
1093 Label next; 1092 __ GetNextPC(T2, TMP);
1094 // The pool pointer is not setup before entering the Dart frame. 1093
1095 __ mov(TMP1, RA); // Save RA.
1096 __ bal(&next); // Branch and link to next instruction to get PC in RA.
1097 __ delay_slot()->mov(T2, RA); // Save PC of the following mov.
1098 // Calculate offset of pool pointer from the PC. 1094 // Calculate offset of pool pointer from the PC.
1099 const intptr_t object_pool_pc_dist = 1095 const intptr_t object_pool_pc_dist =
1100 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1096 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1101 assembler()->CodeSize(); 1097 assembler()->CodeSize() - 1 * Instr::kInstrSize;
1102 __ Bind(&next); 1098
1103 __ mov(RA, TMP1); // Restore RA.
1104 // Preserve PP of caller. 1099 // Preserve PP of caller.
1105 __ mov(T1, PP); 1100 __ mov(T1, PP);
1106 // Temporarily setup pool pointer for this dart function. 1101 // Temporarily setup pool pointer for this dart function.
1107 __ lw(PP, Address(T2, -object_pool_pc_dist)); 1102 __ lw(PP, Address(T2, -object_pool_pc_dist));
1108 // Load function object from object pool. 1103 // Load function object from object pool.
1109 __ LoadObject(function_reg, function); // Uses PP. 1104 __ LoadObject(function_reg, function); // Uses PP.
1110 // Restore PP of caller. 1105 // Restore PP of caller.
1111 __ mov(PP, T1); 1106 __ mov(PP, T1);
1112 1107
1113 // Patch point is after the eventually inlined function object. 1108 // Patch point is after the eventually inlined function object.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1474 __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1480 } 1475 }
1481 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, 1476 AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
1482 Isolate::kNoDeoptId, 1477 Isolate::kNoDeoptId,
1483 token_pos); 1478 token_pos);
1484 __ TraceSimMsg("EqualityRegConstCompare return"); 1479 __ TraceSimMsg("EqualityRegConstCompare return");
1485 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'. 1480 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'.
1486 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant. 1481 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant.
1487 return; 1482 return;
1488 } 1483 }
1489 __ CompareObject(CMPRES, TMP1, reg, obj); 1484 __ CompareObject(CMPRES1, CMPRES2, reg, obj);
1490 } 1485 }
1491 1486
1492 1487
1493 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1488 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
1494 Register right, 1489 Register right,
1495 bool needs_number_check, 1490 bool needs_number_check,
1496 intptr_t token_pos) { 1491 intptr_t token_pos) {
1497 __ TraceSimMsg("EqualityRegRegCompare"); 1492 __ TraceSimMsg("EqualityRegRegCompare");
1498 __ Comment("EqualityRegRegCompare"); 1493 __ Comment("EqualityRegRegCompare");
1499 if (needs_number_check) { 1494 if (needs_number_check) {
1500 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1495 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1501 __ sw(left, Address(SP, 1 * kWordSize)); 1496 __ sw(left, Address(SP, 1 * kWordSize));
1502 __ sw(right, Address(SP, 0 * kWordSize)); 1497 __ sw(right, Address(SP, 0 * kWordSize));
1503 if (is_optimizing()) { 1498 if (is_optimizing()) {
1504 __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel()); 1499 __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
1505 } else { 1500 } else {
1506 __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1501 __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1507 } 1502 }
1508 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, 1503 AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
1509 Isolate::kNoDeoptId, 1504 Isolate::kNoDeoptId,
1510 token_pos); 1505 token_pos);
1511 __ TraceSimMsg("EqualityRegRegCompare return"); 1506 __ TraceSimMsg("EqualityRegRegCompare return");
1512 // Stub returns result in CMPRES. If it is 0, then left and right are equal. 1507 // Stub returns result in CMPRES. If it is 0, then left and right are equal.
1513 __ lw(right, Address(SP, 0 * kWordSize)); 1508 __ lw(right, Address(SP, 0 * kWordSize));
1514 __ lw(left, Address(SP, 1 * kWordSize)); 1509 __ lw(left, Address(SP, 1 * kWordSize));
1515 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1510 __ addiu(SP, SP, Immediate(2 * kWordSize));
1516 } else { 1511 } else {
1517 __ slt(CMPRES, left, right); 1512 __ slt(CMPRES1, left, right);
1518 __ slt(TMP1, right, left); 1513 __ slt(CMPRES2, right, left);
1519 } 1514 }
1520 } 1515 }
1521 1516
1522 1517
1523 // Implement equality spec: if any of the arguments is null do identity check. 1518 // Implement equality spec: if any of the arguments is null do identity check.
1524 // Fallthrough calls super equality. 1519 // Fallthrough calls super equality.
1525 void FlowGraphCompiler::EmitSuperEqualityCallPrologue(Register result, 1520 void FlowGraphCompiler::EmitSuperEqualityCallPrologue(Register result,
1526 Label* skip_call) { 1521 Label* skip_call) {
1527 Label check_identity, is_false, fall_through; 1522 Label check_identity, is_false, fall_through;
1528 __ TraceSimMsg("SuperEqualityCallPrologue"); 1523 __ TraceSimMsg("SuperEqualityCallPrologue");
1529 __ lw(result, Address(SP, 0 * kWordSize)); // Load right operand. 1524 __ lw(result, Address(SP, 0 * kWordSize)); // Load right operand.
1530 __ lw(TMP1, Address(SP, 1 * kWordSize)); // Load left operand. 1525 __ lw(CMPRES1, Address(SP, 1 * kWordSize)); // Load left operand.
1531 __ LoadImmediate(CMPRES, reinterpret_cast<int32_t>(Object::null())); 1526 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
1532 __ beq(result, CMPRES, &check_identity); // Is right null? 1527 __ beq(result, TMP, &check_identity); // Is right null?
1533 __ bne(TMP1, CMPRES, &fall_through); // If right is non-null, check left. 1528 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
1529 __ bne(TMP, CMPRES1, &fall_through); // If right is non-null, check left.
1534 1530
1535 __ Bind(&check_identity); 1531 __ Bind(&check_identity);
1536 __ bne(result, TMP1, &is_false); 1532 __ bne(result, CMPRES1, &is_false);
1537 __ LoadObject(result, Bool::True()); 1533 __ LoadObject(result, Bool::True());
1538 __ Drop(2); 1534 __ Drop(2);
1539 __ b(skip_call); 1535 __ b(skip_call);
1540 __ Bind(&is_false); 1536 __ Bind(&is_false);
1541 __ LoadObject(result, Bool::False()); 1537 __ LoadObject(result, Bool::False());
1542 __ Drop(2); 1538 __ Drop(2);
1543 __ b(skip_call); 1539 __ b(skip_call);
1544 __ Bind(&fall_through); 1540 __ Bind(&fall_through);
1545 } 1541 }
1546 1542
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 case GE: assembler()->coled(right, left); break; 1682 case GE: assembler()->coled(right, left); break;
1687 default: { 1683 default: {
1688 // Should only passing the above conditions to this function. 1684 // Should only passing the above conditions to this function.
1689 UNREACHABLE(); 1685 UNREACHABLE();
1690 break; 1686 break;
1691 } 1687 }
1692 } 1688 }
1693 1689
1694 assembler()->LoadImmediate(TMP, 1); 1690 assembler()->LoadImmediate(TMP, 1);
1695 if (true_condition == NE) { 1691 if (true_condition == NE) {
1696 assembler()->movf(CMPRES, ZR); 1692 assembler()->movf(CMPRES1, ZR);
1697 assembler()->movt(CMPRES, TMP); 1693 assembler()->movt(CMPRES1, TMP);
1698 } else { 1694 } else {
1699 assembler()->movf(CMPRES, TMP); 1695 assembler()->movf(CMPRES1, TMP);
1700 assembler()->movt(CMPRES, ZR); 1696 assembler()->movt(CMPRES1, ZR);
1701 } 1697 }
1702 assembler()->mov(TMP, ZR); 1698 assembler()->mov(CMPRES2, ZR);
1703 1699
1704 // EmitBranchOnCondition expects ordering to be described by CMPRES, TMP1. 1700 // EmitBranchOnCondition expects ordering to be described by CMPRES, CMPRES2.
1705 branch->EmitBranchOnCondition(this, EQ); 1701 branch->EmitBranchOnCondition(this, EQ);
1706 } 1702 }
1707 1703
1708 1704
1709 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition, 1705 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
1710 FpuRegister left, 1706 FpuRegister left,
1711 FpuRegister right, 1707 FpuRegister right,
1712 Register result) { 1708 Register result) {
1713 Label done; 1709 Label done;
1714 __ Comment("DoubleCompareBool"); 1710 __ Comment("DoubleCompareBool");
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 __ AddImmediate(SP, kDoubleSize); 1995 __ AddImmediate(SP, kDoubleSize);
2000 } 1996 }
2001 1997
2002 1998
2003 #undef __ 1999 #undef __
2004 2000
2005 2001
2006 } // namespace dart 2002 } // namespace dart
2007 2003
2008 #endif // defined TARGET_ARCH_MIPS 2004 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_mips.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698