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

Unified Diff: src/mips/constants-mips.h

Issue 549079: Support for MIPS in architecture independent files.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: src/mips/constants-mips.h
===================================================================
--- src/mips/constants-mips.h (revision 0)
+++ src/mips/constants-mips.h (revision 0)
@@ -0,0 +1,453 @@
+#ifndef V8_MIPS_CONSTANTS_H_
+#define V8_MIPS_CONSTANTS_H_
+
+// UNIMPLEMENTED_ macro for MIPS.
+#define UNIMPLEMENTED_() \
+ printf("%s, \tline %d: \tfunction %s not implemented. \n",__FILE__, __LINE__, __func__);
+
+// Defines constants and accessor classes to assemble, disassemble and
+// simulate MIPS32 instructions.
+//
+// See MIPS32® Architecture For Programmers
+// Volume II: The MIPS32® Instruction Set
+// ( http://web.asic.sdesigns.com/tools/libs/mips/doc/74K/doc/MIPS32-ISA.pdf )
Søren Thygesen Gjesse 2010/01/19 22:59:12 This link seems not to work. How about using a www
Alexandre 2010/01/22 23:08:42 Added a functional link and a comment. I doubt it
+
+namespace assembler {
+namespace mips {
+
+// -----------------------------------------------------------------------------
+// Registers and CRegisters
+
+// Number of general purpose registers
+static const int kNumRegisters = 32;
+static const int kInvalidRegister = -1;
+
+// In the simulator, the PC register is simulated as the 34th register
+static const int kPCRegister = 34;
+
+// Number coprocessor registers
+static const int kNumCRegisters = 32;
+static const int kInvalidCRegister = -1;
+
+// Helper functions for converting between register numbers and names.
+class Registers {
+ public:
+ // Return the name of the register.
+ static const char* Name(int reg);
+
+ // Lookup the register number for the name provided.
+ static int Number(const char* name);
+
+ struct RegisterAlias {
+ int reg;
+ const char *name;
+ };
+
+ static int32_t max_val() { return max_val_; }
+ static int32_t min_val() { return min_val_; }
+
+ private:
+ static const int32_t max_val_ = 0x7fffffff;
+ static const int32_t min_val_ = 0x80000000;
+
+ static const char* names_[kNumRegisters];
+ static const RegisterAlias aliases_[];
+};
+
+// Helper functions for converting between register numbers and names.
+class CRegisters {
+ public:
+ // Return the name of the register.
+ static const char* Name(int reg);
+
+ // Lookup the register number for the name provided.
+ static int Number(const char* name);
+
+ struct RegisterAlias {
+ int creg;
+ const char *name;
+ };
+
+ private:
+
+ static const char* names_[kNumCRegisters];
+ static const RegisterAlias aliases_[];
+};
+
+
+// -----------------------------------------------------------------------------
+// Instructions encoding constants.
+
+// On MIPS all instructions are 32 bits.
+typedef int32_t Instr;
+
+typedef unsigned char byte;
+
+// ----- Fields offset (_o) and length (_l)
+static const int opcode_o = 26;
+static const int opcode_l = 6;
+static const int rs_o = 21;
+static const int rs_l = 5;
+static const int rt_o = 16;
+static const int rt_l = 5;
+static const int rd_o = 11;
+static const int rd_l = 5;
+static const int sa_o = 6;
+static const int sa_l = 5;
+static const int function_o = 0;
+static const int function_l = 6;
+
+static const int imm16_o = 0;
+static const int imm16_l = 16;
+static const int imm26_o = 0;
+static const int imm26_l = 26;
+
+// ----- MIPS Opcodes and Function Fields
+// We use this presentation to stay close to the table representation in
+// MIPS32® Architecture For Programmers, Volume II: The MIPS32® Instruction Set
+enum Opcode {
+ SPECIAL = 0 << opcode_o,
+ REGIMM = 1 << opcode_o,
+
+ J = ( (0<<3) + 2 ) << opcode_o,
Søren Thygesen Gjesse 2010/01/19 22:59:12 Formatting like ((0 << 3) + 2) << opcode_o matches
Alexandre 2010/01/22 23:08:42 Style issue fixed. On 2010/01/19 22:59:12, Søren G
+ JAL = ( (0<<3) + 3 ) << opcode_o,
+ BEQ = ( (0<<3) + 4 ) << opcode_o,
+ BNE = ( (0<<3) + 5 ) << opcode_o,
+ BLEZ = ( (0<<3) + 6 ) << opcode_o,
+ BGTZ = ( (0<<3) + 7 ) << opcode_o,
+
+ ADDI = ( (1<<3) + 0 ) << opcode_o,
+ ADDIU = ( (1<<3) + 1 ) << opcode_o,
+ SLTI = ( (1<<3) + 2 ) << opcode_o,
+ SLTIU = ( (1<<3) + 3 ) << opcode_o,
+ ANDI = ( (1<<3) + 4 ) << opcode_o,
+ ORI = ( (1<<3) + 5 ) << opcode_o,
+ XORI = ( (1<<3) + 6 ) << opcode_o,
+ LUI = ( (1<<3) + 7 ) << opcode_o,
+
+ COP1 = ( (2<<3) + 1 ) << opcode_o, // Coprocessor 1 class (floating point)
Søren Thygesen Gjesse 2010/01/19 22:59:12 Long line.
Alexandre 2010/01/22 23:08:42 Style issue fixed. On 2010/01/19 22:59:12, Søren G
+ BEQL = ( (2<<3) + 4 ) << opcode_o,
+ BNEL = ( (2<<3) + 5 ) << opcode_o,
+ BLEZL = ( (2<<3) + 6 ) << opcode_o,
+ BGTZL = ( (2<<3) + 7 ) << opcode_o,
+
+ SPECIAL2 = ( (3<<3) + 4 ) << opcode_o,
+
+ LB = ( (4<<3) + 0 ) << opcode_o,
+ LW = ( (4<<3) + 3 ) << opcode_o,
+ LBU = ( (4<<3) + 4 ) << opcode_o,
+ SB = ( (5<<3) + 0 ) << opcode_o,
+ SW = ( (5<<3) + 3 ) << opcode_o,
+
+ LWC1 = ( (6<<3) + 1 ) << opcode_o,
+ LDC1 = ( (6<<3) + 5 ) << opcode_o,
+
+ SWC1 = ( (7<<3) + 1 ) << opcode_o,
+ SDC1 = ( (7<<3) + 5 ) << opcode_o
+};
+
+enum SecondaryField {
+ // SPECIAL Encoding of Function Field
+ SLL = ( (0<<3) + 0 ),
+ SRL = ( (0<<3) + 2 ),
+ SRA = ( (0<<3) + 3 ),
+ SLLV = ( (0<<3) + 4 ),
+ SRLV = ( (0<<3) + 6 ),
+ SRAV = ( (0<<3) + 7 ),
+
+ JR = ( (1<<3) + 0 ),
+ JALR = ( (1<<3) + 1 ),
+ BREAK = ( (1<<3) + 5 ),
+
+ MFHI = ( (2<<3) + 0 ),
+ MFLO = ( (2<<3) + 2 ),
+
+ MULT = ( (3<<3) + 0 ),
+ MULTU = ( (3<<3) + 1 ),
+ DIV = ( (3<<3) + 2 ),
+ DIVU = ( (3<<3) + 3 ),
+
+ ADD = ( (4<<3) + 0 ),
+ ADDU = ( (4<<3) + 1 ),
+ SUB = ( (4<<3) + 2 ),
+ SUBU = ( (4<<3) + 3 ),
+ AND = ( (4<<3) + 4 ),
+ OR = ( (4<<3) + 5 ),
+ XOR = ( (4<<3) + 6 ),
+ NOR = ( (4<<3) + 7 ),
+
+ SLT = ( (5<<3) + 2 ),
+ SLTU = ( (5<<3) + 3 ),
+
+ TGE = ( (6<<3) + 0 ),
+ TGEU = ( (6<<3) + 1 ),
+ TLT = ( (6<<3) + 2 ),
+ TLTU = ( (6<<3) + 3 ),
+ TEQ = ( (6<<3) + 4 ),
+ TNE = ( (6<<3) + 6 ),
+
+ // SPECIAL2 Encoding of Function Field
+ MUL = ( (0<<3) + 2 ),
+
+ // REGIMM encoding of rt Field
+ BLTZ = ( (0<<3) + 0 ) << 16,
+ BGEZ = ( (0<<3) + 1 ) << 16,
+ BLTZAL = ( (2<<3) + 0 ) << 16,
+ BGEZAL = ( (2<<3) + 1 ) << 16,
+
+ // COP1 Encoding of rs Field
+ MFC1 = ( (0<<3) + 0 ) << 21,
+ MFHC1 = ( (0<<3) + 3 ) << 21,
+ MTC1 = ( (0<<3) + 4 ) << 21,
+ MTHC1 = ( (0<<3) + 7 ) << 21,
+ BC1 = ( (1<<3) + 0 ) << 21,
+ S = ( (2<<3) + 0 ) << 21,
+ D = ( (2<<3) + 1 ) << 21,
+ W = ( (2<<3) + 4 ) << 21,
+ L = ( (2<<3) + 5 ) << 21,
+ PS = ( (2<<3) + 6 ) << 21,
+ // COP1 Encoding of Function Field When rs=S
+ CVT_D_S = ( (4<<3) + 1 ),
+ CVT_W_S = ( (4<<3) + 4 ),
+ CVT_L_S = ( (4<<3) + 5 ),
+ CVT_PS_S = ( (4<<3) + 6 ),
+ // COP1 Encoding of Function Field When rs=D
+ CVT_S_D = ( (4<<3) + 0 ),
+ CVT_W_D = ( (4<<3) + 4 ),
+ CVT_L_D = ( (4<<3) + 5 ),
+ // COP1 Encoding of Function Field When rs=W or L
+ CVT_S_W = ( (4<<3) + 0 ),
+ CVT_D_W = ( (4<<3) + 1 ),
+ CVT_S_L = ( (4<<3) + 0 ),
+ CVT_D_L = ( (4<<3) + 1 ),
+ // COP1 Encoding of Function Field When rs=PS
+
+ NULLSF = 0
+};
+
+// ----- Miscellianous useful masks.
+enum {
+ // Instruction bit masks
+ OpcodeMask = 0x3f << opcode_o,
+ Imm16Mask = 0xffff,
+ Imm26Mask = 0x3fffffff,
+ rsFieldMask = 0x1f << rs_o,
+ rtFieldMask = 0x1f << rt_o,
+ rdFieldMask = 0x1f << rd_o,
+ saFieldMask = 0x1f << sa_o,
+ functionFieldMask = 0x3f << function_o,
+ // Misc masks
+ HIMask = 0xffff << 16,
+ LOMask = 0xffff,
+ signMask = 0x80000000
+};
+
+
+// ----- Emulated conditions
+// On MIPS we use this enum to abstract from conditionnal branch instructions.
+// the 'U' prefix is used to specify unsigned comparisons.
+enum Condition {
+ // any value < 0 is considered no_condition
+ no_condition = -1,
+
+ overflow = 0,
+ no_overflow = 1,
+ Uless = 2,
+ Ugreater_equal= 3,
+ equal = 4,
+ not_equal = 5,
+ Uless_equal = 6,
+ Ugreater = 7,
+ negative = 8,
+ positive = 9,
+ parity_even = 10,
+ parity_odd = 11,
+ less = 12,
+ greater_equal = 13,
+ less_equal = 14,
+ greater = 15,
+
+ cc_always = 16,
+
+ // aliases
+ carry = Uless,
+ not_carry = Ugreater_equal,
+ zero = equal,
+ eq = equal,
+ not_zero = not_equal,
+ ne = not_equal,
+ sign = negative,
+ not_sign = positive,
+
+ cc_default = no_condition
+};
+
+// ----- Coprocessor conditions
+enum C_Condition {
+ F, // False
+ UN, // Unordered
+ EQ, // Equal
+ UEQ, // Unordered or Equal
+ OLT, // Ordered or Less Than
+ ULT, // Unordered or Less Than
+ OLE, // Ordered or Less Than or Equal
+ ULE // Unordered or Less Than or Equal
+};
+
+
+// The class Instruction enables access to individual fields defined in the ARM
+// architecture instruction set encoding as described in figure A3-1.
+//
+// Example: Test whether the instruction at ptr does set the condition code
+// bits.
+//
+// bool InstructionSetsConditionCodes(byte* ptr) {
+// Instruction* instr = Instruction::At(ptr);
+// int type = instr->TypeField();
+// return ((type == 0) || (type == 1)) && instr->HasS();
+// }
+//
+class Instruction {
+ public:
+ enum {
+ kInstructionSize = 4,
+ kInstructionSizeLog2 = 2,
+ // On MIPS PC cannot actually be directly accessed. We behave as if PC was
+ // always the value of the current instruction being exectued.
+ kPCReadOffset = 0
+ };
+
+ // Get the raw instruction bits.
+ inline Instr InstructionBits() const {
+ return *reinterpret_cast<const Instr*>(this);
+ }
+
+ // Set the raw instruction bits to value.
+ inline void SetInstructionBits(Instr value) {
+ *reinterpret_cast<Instr*>(this) = value;
+ }
+
+ // Read one particular bit out of the instruction bits.
+ inline int Bit(int nr) const {
+ return (InstructionBits() >> nr) & 1;
+ }
+
+ // Read a bit field out of the instruction bits.
+ inline int Bits(int hi, int lo) const {
+ return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
+ }
+
+
+ // Accessors for the different named fields used in the MIPS encoding.
+ // Generally applicable fields
+
+ // Fields used in Data processing instructions
+ inline Opcode OpcodeField() const {
+ return static_cast<Opcode>(Bits(opcode_o+opcode_l-1, opcode_o));
+ }
+
+ inline int rsField() const {
+ return Bits(rs_o+rs_l-1, rs_o);
Søren Thygesen Gjesse 2010/01/19 22:59:12 Format expression with spaces rs_o + rs_l - 1.
Alexandre 2010/01/22 23:08:42 Style issue fixed. On 2010/01/19 22:59:12, Søren G
+ }
+
+ inline int rtField() const {
+ return Bits(rt_o+rt_l-1, rt_o);
+ }
+
+ inline int rdField() const {
+ return Bits(rd_o+rd_l-1, rd_o);
+ }
+
+ inline int saField() const {
+ return Bits(sa_o+sa_l-1, sa_o);
+ }
+
+ inline int functionField() const {
+ return Bits(function_o+function_l-1, function_o);
+ }
+
+ // Return the fields at their original place in the instruction encoding.
+ inline Opcode OpcodeFieldRaw() const {
+ return static_cast<Opcode>(InstructionBits() & OpcodeMask);
+ }
+
+ inline int rsFieldRaw() const {
+ return InstructionBits() & rsFieldMask;
+ }
+
+ inline int rtFieldRaw() const {
+ return InstructionBits() & rtFieldMask;
+ }
+
+ inline int rdFieldRaw() const {
+ return InstructionBits() & rdFieldMask;
+ }
+
+ inline int saFieldRaw() const {
+ return InstructionBits() & saFieldMask;
+ }
+
+ inline int functionFieldRaw() const {
+ return InstructionBits() & functionFieldMask;
+ }
+
+ // Get the secondary field according to the opcode.
+ inline int secondaryField() const {
+ Opcode op = OpcodeFieldRaw();
+ switch (op) {
+ case SPECIAL:
+ case SPECIAL2:
+ return functionField();
+ break;
antonm 2010/01/21 13:10:45 why break after return?
Alexandre 2010/01/22 23:08:42 Fixed. On 2010/01/21 13:10:45, antonm wrote:
+ case COP1:
+ return rsField();
+ break;
+ case REGIMM:
+ return rtField();
+ break;
+ default:
+ return NULLSF;
+ }
+ }
+
+ inline int32_t Imm16Field() const {
+ return Bits(imm16_o+imm16_l-1, imm16_o);
+ }
+
+ inline int32_t Imm26Field() const {
+ return Bits(imm16_o+imm26_l-1, imm26_o);
+ }
+
+ // Say if the instruction should not be used in a branch delay slot.
+ bool isForbiddenInBranchDelay();
+ // Say if the instruction 'links'. eg: jal, bal
+ bool isLinkingInstruction();
+
+ // Get the encoding type of the instruction.
+ // type 1 is imm16 type
+ // type 2 is register type
+ // type 3 is imm26 type
+ int instrType();
+
+ // Instructions are read of out a code stream. The only way to get a
+ // reference to an instruction is to convert a pointer. There is no way
+ // to allocate or create instances of class Instruction.
+ // Use the At(pc) function to create references to Instruction.
+ static Instruction* At(byte* pc) { return reinterpret_cast<Instruction*>(pc); }
+
+ private:
+ // We need to prevent the creation of instances of class Instruction.
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
+};
+
+
+// -----------------------------------------------------------------------------
+// MIPS assembly various constants
+
+static const int argsSlotsSize = 4*Instruction::kInstructionSize;
+static const int argsSlotsNum = 4;
+
+
+} } // namespace assembler::mips
+
+#endif // #ifndef V8_MIPS_CONSTANTS_H_

Powered by Google App Engine
This is Rietveld 408576698