From 7860c045e2a87a4e63b7d542a63a30da934ac6dd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 31 May 2007 13:50:35 +0000 Subject: [PATCH] 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 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 10 ++--- src/arch/x86/predecoder.cc | 38 +++++++++++-------- src/arch/x86/predecoder.hh | 20 +++++++++- src/arch/x86/predecoder_tables.cc | 2 +- src/arch/x86/regfile.cc | 3 +- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 4e044363b..12f3c5f96 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -237,11 +237,11 @@ 0x7: xchg_Ev_Gv(); } 0x11: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::MOV(); //mov_Eb_Gb(); - 0x1: Inst::MOV(); //mov_Ev_Gv(); - 0x2: Inst::MOV(); //mov_Gb_Eb(); - 0x3: Inst::MOV(); //mov_Gv_Ev(); - 0x4: Inst::MOV(); //mov_MwRv_Sw(); + 0x0: Inst::MOV(Eb, Gb); + 0x1: Inst::MOV(Ev, Gv); + 0x2: Inst::MOV(Gb, Eb); + 0x3: Inst::MOV(Gv, Ev); + 0x4: mov_MwRv_Sw(); //What to do with this one? 0x5: lea_Gv_M(); 0x6: mov_Sw_MwRv(); 0x7: group10_Ev(); //Make sure this is Ev diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 573012ee6..65f951f44 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -62,6 +62,21 @@ 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() { //This function drives the predecoder state machine. @@ -78,6 +93,9 @@ namespace X86ISA uint8_t nextByte = getNextByte(); switch(state) { + case ResetState: + reset(); + state = PrefixState; case PrefixState: state = doPrefixState(nextByte); break; @@ -150,7 +168,6 @@ namespace X86ISA emi.rex = nextByte; break; case 0: - emi.opcode.num = 0; nextState = OpcodeState; break; default: @@ -188,12 +205,6 @@ namespace X86ISA DPRINTF(Predecoder, "Found opcode %#x.\n", 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 //a fixed value at the decoder level. if(/*FIXME long mode*/1) @@ -229,14 +240,11 @@ namespace X86ISA if (UsesModRM[emi.opcode.num - 1][nextByte]) { nextState = ModRMState; } else { - //If there's no modRM byte, set it to 0 so we can detect - //that later. - emi.modRM = 0; if(immediateSize) { nextState = ImmediateState; } else { emiIsReady = true; - nextState = PrefixState; + nextState = ResetState; } } } @@ -282,7 +290,7 @@ namespace X86ISA nextState = ImmediateState; } else { emiIsReady = true; - nextState = PrefixState; + nextState = ResetState; } //The ModRM byte is consumed no matter what consumeByte(); @@ -304,7 +312,7 @@ namespace X86ISA nextState = ImmediateState; } else { emiIsReady = true; - nextState = PrefixState; + nextState = ResetState; } return nextState; } @@ -344,7 +352,7 @@ namespace X86ISA nextState = ImmediateState; } else { emiIsReady = true; - nextState = PrefixState; + nextState = ResetState; } } else @@ -380,7 +388,7 @@ namespace X86ISA DPRINTF(Predecoder, "Collected immediate %#x.\n", emi.immediate); emiIsReady = true; - nextState = PrefixState; + nextState = ResetState; } else nextState = ImmediateState; diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index 6562ab9f5..9b4d36d4a 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -60,6 +60,8 @@ #include "arch/x86/types.hh" #include "base/bitfield.hh" +#include "base/misc.hh" +#include "base/trace.hh" #include "sim/host.hh" class ThreadContext; @@ -81,6 +83,8 @@ namespace X86ISA MachInst fetchChunk; //The pc of the start of fetchChunk Addr basePC; + //The pc the current instruction started at + Addr origPC; //The offset into fetchChunk of current processing int offset; //The extended machine instruction being generated @@ -130,6 +134,8 @@ namespace X86ISA outOfBytes = true; } + void reset(); + //State machine state protected: //Whether or not we're out of bytes @@ -144,6 +150,7 @@ namespace X86ISA int immediateCollected; enum State { + ResetState, PrefixState, OpcodeState, ModRMState, @@ -166,9 +173,9 @@ namespace X86ISA public: Predecoder(ThreadContext * _tc) : - tc(_tc), basePC(0), offset(0), + tc(_tc), basePC(0), origPC(0), offset(0), outOfBytes(true), emiIsReady(false), - state(PrefixState) + state(ResetState) {} ThreadContext * getTC() @@ -219,6 +226,15 @@ namespace X86ISA emiIsReady = false; return emi; } + + int getInstSize() + { + DPRINTF(Predecoder, + "Calculating the instruction size: " + "basePC: %#x offset: %#x origPC: %#x\n", + basePC, offset, origPC); + return basePC + offset - origPC; + } }; }; diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 38b9c57a3..6fe54b719 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -170,7 +170,7 @@ namespace X86ISA // 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, 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 diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index 568eb1d94..f54f531e2 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -117,7 +117,8 @@ void RegFile::setNextPC(Addr val) 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) -- 2.30.2