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:
parent
57428b8b0b
commit
c0670187c5
|
@ -96,6 +96,62 @@ namespace X86ISA
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
std::string generateDisassembly(Addr pc,
|
||||||
const SymbolTable *symtab) const;
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,24 +123,9 @@ def template MicroLoadExecute {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
unsigned flags = 0;
|
fault = read(xc, EA, Mem, 0);
|
||||||
switch(dataSize)
|
int offset = EA & (dataSize - 1);
|
||||||
{
|
Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
|
@ -167,24 +152,8 @@ def template MicroLoadInitiateAcc {{
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||||
|
|
||||||
unsigned flags = 0;
|
int offset = EA & (dataSize - 1);
|
||||||
switch(dataSize)
|
fault = read(xc, EA, Mem, offset);
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
@ -201,6 +170,8 @@ def template MicroLoadCompleteAcc {{
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
|
||||||
Mem = pkt->get<typeof(Mem)>();
|
Mem = pkt->get<typeof(Mem)>();
|
||||||
|
int offset = pkt->flags;
|
||||||
|
Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
|
||||||
%(code)s;
|
%(code)s;
|
||||||
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
|
@ -230,30 +201,13 @@ def template MicroStoreExecute {{
|
||||||
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
unsigned flags = 0;
|
Mem = Mem << ((EA & (dataSize - 1)) * 8);
|
||||||
uint64_t *res = 0;
|
fault = write(xc, Mem, EA, 0);
|
||||||
switch(dataSize)
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
@ -275,30 +229,13 @@ def template MicroStoreInitiateAcc {{
|
||||||
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
unsigned flags = 0;
|
Mem = Mem << ((EA & (dataSize - 1)) * 8);
|
||||||
uint64_t *res = 0;
|
fault = write(xc, Mem, EA, 0);
|
||||||
switch(dataSize)
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue