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
This commit is contained in:
Gabe Black 2007-07-26 22:08:35 -07:00
parent 57428b8b0b
commit c0670187c5
2 changed files with 71 additions and 78 deletions

View file

@ -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;
}
};
}

View file

@ -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;
}
}};