X86: Make 64 bit unaligned accesses work as well as the other sizes.
There is a fundemental flaw in how unaligned accesses are supported, but this is still an improvement. --HG-- extra : convert_revision : 1c20b524ac24cd4a812c876b067495ee6a7ae29f
This commit is contained in:
@@ -113,19 +113,22 @@ namespace X86ISA
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->read(alignedEA, (uint8_t&)Mem, flags);
|
||||
fault = xc->read(alignedEA, (uint8_t&)(Mem.a), flags);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->read(alignedEA, (uint16_t&)Mem, flags);
|
||||
fault = xc->read(alignedEA, (uint16_t&)(Mem.a), flags);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->read(alignedEA, (uint32_t&)Mem, flags);
|
||||
fault = xc->read(alignedEA, (uint32_t&)(Mem.a), flags);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->read(alignedEA, (uint64_t&)Mem, flags);
|
||||
fault = xc->read(alignedEA, (uint64_t&)(Mem.a), flags);
|
||||
break;
|
||||
case 16:
|
||||
fault = xc->read(alignedEA, Mem, flags);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size %d!\n", size);
|
||||
panic("Bad operand size %d for read at %#x.\n", size, EA);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
@@ -141,19 +144,22 @@ namespace X86ISA
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->write((uint8_t&)Mem, alignedEA, flags, 0);
|
||||
fault = xc->write((uint8_t&)(Mem.a), alignedEA, flags, 0);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->write((uint16_t&)Mem, alignedEA, flags, 0);
|
||||
fault = xc->write((uint16_t&)(Mem.a), alignedEA, flags, 0);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->write((uint32_t&)Mem, alignedEA, flags, 0);
|
||||
fault = xc->write((uint32_t&)(Mem.a), alignedEA, flags, 0);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->write((uint64_t&)Mem, alignedEA, flags, 0);
|
||||
fault = xc->write((uint64_t&)(Mem.a), alignedEA, flags, 0);
|
||||
break;
|
||||
case 16:
|
||||
fault = xc->write(Mem, alignedEA, flags, 0);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size %d!\n", size);
|
||||
panic("Bad operand size %d for write at %#x.\n", size, EA);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
@@ -123,9 +123,19 @@ def template MicroLoadExecute {{
|
||||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = read(xc, EA, Mem, 0);
|
||||
Twin64_t alignedMem;
|
||||
fault = read(xc, EA, alignedMem, 0);
|
||||
int offset = EA & (dataSize - 1);
|
||||
Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
|
||||
if(dataSize != 8 || !offset)
|
||||
{
|
||||
Mem = bits(alignedMem.a,
|
||||
(offset + dataSize) * 8 - 1, offset * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mem = alignedMem.b << (dataSize - offset) * 8;
|
||||
Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8);
|
||||
}
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
@@ -153,7 +163,8 @@ def template MicroLoadInitiateAcc {{
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
int offset = EA & (dataSize - 1);
|
||||
fault = read(xc, EA, Mem, offset);
|
||||
Twin64_t alignedMem;
|
||||
fault = read(xc, EA, alignedMem, offset);
|
||||
|
||||
return fault;
|
||||
}
|
||||
@@ -169,9 +180,18 @@ def template MicroLoadCompleteAcc {{
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
Twin64_t alignedMem = pkt->get<Twin64_t>();
|
||||
int offset = pkt->req->getFlags();
|
||||
Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
|
||||
if(dataSize != 8 || !offset)
|
||||
{
|
||||
Mem = bits(alignedMem.a,
|
||||
(offset + dataSize) * 8 - 1, offset * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mem = alignedMem.b << (dataSize - offset) * 8;
|
||||
Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8);
|
||||
}
|
||||
%(code)s;
|
||||
|
||||
if(fault == NoFault)
|
||||
@@ -201,8 +221,14 @@ def template MicroStoreExecute {{
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
Mem = Mem << ((EA & (dataSize - 1)) * 8);
|
||||
fault = write(xc, Mem, EA, 0);
|
||||
int offset = EA & (dataSize - 1);
|
||||
|
||||
Twin64_t alignedMem;
|
||||
alignedMem.a = Mem << (offset * 8);
|
||||
alignedMem.b =
|
||||
bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8);
|
||||
|
||||
fault = write(xc, alignedMem, EA, 0);
|
||||
if(fault == NoFault)
|
||||
{
|
||||
%(op_wb)s;
|
||||
@@ -229,8 +255,14 @@ def template MicroStoreInitiateAcc {{
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
Mem = Mem << ((EA & (dataSize - 1)) * 8);
|
||||
fault = write(xc, Mem, EA, 0);
|
||||
int offset = EA & (dataSize - 1);
|
||||
|
||||
Twin64_t alignedMem;
|
||||
alignedMem.a = Mem << (offset * 8);
|
||||
alignedMem.b =
|
||||
bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8);
|
||||
|
||||
fault = write(xc, alignedMem, EA, 0);
|
||||
if(fault == NoFault)
|
||||
{
|
||||
%(op_wb)s;
|
||||
|
||||
Reference in New Issue
Block a user