From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Blandy To: gdb-patches@sources.redhat.com Subject: RFA: correct mn10300 saved regs handling Date: Sun, 06 May 2001 22:30:00 -0000 Message-id: <20010507053156.33A275E9D5@zwingli.cygnus.com> X-SW-Source: 2001-05/msg00078.html 2001-05-06 Jim Blandy Correct and expand handling of `movm' instruction, and register saves in general. * config/mn10300/tm-mn10300.h (D0_REGNUM, A0_REGNUM, MDRQ_REGNUM, MCRH_REGNUM, MCRL_REGNUM, MCVF_REGNUM): New definitions. (enum movm_register_bits): New enum. * mn10300-tdep.c (set_movm_offsets): Use symbolic names for the bits, not hex literals. Handle the `other', `exreg0', and `exother' bits. Correct handling of `exreg1': it saves r4, r5, r6, and r7, not r2, r3, r4, and r5. (saved_regs_size): New function. (mn10300_frame_chain, mn10300_frame_saved_pc): Use it, instead of computing the same thing inline, incorrectly. *** gdb/mn10300-tdep.c.base Fri May 4 16:27:44 2001 --- gdb/mn10300-tdep.c Sun May 6 20:15:55 2001 *************** *** 216,247 **** if (fi == NULL || movm_args == 0) return; ! if (movm_args & 0x10) { fi->saved_regs[A3_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & 0x20) { fi->saved_regs[A2_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & 0x40) { fi->saved_regs[D3_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & 0x80) { fi->saved_regs[D2_REGNUM] = fi->frame + offset; offset += 4; } ! if (AM33_MODE && movm_args & 0x02) { ! fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset; ! fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 4; ! fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset + 8; ! fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 12; } } --- 216,278 ---- if (fi == NULL || movm_args == 0) return; ! if (movm_args & movm_other_bit) ! { ! fi->saved_regs[LAR_REGNUM] = fi->frame + offset; ! fi->saved_regs[LIR_REGNUM] = fi->frame + offset + 4; ! fi->saved_regs[MDR_REGNUM] = fi->frame + offset + 8; ! fi->saved_regs[A0_REGNUM + 1] = fi->frame + offset + 12; ! fi->saved_regs[A0_REGNUM] = fi->frame + offset + 16; ! fi->saved_regs[D0_REGNUM + 1] = fi->frame + offset + 20; ! fi->saved_regs[D0_REGNUM] = fi->frame + offset + 24; ! offset += 28; ! } ! if (movm_args & movm_a3_bit) { fi->saved_regs[A3_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & movm_a2_bit) { fi->saved_regs[A2_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & movm_d3_bit) { fi->saved_regs[D3_REGNUM] = fi->frame + offset; offset += 4; } ! if (movm_args & movm_d2_bit) { fi->saved_regs[D2_REGNUM] = fi->frame + offset; offset += 4; } ! if (AM33_MODE) { ! if (movm_args & movm_exother_bit) ! { ! fi->saved_regs[MCVF_REGNUM] = fi->frame + offset; ! fi->saved_regs[MCRL_REGNUM] = fi->frame + offset + 4; ! fi->saved_regs[MCRH_REGNUM] = fi->frame + offset + 8; ! fi->saved_regs[MDRQ_REGNUM] = fi->frame + offset + 12; ! fi->saved_regs[E0_REGNUM + 1] = fi->frame + offset + 16; ! fi->saved_regs[E0_REGNUM + 0] = fi->frame + offset + 20; ! offset += 24; ! } ! if (movm_args & movm_exreg1_bit) ! { ! fi->saved_regs[E0_REGNUM + 7] = fi->frame + offset; ! fi->saved_regs[E0_REGNUM + 6] = fi->frame + offset + 4; ! fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset + 8; ! fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 12; ! offset += 16; ! } ! if (movm_args & movm_exreg0_bit) ! { ! fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset; ! fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 4; ! offset += 8; ! } } } *************** *** 529,534 **** --- 560,591 ---- return addr; } + + /* Function: saved_regs_size + Return the size in bytes of the register save area, based on the + saved_regs array in FI. */ + static int + saved_regs_size (struct frame_info *fi) + { + int adjust = 0; + int i; + + /* Reserve four bytes for every register saved. */ + for (i = 0; i < NUM_REGS; i++) + if (fi->saved_regs[i]) + adjust += 4; + + /* If we saved LIR, then it's most likely we used a `movm' + instruction with the `other' bit set, in which case the SP is + decremented by an extra four bytes, "to simplify calculation + of the transfer area", according to the processor manual. */ + if (fi->saved_regs[LIR_REGNUM]) + adjust += 4; + + return adjust; + } + + /* Function: frame_chain Figure out and return the caller's frame pointer given current frame_info struct. *************** *** 579,597 **** } else { ! int adjust = 0; ! ! adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0); ! if (AM33_MODE) ! { ! adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0); ! } /* Our caller does not have a frame pointer. So his frame starts at the base of our frame (fi->frame) + register save space --- 636,642 ---- } else { ! int adjust = saved_regs_size (fi); /* Our caller does not have a frame pointer. So his frame starts at the base of our frame (fi->frame) + register save space *************** *** 767,785 **** static CORE_ADDR mn10300_frame_saved_pc (struct frame_info *fi) { ! int adjust = 0; ! ! adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0); ! adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0); ! if (AM33_MODE) ! { ! adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0); ! adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0); ! } return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE)); } --- 812,818 ---- static CORE_ADDR mn10300_frame_saved_pc (struct frame_info *fi) { ! int adjust = saved_regs_size (fi); return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE)); } *** gdb/config/mn10300/tm-mn10300.h.base Fri May 4 14:55:16 2001 --- gdb/config/mn10300/tm-mn10300.h Sun May 6 20:04:25 2001 *************** *** 43,50 **** --- 43,52 ---- #define REGISTER_RAW_SIZE(REG) 4 #endif + #define D0_REGNUM 0 #define D2_REGNUM 2 #define D3_REGNUM 3 + #define A0_REGNUM 4 #define A2_REGNUM 6 #define A3_REGNUM 7 #define SP_REGNUM 8 *************** *** 53,62 **** --- 55,79 ---- #define PSW_REGNUM 11 #define LIR_REGNUM 12 #define LAR_REGNUM 13 + #define MDRQ_REGNUM 14 #define E0_REGNUM 15 + #define MCRH_REGNUM 26 + #define MCRL_REGNUM 27 + #define MCVF_REGNUM 28 /* start-sanitize-am33-2 */ #define FS0_REGNUM 32 /* end-sanitize-am33-2 */ + + enum movm_register_bits { + movm_exother_bit = 0x01, + movm_exreg1_bit = 0x02, + movm_exreg0_bit = 0x04, + movm_other_bit = 0x08, + movm_a3_bit = 0x10, + movm_a2_bit = 0x20, + movm_d3_bit = 0x40, + movm_d2_bit = 0x80 + }; #define INIT_FRAME_PC /* Not necessary */