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

Unified Diff: runtime/vm/constants_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
Index: runtime/vm/constants_mips.h
===================================================================
--- runtime/vm/constants_mips.h (revision 42479)
+++ runtime/vm/constants_mips.h (working copy)
@@ -6,6 +6,8 @@
#define VM_CONSTANTS_MIPS_H_
#include "platform/assert.h"
+#include "vm/allocation.h"
+#include "vm/bitfield.h"
namespace dart {
@@ -45,6 +47,7 @@
R30 = 30,
R31 = 31,
kNumberOfCpuRegisters = 32,
+ IMM = 32, // Positive value is easier to encode than kNoRegister in bitfield.
kNoRegister = -1,
// Register aliases.
@@ -236,10 +239,15 @@
const int kDartVolatileFpuRegCount = 20;
-// Values for the condition field.
-// There is no condition field on MIPS, but Conditions are used and passed
-// around by the intermediate language, so we need them here, too.
-enum Condition {
+// Values for the condition field in the status register.
+// There is no dedicated status register on MIPS, but Condition values are used
+// and passed around by the intermediate language, so we need them here, too.
+// We delay code generation of a comparison that would result in a traditional
+// condition code in the status register by keeping both register operands and
+// the relational operator between them as the Condition.
+enum RelationOperator {
+ AL, // always
+ NV, // never
EQ, // equal
NE, // not equal
GT, // greater than
@@ -246,10 +254,101 @@
GE, // greater equal
LT, // less than
LE, // less equal
- VS, // overflow
+ UGT, // unsigned greater than
+ UGE, // unsigned greater equal
+ ULT, // unsigned less than
+ ULE, // unsigned less equal
};
+class Condition : public ValueObject {
zra 2014/12/19 17:49:47 Should this go in assembler_mips.h?
regis 2014/12/22 20:17:34 Done.
+ public:
+ enum Bits {
+ kLeftPos = 0,
+ kLeftSize = 6,
+ kRightPos = kLeftPos + kLeftSize,
+ kRightSize = 6,
+ kRelOpPos = kRightPos + kRightSize,
+ kRelOpSize = 4,
+ kImmPos = kRelOpPos + kRelOpSize,
+ kImmSize = 16,
+ };
+
+ class LeftBits : public BitField<Register, kLeftPos, kLeftSize> {};
+ class RightBits : public BitField<Register, kRightPos, kRightSize> {};
+ class RelOpBits : public BitField<RelationOperator, kRelOpPos, kRelOpSize> {};
+ class ImmBits : public BitField<uint16_t, kImmPos, kImmSize> {};
+
+ Register left() const { return LeftBits::decode(bits_); }
+ Register right() const { return RightBits::decode(bits_); }
+ RelationOperator rel_op() const { return RelOpBits::decode(bits_); }
+ int16_t imm() const { return static_cast<int16_t>(ImmBits::decode(bits_)); }
+
+ static bool IsValidImm(int32_t value) {
+ // We want both value and value + 1 to fit in an int16_t.
+ return (-0x08000 <= value) && (value < 0x7fff);
+ }
+
+ void set_rel_op(RelationOperator value) {
+ ASSERT(IsValidRelOp(value));
+ bits_ = RelOpBits::update(value, bits_);
+ }
+
+ // Uninitialized condition.
+ Condition() : ValueObject(), bits_(0) { }
+
+ // Copy constructor.
+ Condition(const Condition& other) : ValueObject(), bits_(other.bits_) { }
+
+ // Copy assignment operator.
+ Condition& operator=(const Condition& other) {
+ bits_ = other.bits_;
+ return *this;
+ }
+
+ Condition(Register left,
+ Register right,
+ RelationOperator rel_op,
+ int16_t imm = 0) {
+ // At most one constant, ZR or immediate.
+ ASSERT(!(((left == ZR) || (left == IMM)) &&
+ ((right == ZR) || (right == IMM))));
+ // Non-zero immediate value is only allowed for IMM.
+ ASSERT((imm != 0) == ((left == IMM) || (right == IMM)));
+ set_left(left);
+ set_right(right);
+ set_rel_op(rel_op);
+ set_imm(imm);
+ }
+
+ private:
+ static bool IsValidRelOp(RelationOperator value) {
+ return (AL <= value) && (value <= ULE);
+ }
+
+ static bool IsValidRegister(Register value) {
+ return (ZR <= value) && (value <= IMM) && (value != AT);
+ }
+
+ void set_left(Register value) {
+ ASSERT(IsValidRegister(value));
+ bits_ = LeftBits::update(value, bits_);
+ }
+
+ void set_right(Register value) {
+ ASSERT(IsValidRegister(value));
+ bits_ = RightBits::update(value, bits_);
+ }
+
+ void set_imm(int16_t value) {
+ ASSERT(IsValidImm(value));
+ bits_ = ImmBits::update(static_cast<uint16_t>(value), bits_);
+ }
+
+ uword bits_;
+};
+
+
// Constants used for the decoding or encoding of the individual fields of
// instructions. Based on the "Table 4.25 CPU Instruction Format Fields".
enum InstructionFields {
@@ -361,7 +460,7 @@
SYSCALL = 12,
BREAK = 13,
SYNC = 15,
- MFHI =16,
+ MFHI = 16,
MTHI = 17,
MFLO = 18,
MTLO = 19,

Powered by Google App Engine
This is Rietveld 408576698