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 + 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 + 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(); + 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; } }};