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

Unified Diff: runtime/vm/assembler_mips.h

Issue 817593002: Improve generated MIPS code for conditional expressions and branches by delaying (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | runtime/vm/constants_mips.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_mips.h
===================================================================
--- runtime/vm/assembler_mips.h (revision 42479)
+++ runtime/vm/assembler_mips.h (working copy)
@@ -934,6 +934,184 @@
}
}
+ void OrImmediate(Register rd, Register rs, int32_t imm) {
+ ASSERT(!in_delay_slot_);
+ if (imm == 0) {
+ mov(rd, rs);
+ return;
+ }
+
+ if (Utils::IsUint(kImmBits, imm)) {
+ ori(rd, rs, Immediate(imm));
+ } else {
+ LoadImmediate(TMP, imm);
+ or_(rd, rs, TMP);
+ }
+ }
+
+ void XorImmediate(Register rd, Register rs, int32_t imm) {
+ ASSERT(!in_delay_slot_);
+ if (imm == 0) {
+ mov(rd, rs);
+ return;
+ }
+
+ if (Utils::IsUint(kImmBits, imm)) {
+ xori(rd, rs, Immediate(imm));
+ } else {
+ LoadImmediate(TMP, imm);
+ xor_(rd, rs, TMP);
+ }
+ }
+
+ // Branch to label if condition is true.
+ void BranchOnCondition(Condition cond, Label* l) {
+ ASSERT(!in_delay_slot_);
+ Register left = cond.left();
+ Register right = cond.right();
+ RelationOperator rel_op = cond.rel_op();
+ switch (rel_op) {
+ case NV: return;
+ case AL: b(l); return;
+ case EQ: // fall through.
+ case NE: {
+ if (left == IMM) {
+ addiu(AT, ZR, Immediate(cond.imm()));
zra 2014/12/19 17:49:47 Why not LoadImmediate?
regis 2014/12/22 20:17:34 I like to see exactly what instruction we generate
+ left = AT;
+ } else if (right == IMM) {
+ addiu(AT, ZR, Immediate(cond.imm()));
+ right = AT;
+ }
+ if (rel_op == EQ) {
+ beq(left, right, l);
+ } else {
+ bne(left, right, l);
+ }
+ break;
+ }
+ case GT: {
+ if (left == ZR) {
+ bltz(right, l);
+ } else if (right == ZR) {
+ bgtz(left, l);
+ } else if (left == IMM) {
+ slti(AT, right, Immediate(cond.imm()));
+ bne(AT, ZR, l);
+ } else if (right == IMM) {
+ slti(AT, left, Immediate(cond.imm() + 1));
+ beq(AT, ZR, l);
+ } else {
+ slt(AT, right, left);
+ bne(AT, ZR, l);
+ }
+ break;
+ }
+ case GE: {
+ if (left == ZR) {
+ blez(right, l);
+ } else if (right == ZR) {
+ bgez(left, l);
+ } else if (left == IMM) {
+ slti(AT, right, Immediate(cond.imm() + 1));
+ bne(AT, ZR, l);
+ } else if (right == IMM) {
+ slti(AT, left, Immediate(cond.imm()));
+ beq(AT, ZR, l);
+ } else {
+ slt(AT, left, right);
+ beq(AT, ZR, l);
+ }
+ break;
+ }
+ case LT: {
+ if (left == ZR) {
+ bgtz(right, l);
+ } else if (right == ZR) {
+ bltz(left, l);
+ } else if (left == IMM) {
+ slti(AT, right, Immediate(cond.imm() + 1));
+ beq(AT, ZR, l);
+ } else if (right == IMM) {
+ slti(AT, left, Immediate(cond.imm()));
+ bne(AT, ZR, l);
+ } else {
+ slt(AT, left, right);
+ bne(AT, ZR, l);
+ }
+ break;
+ }
+ case LE: {
+ if (left == ZR) {
+ bgez(right, l);
+ } else if (right == ZR) {
+ blez(left, l);
+ } else if (left == IMM) {
+ slti(AT, right, Immediate(cond.imm()));
+ beq(AT, ZR, l);
+ } else if (right == IMM) {
+ slti(AT, left, Immediate(cond.imm() + 1));
+ bne(AT, ZR, l);
+ } else {
+ slt(AT, right, left);
+ beq(AT, ZR, l);
+ }
+ break;
+ }
+ case UGT: {
+ ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
zra 2014/12/19 17:49:47 What do you do if you want to branch on an unsigne
regis 2014/12/22 20:17:34 This does not come up. The compiler will always al
+ if (left == ZR) {
+ // NV: Never branch. Fall through.
+ } else if (right == ZR) {
+ bne(left, ZR, l);
+ } else {
+ sltu(AT, right, left);
+ bne(AT, ZR, l);
+ }
+ break;
+ }
+ case UGE: {
+ ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
+ if (left == ZR) {
+ beq(right, ZR, l);
+ } else if (right == ZR) {
+ // AL: Always branch to l.
+ beq(ZR, ZR, l);
+ } else {
+ sltu(AT, left, right);
+ beq(AT, ZR, l);
+ }
+ break;
+ }
+ case ULT: {
+ ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
+ if (left == ZR) {
+ bne(right, ZR, l);
+ } else if (right == ZR) {
+ // NV: Never branch. Fall through.
+ } else {
+ sltu(AT, left, right);
+ bne(AT, ZR, l);
+ }
+ break;
+ }
+ case ULE: {
+ ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
+ if (left == ZR) {
+ // AL: Always branch to l.
+ beq(ZR, ZR, l);
+ } else if (right == ZR) {
+ beq(left, ZR, l);
+ } else {
+ sltu(AT, right, left);
+ beq(AT, ZR, l);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+
void BranchEqual(Register rd, Register rn, Label* l) {
beq(rd, rn, l);
}
@@ -989,9 +1167,14 @@
if (imm.value() == 0) {
bgtz(rd, l);
} else {
- ASSERT(rd != CMPRES2);
- LoadImmediate(CMPRES2, imm.value());
- BranchSignedGreater(rd, CMPRES2, l);
+ if (Utils::IsInt(kImmBits, imm.value() + 1)) {
+ slti(CMPRES2, rd, Immediate(imm.value() + 1));
+ beq(CMPRES2, ZR, l);
+ } else {
+ ASSERT(rd != CMPRES2);
+ LoadImmediate(CMPRES2, imm.value());
+ BranchSignedGreater(rd, CMPRES2, l);
+ }
}
}
@@ -1006,9 +1189,14 @@
if (imm.value() == 0) {
BranchNotEqual(rd, Immediate(0), l);
} else {
- ASSERT(rd != CMPRES2);
- LoadImmediate(CMPRES2, imm.value());
- BranchUnsignedGreater(rd, CMPRES2, l);
+ if ((imm.value() != -1) && Utils::IsInt(kImmBits, imm.value() + 1)) {
+ sltiu(CMPRES2, rd, Immediate(imm.value() + 1));
+ beq(CMPRES2, ZR, l);
+ } else {
+ ASSERT(rd != CMPRES2);
+ LoadImmediate(CMPRES2, imm.value());
+ BranchUnsignedGreater(rd, CMPRES2, l);
+ }
}
}
@@ -1045,7 +1233,7 @@
if (imm.value() == 0) {
b(l);
} else {
- if (Utils::IsUint(kImmBits, imm.value())) {
+ if (Utils::IsInt(kImmBits, imm.value())) {
sltiu(CMPRES2, rd, imm);
beq(CMPRES2, ZR, l);
} else {
@@ -1084,14 +1272,17 @@
void BranchUnsignedLess(Register rd, const Immediate& imm, Label* l) {
ASSERT(!in_delay_slot_);
- ASSERT(imm.value() != 0);
- if (Utils::IsInt(kImmBits, imm.value())) {
- sltiu(CMPRES2, rd, imm);
- bne(CMPRES2, ZR, l);
+ if (imm.value() == 0) {
+ // Never branch. Fall through.
} else {
- ASSERT(rd != CMPRES2);
- LoadImmediate(CMPRES2, imm.value());
- BranchUnsignedGreater(CMPRES2, rd, l);
+ if (Utils::IsInt(kImmBits, imm.value())) {
+ sltiu(CMPRES2, rd, imm);
+ bne(CMPRES2, ZR, l);
+ } else {
+ ASSERT(rd != CMPRES2);
+ LoadImmediate(CMPRES2, imm.value());
+ BranchUnsignedGreater(CMPRES2, rd, l);
+ }
}
}
@@ -1105,9 +1296,14 @@
if (imm.value() == 0) {
blez(rd, l);
} else {
- ASSERT(rd != CMPRES2);
- LoadImmediate(CMPRES2, imm.value());
- BranchSignedGreaterEqual(CMPRES2, rd, l);
+ if (Utils::IsInt(kImmBits, imm.value() + 1)) {
+ slti(CMPRES2, rd, Immediate(imm.value() + 1));
+ bne(CMPRES2, ZR, l);
+ } else {
+ ASSERT(rd != CMPRES2);
+ LoadImmediate(CMPRES2, imm.value());
+ BranchSignedGreaterEqual(CMPRES2, rd, l);
+ }
}
}
@@ -1118,9 +1314,18 @@
void BranchUnsignedLessEqual(Register rd, const Immediate& imm, Label* l) {
ASSERT(!in_delay_slot_);
- ASSERT(rd != CMPRES2);
- LoadImmediate(CMPRES2, imm.value());
- BranchUnsignedGreaterEqual(CMPRES2, rd, l);
+ if (imm.value() == 0) {
+ beq(rd, ZR, l);
+ } else {
+ if ((imm.value() != -1) && Utils::IsInt(kImmBits, imm.value() + 1)) {
+ sltiu(CMPRES2, rd, Immediate(imm.value() + 1));
+ bne(CMPRES2, ZR, l);
+ } else {
+ ASSERT(rd != CMPRES2);
+ LoadImmediate(CMPRES2, imm.value());
+ BranchUnsignedGreaterEqual(CMPRES2, rd, l);
+ }
+ }
}
void Push(Register rt) {
@@ -1218,12 +1423,6 @@
void LoadObject(Register rd, const Object& object);
void PushObject(const Object& object);
- // Compares rn with the object. Returns results in rd1 and rd2.
- // rd1 is 1 if rn < object. rd2 is 1 if object < rn. Since both cannot be
- // 1, rd1 == rd2 (== 0) iff rn == object.
- void CompareObject(Register rd1, Register rd2,
- Register rn, const Object& object);
-
void LoadIsolate(Register result);
void LoadClassId(Register result, Register object);
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | runtime/vm/constants_mips.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698