Chromium Code Reviews| 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, |