diff options
Diffstat (limited to 'src/arch/riscv/decoder.cc')
-rw-r--r-- | src/arch/riscv/decoder.cc | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index acda6d04f..36504f4f8 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2012 Google + * Copyright (c) The University of Virginia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,13 +27,71 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Gabe Black + * Alec Roelke */ #include "arch/riscv/decoder.hh" +#include "arch/riscv/types.hh" +#include "debug/Decode.hh" namespace RiscvISA { -GenericISA::BasicDecodeCache Decoder::defaultCache; +void +Decoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst) +{ + DPRINTF(Decode, "Getting bytes 0x%08x from address %#x\n", + inst, pc.pc()); + + bool aligned = pc.pc() % sizeof(MachInst) == 0; + if (mid) { + assert(!aligned); + emi |= (inst & 0xFFFF) << 16; + instDone = true; + } else { + MachInst instChunk = aligned ? inst & 0xFFFF : + (inst & 0xFFFF0000) >> 16; + if (aligned) { + emi = (inst & 0x3) < 0x3 ? instChunk : inst; + instDone = true; + } else { + emi = instChunk; + instDone = (instChunk & 0x3) < 0x3; + } + } + mid = !instDone; +} + +StaticInstPtr +Decoder::decode(ExtMachInst mach_inst, Addr addr) +{ + DPRINTF(Decode, "Decoding instruction 0x%08x at address %#x\n", + mach_inst, addr); + if (instMap.find(mach_inst) != instMap.end()) + return instMap[mach_inst]; + else { + StaticInstPtr si = decodeInst(mach_inst); + instMap[mach_inst] = si; + return si; + } +} + +StaticInstPtr +Decoder::decode(RiscvISA::PCState &nextPC) +{ + if (!instDone) + return nullptr; + instDone = false; + + if ((emi & 0x3) < 0x3) { + nextPC.compressed(true); + nextPC.npc(nextPC.pc() + sizeof(MachInst)/2); + } else { + nextPC.compressed(false); + nextPC.npc(nextPC.pc() + sizeof(MachInst)); + } + + return decode(emi, nextPC.instAddr()); +} } |