From: Gabe Black Date: Sun, 5 Aug 2007 03:22:20 +0000 (-0700) Subject: X86: Make 64 bit unaligned accesses work as well as the other sizes. X-Git-Tag: m5_2.0_beta4~197 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=802f13e6bdbbc2d6af5a7669a18c0893e5347de6;p=gem5.git 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 --- diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index 8fef14121..fac1fa3aa 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -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; } diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 8dbd4d5cc..403a1aacf 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -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(); + Twin64_t alignedMem = pkt->get(); 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;