int framereg;
};
+#define SWAP_TARGET_AND_HOST(buffer,len) \
+ do \
+ { \
+ if (TARGET_BYTE_ORDER != HOST_BYTE_ORDER) \
+ { \
+ char tmp; \
+ char *p = (char *)(buffer); \
+ char *q = ((char *)(buffer)) + len - 1; \
+ for (; p < q; p++, q--) \
+ { \
+ tmp = *q; \
+ *q = *p; \
+ *p = tmp; \
+ } \
+ } \
+ } \
+ while (0)
+
/* Will a function return an aggregate type in memory or in a
register? Return 0 if an aggregate type can be returned in a
register, 1 if it must be returned in memory. */
{
CORE_ADDR sp = read_sp ();
- if (PC_IN_CALL_DUMMY (memaddr, sp, sp + 64))
+ /* FIXME: Until we switch for the new call dummy macros, this heuristic
+ is the best we can do. We are trying to determine if the pc is on
+ the stack, which (hopefully) will only happen in a call dummy.
+ We hope the current stack pointer is not so far alway from the dummy
+ frame location (true if we have not pushed large data structures or
+ gone too many levels deep) and that our 1024 is not enough to consider
+ code regions as part of the stack (true for most practical purposes) */
+ if (PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024))
return caller_is_thumb;
else
return 0;
calling the function. */
if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
{
- float f = *(float *) val;
- dbl_arg = f;
- val = (char *) &dbl_arg;
+ float f;
+ double d;
+ char * bufo = (char *) &d;
+ char * bufd = (char *) &dbl_arg;
+
len = sizeof (double);
+ f = *(float *) val;
+ SWAP_TARGET_AND_HOST (&f, sizeof (float)); /* adjust endianess */
+ d = f;
+ /* We must revert the longwords so they get loaded into the
+ the right registers. */
+ memcpy (bufd, bufo + len / 2, len / 2);
+ SWAP_TARGET_AND_HOST (bufd, len / 2); /* adjust endianess */
+ memcpy (bufd + len / 2, bufo, len / 2);
+ SWAP_TARGET_AND_HOST (bufd + len / 2, len / 2); /* adjust endianess */
+ val = (char *) &dbl_arg;
}
#if 1
/* I don't know why this code was disable. The only logical use
void
arm_pop_frame (void)
{
- struct frame_info *frame = get_current_frame ();
int regnum;
- CORE_ADDR old_SP;
+ struct frame_info *frame = get_current_frame ();
+
+ if (!PC_IN_CALL_DUMMY(frame->pc, frame->frame, read_fp()))
+ {
+ CORE_ADDR old_SP;
- old_SP = read_register (frame->framereg);
- for (regnum = 0; regnum < NUM_REGS; regnum++)
- if (frame->fsr.regs[regnum] != 0)
- write_register (regnum,
+ old_SP = read_register (frame->framereg);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
read_memory_integer (frame->fsr.regs[regnum], 4));
- write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
- write_register (SP_REGNUM, old_SP);
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (SP_REGNUM, old_SP);
+ }
+ else
+ {
+ CORE_ADDR sp;
+
+ sp = read_register (FP_REGNUM);
+ sp -= sizeof(CORE_ADDR); /* we don't care about this first word */
+
+ write_register (PC_REGNUM, read_memory_integer (sp, 4));
+ sp -= sizeof(CORE_ADDR);
+ write_register (SP_REGNUM, read_memory_integer (sp, 4));
+ sp -= sizeof(CORE_ADDR);
+ write_register (FP_REGNUM, read_memory_integer (sp, 4));
+ sp -= sizeof(CORE_ADDR);
+
+ for (regnum = 10; regnum >= 0; regnum--)
+ {
+ write_register (regnum, read_memory_integer (sp, 4));
+ sp -= sizeof(CORE_ADDR);
+ }
+ }
flush_cached_frames ();
}