namespace AlphaISA {
uint64_t
-getArgument(ThreadContext *tc, int number, bool fp)
+getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp)
{
#if FULL_SYSTEM
const int NumArgumentRegs = 6;
copyIprs(src, dest);
}
+void
+skipFunction(ThreadContext *tc)
+{
+ Addr newpc = tc->readIntReg(ReturnAddressReg);
+ tc->setPC(newpc);
+ tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
+}
+
+
} // namespace AlphaISA
namespace AlphaISA {
-uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp);
inline bool
inUserMode(ThreadContext *tc)
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+void skipFunction(ThreadContext *tc);
} // namespace AlphaISA
#endif // __ARCH_ALPHA_UTILITY_HH__
virtual Addr fixFuncEventAddr(Addr addr)
{
- //XXX This may eventually have to do something useful.
+ // Remove the low bit that thumb symbols have set
+ // but that aren't actually odd aligned
+ if (addr & 0x1)
+ return (addr & ~1) | PcTBit;
return addr;
}
};
#include "arch/arm/utility.hh"
#include "cpu/thread_context.hh"
+#if FULL_SYSTEM
+#include "arch/arm/vtophys.hh"
+#include "mem/vport.hh"
+#endif
namespace ArmISA {
reset->invoke(tc);
}
-uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp) {
#if FULL_SYSTEM
+ if (fp)
+ panic("getArgument(): Floating point arguments not implemented\n");
+
if (number < NumArgumentRegs) {
- if (fp)
- panic("getArgument(): Floating point arguments not implemented\n");
- else
- return tc->readIntReg(number);
- }
- else {
- panic("getArgument(): Argument index %d beyond max supported (%d).\n",
- number, NumArgumentRegs - 1);
+ // If the argument is 64 bits, it must be in an even regiser number
+ // Increment the number here if it isn't even
+ if (size == sizeof(uint64_t)) {
+ if ((number % 2) != 0)
+ number++;
+ // Read the two halves of the data
+ // number is inc here to get the second half of the 64 bit reg
+ uint64_t tmp;
+ tmp = tc->readIntReg(number++);
+ tmp |= tc->readIntReg(number) << 32;
+ return tmp;
+ } else {
+ return tc->readIntReg(number);
+ }
+ } else {
+ Addr sp = tc->readIntReg(StackPointerReg);
+ VirtualPort *vp = tc->getVirtPort();
+ uint64_t arg;
+ if (size == sizeof(uint64_t)) {
+ // If the argument is even it must be aligned
+ if ((number % 2) != 0)
+ number++;
+ arg = vp->read<uint64_t>(sp +
+ (number-NumArgumentRegs) * sizeof(uint32_t));
+ // since two 32 bit args == 1 64 bit arg, increment number
+ number++;
+ } else {
+ arg = vp->read<uint32_t>(sp +
+ (number-NumArgumentRegs) * sizeof(uint32_t));
+ }
+ return arg;
}
#else
panic("getArgument() only implemented for FULL_SYSTEM\n");
}
+void
+skipFunction(ThreadContext *tc)
+{
+ Addr newpc = tc->readIntReg(ReturnAddressReg);
+ newpc &= ~ULL(1);
+ if (isThumb(tc->readPC()))
+ tc->setPC(newpc | PcTBit);
+ else
+ tc->setPC(newpc);
+ tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
+}
+
}
return !cpacr.asedis && vfpEnabled(cpacr, cpsr, fpexc);
}
-uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp);
Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
+void skipFunction(ThreadContext *tc);
+
};
namespace MipsISA {
uint64_t
-getArgument(ThreadContext *tc, int number, bool fp)
+getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp)
{
#if FULL_SYSTEM
if (number < 4) {
{
panic("Copy Misc. Regs Not Implemented Yet\n");
}
+void
+skipFunction(ThreadContext *tc)
+{
+ Addr newpc = tc->readIntReg(ReturnAddressReg);
+ tc->setPC(newpc);
+ tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
+ tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
+}
+
} // namespace MipsISA
namespace MipsISA {
-uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp);
////////////////////////////////////////////////////////////////////////
//
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+void skipFunction(ThreadContext *tc);
+
};
dest->setNextPC(src->readNextPC());
}
+void
+skipFunction(ThreadContext *tc)
+{
+ panic("Not Implemented for POWER");
+}
+
+
} // PowerISA namespace
{
}
+void skipFunction(ThreadContext *tc);
+
} // PowerISA namespace
#endif // __ARCH_POWER_UTILITY_HH__
//the sixth are passed on the stack past the 16 word window save area,
//space for the struct/union return pointer, and space reserved for the
//first 6 arguments which the caller may use but doesn't have to.
-uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp) {
#if FULL_SYSTEM
const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
dest->setNextNPC(src->readNextNPC());
}
+void
+skipFunction(ThreadContext *tc)
+{
+ Addr newpc = tc->readIntReg(ReturnAddressReg);
+ tc->setPC(newpc);
+ tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
+ tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
+}
+
+
void
initCPU(ThreadContext *tc, int cpuId)
{
namespace SparcISA
{
- uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+ uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp);
static inline bool
inUserMode(ThreadContext *tc)
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+ void skipFunction(ThreadContext *tc);
+
} // namespace SparcISA
#endif
namespace X86ISA {
-uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
+uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp) {
#if FULL_SYSTEM
panic("getArgument() not implemented for x86!\n");
#else
dest->setNextPC(src->readNextPC());
}
+void
+skipFunction(ThreadContext *tc)
+{
+ panic("Not implemented for x86\n");
+}
+
+
} //namespace X86_ISA
namespace X86ISA
{
- uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+ uint64_t getArgument(ThreadContext *tc, int &number, uint8_t size, bool fp);
static inline bool
inUserMode(ThreadContext *tc)
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+
+ void skipFunction(ThreadContext *tc);
};
#endif // __ARCH_X86_UTILITY_HH__
*/
#include "arch/isa_traits.hh"
+#include "arch/utility.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
void
SkipFuncEvent::process(ThreadContext *tc)
{
- Addr newpc = tc->readIntReg(ReturnAddressReg);
-
DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
- tc->readPC(), newpc);
+ tc->readPC(), tc->readIntReg(ReturnAddressReg));
- tc->setPC(newpc);
- tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
-#if ISA_HAS_DELAY_SLOT
- tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
-#endif
+ // Call ISA specific code to do the skipping
+ TheISA::skipFunction(tc);
}
}
uint64_t
-Arguments::getArg(bool fp)
+Arguments::getArg(uint8_t size, bool fp)
{
- return TheISA::getArgument(tc, number, fp);
+ return TheISA::getArgument(tc, number, size, fp);
}
protected:
ThreadContext *tc;
int number;
- uint64_t getArg(bool fp = false);
+ uint64_t getArg(uint8_t size, bool fp = false);
protected:
class Data : public RefCounted
// for checking if an argument is NULL
bool operator!() {
- return getArg() == 0;
+ return getArg(TheISA::MachineBytes) == 0;
}
Arguments &operator++() {
template <class T>
operator T() {
assert(sizeof(T) <= sizeof(uint64_t));
- T data = static_cast<T>(getArg());
+ T data = static_cast<T>(getArg(sizeof(T)));
return data;
}
template <class T>
operator T *() {
T *buf = (T *)data->alloc(sizeof(T));
- CopyData(tc, buf, getArg(), sizeof(T));
+ CopyData(tc, buf, getArg(sizeof(T)), sizeof(T));
return buf;
}
operator char *() {
char *buf = data->alloc(2048);
- CopyStringOut(tc, buf, getArg(), 2048);
+ CopyStringOut(tc, buf, getArg(TheISA::MachineBytes), 2048);
return buf;
}
};