summaryrefslogtreecommitdiff
path: root/src/arch/x86/types.hh
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-03-21 19:19:53 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-03-21 19:19:53 +0000
commit0a80d06deaaf6fc574abacc2fed9b74d0bca1085 (patch)
tree070b5addf386a199fb9837c07eabe85191b5d3ba /src/arch/x86/types.hh
parent3efec59fc55a439353adbd859722d8a5d170c18d (diff)
downloadgem5-0a80d06deaaf6fc574abacc2fed9b74d0bca1085.tar.xz
Break out the one and two byte opcodes into different files. Also change what bits decode is done on to reflect where clumps of instructions are.
--HG-- extra : convert_revision : 8768676eac25e6a4f0dc50ce2dc576bdcdd6e025
Diffstat (limited to 'src/arch/x86/types.hh')
-rw-r--r--src/arch/x86/types.hh87
1 files changed, 59 insertions, 28 deletions
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index 583f03d55..ca4a15d24 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -61,6 +61,9 @@
#include <inttypes.h>
#include <iostream>
+#include "base/bitfield.hh"
+#include "base/cprintf.hh"
+
namespace X86ISA
{
//This really determines how many bytes are passed to the predecoder.
@@ -76,7 +79,7 @@ namespace X86ISA
SSOverride = 6,
//The Rex prefix obviously doesn't fit in with the above, but putting
//it here lets us save double the space the enums take up.
- Rex = 7,
+ RexPrefix = 7,
//There can be only one segment override, so they share the
//first 3 bits in the legacyPrefixes bitfield.
SegmentOverride = 0x7,
@@ -87,43 +90,71 @@ namespace X86ISA
Repne = 128
};
+ BitUnion8(ModRM)
+ Bitfield<7,6> mod;
+ Bitfield<5,3> reg;
+ Bitfield<2,0> rm;
+ EndBitUnion(ModRM)
+
+ BitUnion8(Sib)
+ Bitfield<7,6> scale;
+ Bitfield<5,3> index;
+ Bitfield<2,0> base;
+ EndBitUnion(Sib)
+
+ BitUnion8(Rex)
+ Bitfield<3> w;
+ Bitfield<2> r;
+ Bitfield<1> x;
+ Bitfield<0> b;
+ EndBitUnion(Rex)
+
+ BitUnion8(Opcode)
+ Bitfield<7,3> top5;
+ Bitfield<2,0> bottom3;
+ EndBitUnion(Opcode)
+
//The intermediate structure the x86 predecoder returns.
struct ExtMachInst
{
- public: //XXX These should be hidden in the future
-
- uint8_t legacyPrefixes;
- uint8_t rexPrefix;
- //Right now, we ignore that this can be 3 in
- //some cases
- uint8_t numOpcodes;
- //This will need to be decoded specially later
- bool is3dnow;
- uint8_t opcode;
+ //Prefixes
+ uint8_t legacy;
+ Rex rex;
+ //This holds all of the bytes of the opcode
+ struct
+ {
+ //The number of bytes in this opcode. Right now, we ignore that
+ //this can be 3 in some cases
+ uint8_t num;
+ //The first byte detected in a 2+ byte opcode. Should be 0xF0.
+ uint8_t prefixA;
+ //The second byte detected in a 3+ byte opcode. Could be 0xF0 for
+ //3dnow instructions, or 0x38-0x3F for some SSE instructions.
+ uint8_t prefixB;
+ //The main opcode byte. The highest addressed byte in the opcode.
+ Opcode op;
+ } opcode;
+ //Modifier bytes
+ ModRM modRM;
+ uint8_t sib;
+ //Immediate fields
uint64_t immediate;
uint64_t displacement;
-
- public:
-
- //These are to pacify the decoder for now. This will go away once
- //it can handle non integer inputs, and in the mean time allow me to
- //excercise the predecoder a little.
- operator unsigned int()
- {
- return 0;
- }
-
- ExtMachInst(unsigned int)
- {;}
-
- ExtMachInst()
- {;}
};
inline static std::ostream &
operator << (std::ostream & os, const ExtMachInst & emi)
{
- os << "{X86 ExtMachInst}";
+ ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t"
+ "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t"
+ "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t"
+ "modRM = %#x,\n\tsib = %#x,\n\t"
+ "immediate = %#x,\n\tdisplacement = %#x\n}\n",
+ emi.legacy, (uint8_t)emi.rex,
+ emi.opcode.num, emi.opcode.op,
+ emi.opcode.prefixA, emi.opcode.prefixB,
+ (uint8_t)emi.modRM, (uint8_t)emi.sib,
+ emi.immediate, emi.displacement);
return os;
}