x86 work that hadn't been checked in.
src/arch/x86/isa/decoder/one_byte_opcodes.isa: Give the "MOV" instruction the format of it's arguments. This will likely need to be completely overhauled in the near future. src/arch/x86/predecoder.cc: src/arch/x86/predecoder.hh: Make the predecoder explicitly reset itself rather than counting on it happening naturally. src/arch/x86/predecoder_tables.cc: Fix the immediate size table src/arch/x86/regfile.cc: nextnpc is bogus --HG-- extra : convert_revision : 0926701fedaab41817e64bb05410a25174484a5a
This commit is contained in:
parent
a3ae9486d5
commit
7860c045e2
5 changed files with 49 additions and 24 deletions
|
@ -237,11 +237,11 @@
|
||||||
0x7: xchg_Ev_Gv();
|
0x7: xchg_Ev_Gv();
|
||||||
}
|
}
|
||||||
0x11: decode OPCODE_OP_BOTTOM3 {
|
0x11: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: Inst::MOV(); //mov_Eb_Gb();
|
0x0: Inst::MOV(Eb, Gb);
|
||||||
0x1: Inst::MOV(); //mov_Ev_Gv();
|
0x1: Inst::MOV(Ev, Gv);
|
||||||
0x2: Inst::MOV(); //mov_Gb_Eb();
|
0x2: Inst::MOV(Gb, Eb);
|
||||||
0x3: Inst::MOV(); //mov_Gv_Ev();
|
0x3: Inst::MOV(Gv, Ev);
|
||||||
0x4: Inst::MOV(); //mov_MwRv_Sw();
|
0x4: mov_MwRv_Sw(); //What to do with this one?
|
||||||
0x5: lea_Gv_M();
|
0x5: lea_Gv_M();
|
||||||
0x6: mov_Sw_MwRv();
|
0x6: mov_Sw_MwRv();
|
||||||
0x7: group10_Ev(); //Make sure this is Ev
|
0x7: group10_Ev(); //Make sure this is Ev
|
||||||
|
|
|
@ -62,6 +62,21 @@
|
||||||
|
|
||||||
namespace X86ISA
|
namespace X86ISA
|
||||||
{
|
{
|
||||||
|
void Predecoder::reset()
|
||||||
|
{
|
||||||
|
origPC = basePC + offset;
|
||||||
|
DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC);
|
||||||
|
emi.opcode.num = 0;
|
||||||
|
|
||||||
|
immediateCollected = 0;
|
||||||
|
emi.immediate = 0;
|
||||||
|
displacementCollected = 0;
|
||||||
|
emi.displacement = 0;
|
||||||
|
|
||||||
|
emi.modRM = 0;
|
||||||
|
emi.sib = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Predecoder::process()
|
void Predecoder::process()
|
||||||
{
|
{
|
||||||
//This function drives the predecoder state machine.
|
//This function drives the predecoder state machine.
|
||||||
|
@ -78,6 +93,9 @@ namespace X86ISA
|
||||||
uint8_t nextByte = getNextByte();
|
uint8_t nextByte = getNextByte();
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
|
case ResetState:
|
||||||
|
reset();
|
||||||
|
state = PrefixState;
|
||||||
case PrefixState:
|
case PrefixState:
|
||||||
state = doPrefixState(nextByte);
|
state = doPrefixState(nextByte);
|
||||||
break;
|
break;
|
||||||
|
@ -150,7 +168,6 @@ namespace X86ISA
|
||||||
emi.rex = nextByte;
|
emi.rex = nextByte;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
emi.opcode.num = 0;
|
|
||||||
nextState = OpcodeState;
|
nextState = OpcodeState;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -188,12 +205,6 @@ namespace X86ISA
|
||||||
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
|
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
|
||||||
emi.opcode.op = nextByte;
|
emi.opcode.op = nextByte;
|
||||||
|
|
||||||
//Prepare for any immediate/displacement we might need
|
|
||||||
immediateCollected = 0;
|
|
||||||
emi.immediate = 0;
|
|
||||||
displacementCollected = 0;
|
|
||||||
emi.displacement = 0;
|
|
||||||
|
|
||||||
//Figure out the effective operand size. This can be overriden to
|
//Figure out the effective operand size. This can be overriden to
|
||||||
//a fixed value at the decoder level.
|
//a fixed value at the decoder level.
|
||||||
if(/*FIXME long mode*/1)
|
if(/*FIXME long mode*/1)
|
||||||
|
@ -229,14 +240,11 @@ namespace X86ISA
|
||||||
if (UsesModRM[emi.opcode.num - 1][nextByte]) {
|
if (UsesModRM[emi.opcode.num - 1][nextByte]) {
|
||||||
nextState = ModRMState;
|
nextState = ModRMState;
|
||||||
} else {
|
} else {
|
||||||
//If there's no modRM byte, set it to 0 so we can detect
|
|
||||||
//that later.
|
|
||||||
emi.modRM = 0;
|
|
||||||
if(immediateSize) {
|
if(immediateSize) {
|
||||||
nextState = ImmediateState;
|
nextState = ImmediateState;
|
||||||
} else {
|
} else {
|
||||||
emiIsReady = true;
|
emiIsReady = true;
|
||||||
nextState = PrefixState;
|
nextState = ResetState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,7 +290,7 @@ namespace X86ISA
|
||||||
nextState = ImmediateState;
|
nextState = ImmediateState;
|
||||||
} else {
|
} else {
|
||||||
emiIsReady = true;
|
emiIsReady = true;
|
||||||
nextState = PrefixState;
|
nextState = ResetState;
|
||||||
}
|
}
|
||||||
//The ModRM byte is consumed no matter what
|
//The ModRM byte is consumed no matter what
|
||||||
consumeByte();
|
consumeByte();
|
||||||
|
@ -304,7 +312,7 @@ namespace X86ISA
|
||||||
nextState = ImmediateState;
|
nextState = ImmediateState;
|
||||||
} else {
|
} else {
|
||||||
emiIsReady = true;
|
emiIsReady = true;
|
||||||
nextState = PrefixState;
|
nextState = ResetState;
|
||||||
}
|
}
|
||||||
return nextState;
|
return nextState;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +352,7 @@ namespace X86ISA
|
||||||
nextState = ImmediateState;
|
nextState = ImmediateState;
|
||||||
} else {
|
} else {
|
||||||
emiIsReady = true;
|
emiIsReady = true;
|
||||||
nextState = PrefixState;
|
nextState = ResetState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -380,7 +388,7 @@ namespace X86ISA
|
||||||
DPRINTF(Predecoder, "Collected immediate %#x.\n",
|
DPRINTF(Predecoder, "Collected immediate %#x.\n",
|
||||||
emi.immediate);
|
emi.immediate);
|
||||||
emiIsReady = true;
|
emiIsReady = true;
|
||||||
nextState = PrefixState;
|
nextState = ResetState;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nextState = ImmediateState;
|
nextState = ImmediateState;
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
|
|
||||||
#include "arch/x86/types.hh"
|
#include "arch/x86/types.hh"
|
||||||
#include "base/bitfield.hh"
|
#include "base/bitfield.hh"
|
||||||
|
#include "base/misc.hh"
|
||||||
|
#include "base/trace.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
@ -81,6 +83,8 @@ namespace X86ISA
|
||||||
MachInst fetchChunk;
|
MachInst fetchChunk;
|
||||||
//The pc of the start of fetchChunk
|
//The pc of the start of fetchChunk
|
||||||
Addr basePC;
|
Addr basePC;
|
||||||
|
//The pc the current instruction started at
|
||||||
|
Addr origPC;
|
||||||
//The offset into fetchChunk of current processing
|
//The offset into fetchChunk of current processing
|
||||||
int offset;
|
int offset;
|
||||||
//The extended machine instruction being generated
|
//The extended machine instruction being generated
|
||||||
|
@ -130,6 +134,8 @@ namespace X86ISA
|
||||||
outOfBytes = true;
|
outOfBytes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
//State machine state
|
//State machine state
|
||||||
protected:
|
protected:
|
||||||
//Whether or not we're out of bytes
|
//Whether or not we're out of bytes
|
||||||
|
@ -144,6 +150,7 @@ namespace X86ISA
|
||||||
int immediateCollected;
|
int immediateCollected;
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
ResetState,
|
||||||
PrefixState,
|
PrefixState,
|
||||||
OpcodeState,
|
OpcodeState,
|
||||||
ModRMState,
|
ModRMState,
|
||||||
|
@ -166,9 +173,9 @@ namespace X86ISA
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Predecoder(ThreadContext * _tc) :
|
Predecoder(ThreadContext * _tc) :
|
||||||
tc(_tc), basePC(0), offset(0),
|
tc(_tc), basePC(0), origPC(0), offset(0),
|
||||||
outOfBytes(true), emiIsReady(false),
|
outOfBytes(true), emiIsReady(false),
|
||||||
state(PrefixState)
|
state(ResetState)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ThreadContext * getTC()
|
ThreadContext * getTC()
|
||||||
|
@ -219,6 +226,15 @@ namespace X86ISA
|
||||||
emiIsReady = false;
|
emiIsReady = false;
|
||||||
return emi;
|
return emi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getInstSize()
|
||||||
|
{
|
||||||
|
DPRINTF(Predecoder,
|
||||||
|
"Calculating the instruction size: "
|
||||||
|
"basePC: %#x offset: %#x origPC: %#x\n",
|
||||||
|
basePC, offset, origPC);
|
||||||
|
return basePC + offset - origPC;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace X86ISA
|
||||||
// noimm byte word dword qword oword vword zword enter pointer
|
// noimm byte word dword qword oword vword zword enter pointer
|
||||||
{0, 1, 2, 4, 8, 16, 2, 2, 3, 4 }, //16 bit
|
{0, 1, 2, 4, 8, 16, 2, 2, 3, 4 }, //16 bit
|
||||||
{0, 1, 2, 4, 8, 16, 4, 4, 3, 6 }, //32 bit
|
{0, 1, 2, 4, 8, 16, 4, 4, 3, 6 }, //32 bit
|
||||||
{0, 1, 2, 4, 8, 16, 4, 8, 3, 0 } //64 bit
|
{0, 1, 2, 4, 8, 16, 8, 4, 3, 0 } //64 bit
|
||||||
};
|
};
|
||||||
|
|
||||||
//This table determines the immediate type. The first index is the
|
//This table determines the immediate type. The first index is the
|
||||||
|
|
|
@ -117,7 +117,8 @@ void RegFile::setNextPC(Addr val)
|
||||||
|
|
||||||
Addr RegFile::readNextNPC()
|
Addr RegFile::readNextNPC()
|
||||||
{
|
{
|
||||||
return nextRip + sizeof(MachInst);
|
//There's no way to know how big the -next- instruction will be.
|
||||||
|
return nextRip + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegFile::setNextNPC(Addr val)
|
void RegFile::setNextNPC(Addr val)
|
||||||
|
|
Loading…
Reference in a new issue