summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-07-26 22:08:35 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-07-26 22:08:35 -0700
commitc0670187c5af1421d172197db7040cd8861f7465 (patch)
treefe1e9e4960f32d5bb99be0fa2c2d021db3025aca /src
parent57428b8b0bc277f45dfcc415677a116c0c0673a6 (diff)
downloadgem5-c0670187c5af1421d172197db7040cd8861f7465.tar.xz
X86: Add functions to read and write to an exec context.
These functions take care of calling the thread contexts read and write functions with the right sized data type, and handle unaligned accesses. --HG-- extra : convert_revision : b4b59ab2b22559333035185946bae3eab316c879
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/insts/microldstop.hh56
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa93
2 files changed, 71 insertions, 78 deletions
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
index f90d6670e..ae03d176e 100644
--- a/src/arch/x86/insts/microldstop.hh
+++ b/src/arch/x86/insts/microldstop.hh
@@ -96,6 +96,62 @@ namespace X86ISA
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
+
+ template<class Context, class MemType>
+ Fault read(Context *xc, Addr EA, MemType & Mem, unsigned flags) const
+ {
+ Fault fault = NoFault;
+ int size = dataSize;
+ Addr alignedEA = EA & ~(dataSize - 1);
+ if (EA != alignedEA)
+ size *= 2;
+ switch(size)
+ {
+ case 1:
+ fault = xc->read(alignedEA, (uint8_t&)Mem, flags);
+ break;
+ case 2:
+ fault = xc->read(alignedEA, (uint16_t&)Mem, flags);
+ break;
+ case 4:
+ fault = xc->read(alignedEA, (uint32_t&)Mem, flags);
+ break;
+ case 8:
+ fault = xc->read(alignedEA, (uint64_t&)Mem, flags);
+ break;
+ default:
+ panic("Bad operand size %d!\n", size);
+ }
+ return fault;
+ }
+
+ template<class Context, class MemType>
+ Fault write(Context *xc, MemType & Mem, Addr EA, unsigned flags) const
+ {
+ Fault fault = NoFault;
+ int size = dataSize;
+ Addr alignedEA = EA & ~(dataSize - 1);
+ if (EA != alignedEA)
+ size *= 2;
+ switch(size)
+ {
+ case 1:
+ fault = xc->write((uint8_t&)Mem, alignedEA, flags, 0);
+ break;
+ case 2:
+ fault = xc->write((uint16_t&)Mem, alignedEA, flags, 0);
+ break;
+ case 4:
+ fault = xc->write((uint32_t&)Mem, alignedEA, flags, 0);
+ break;
+ case 8:
+ fault = xc->write((uint64_t&)Mem, alignedEA, flags, 0);
+ break;
+ default:
+ panic("Bad operand size %d!\n", size);
+ }
+ return fault;
+ }
};
}
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index ccf519963..18cbc6082 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -123,24 +123,9 @@ def template MicroLoadExecute {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- unsigned flags = 0;
- switch(dataSize)
- {
- case 1:
- fault = xc->read(EA, (uint8_t&)Mem, flags);
- break;
- case 2:
- fault = xc->read(EA, (uint16_t&)Mem, flags);
- break;
- case 4:
- fault = xc->read(EA, (uint32_t&)Mem, flags);
- break;
- case 8:
- fault = xc->read(EA, (uint64_t&)Mem, flags);
- break;
- default:
- panic("Bad operand size!\n");
- }
+ fault = read(xc, EA, Mem, 0);
+ int offset = EA & (dataSize - 1);
+ Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
if(fault == NoFault)
{
@@ -167,24 +152,8 @@ def template MicroLoadInitiateAcc {{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- unsigned flags = 0;
- switch(dataSize)
- {
- case 1:
- fault = xc->read(EA, (uint8_t&)Mem, flags);
- break;
- case 2:
- fault = xc->read(EA, (uint16_t&)Mem, flags);
- break;
- case 4:
- fault = xc->read(EA, (uint32_t&)Mem, flags);
- break;
- case 8:
- fault = xc->read(EA, (uint64_t&)Mem, flags);
- break;
- default:
- panic("Bad operand size!\n");
- }
+ int offset = EA & (dataSize - 1);
+ fault = read(xc, EA, Mem, offset);
return fault;
}
@@ -201,6 +170,8 @@ def template MicroLoadCompleteAcc {{
%(op_rd)s;
Mem = pkt->get<typeof(Mem)>();
+ int offset = pkt->flags;
+ Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
%(code)s;
if(fault == NoFault)
@@ -230,30 +201,13 @@ def template MicroStoreExecute {{
if(fault == NoFault)
{
- unsigned flags = 0;
- uint64_t *res = 0;
- switch(dataSize)
+ Mem = Mem << ((EA & (dataSize - 1)) * 8);
+ fault = write(xc, Mem, EA, 0);
+ if(fault == NoFault)
{
- case 1:
- fault = xc->write((uint8_t&)Mem, EA, flags, res);
- break;
- case 2:
- fault = xc->write((uint16_t&)Mem, EA, flags, res);
- break;
- case 4:
- fault = xc->write((uint32_t&)Mem, EA, flags, res);
- break;
- case 8:
- fault = xc->write((uint64_t&)Mem, EA, flags, res);
- break;
- default:
- panic("Bad operand size!\n");
+ %(op_wb)s;
}
}
- if(fault == NoFault)
- {
- %(op_wb)s;
- }
return fault;
}
@@ -275,30 +229,13 @@ def template MicroStoreInitiateAcc {{
if(fault == NoFault)
{
- unsigned flags = 0;
- uint64_t *res = 0;
- switch(dataSize)
+ Mem = Mem << ((EA & (dataSize - 1)) * 8);
+ fault = write(xc, Mem, EA, 0);
+ if(fault == NoFault)
{
- case 1:
- fault = xc->write((uint8_t&)Mem, EA, flags, res);
- break;
- case 2:
- fault = xc->write((uint16_t&)Mem, EA, flags, res);
- break;
- case 4:
- fault = xc->write((uint32_t&)Mem, EA, flags, res);
- break;
- case 8:
- fault = xc->write((uint64_t&)Mem, EA, flags, res);
- break;
- default:
- panic("Bad operand size!\n");
+ %(op_wb)s;
}
}
- if(fault == NoFault)
- {
- %(op_wb)s;
- }
return fault;
}
}};