/* Target-dependent code for Renesas Super-H, for GDB.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2016 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-/*
- Contributed by Steve Chamberlain
- sac@cygnus.com
- */
+/* Contributed by Steve Chamberlain
+ sac@cygnus.com. */
#include "defs.h"
#include "frame.h"
#include "value.h"
#include "dis-asm.h"
#include "inferior.h"
-#include "gdb_string.h"
-#include "gdb_assert.h"
#include "arch-utils.h"
#include "regcache.h"
#include "osabi.h"
/* sh flags */
#include "elf/sh.h"
-/* registers numbers shared with the simulator */
+/* Register numbers shared with the simulator. */
#include "gdb/sim-sh.h"
#include "language.h"
+#include "sh64-tdep.h"
/* Information that is dependent on the processor variant. */
enum sh_abi
LONGEST sp_offset;
CORE_ADDR pc;
- /* Flag showing that a frame has been created in the prologue code. */
+ /* Flag showing that a frame has been created in the prologue code. */
int uses_fp;
int media_mode;
DR_LAST_REGNUM = 172,
/* FPP stands for Floating Point Pair, to avoid confusion with
GDB's gdbarch_fp0_regnum, which is the number of the first Floating
- point register. Unfortunately on the sh5, the floating point
+ point register. Unfortunately on the sh5, the floating point
registers are called FR, and the floating point pairs are called FP. */
FPP0_REGNUM = 173,
FPP_LAST_REGNUM = 204,
/* status reg., saved status reg., saved pc reg. (64-bit) 65-67 */
"sr", "ssr", "spc",
- /* target registers (64-bit) 68-75*/
+ /* target registers (64-bit) 68-75 */
"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
/* floating point state control register (32-bit) 76 */
"fpscr",
- /* single precision floating point registers (32-bit) 77-140*/
+ /* single precision floating point registers (32-bit) 77-140 */
"fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
"fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
"fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
"dr32", "dr34", "dr36", "dr38", "dr40", "dr42", "dr44", "dr46",
"dr48", "dr50", "dr52", "dr54", "dr56", "dr58", "dr60", "dr62",
- /* floating point pairs (pseudo) 173-204*/
+ /* floating point pairs (pseudo) 173-204 */
"fp0", "fp2", "fp4", "fp6", "fp8", "fp10", "fp12", "fp14",
"fp16", "fp18", "fp20", "fp22", "fp24", "fp26", "fp28", "fp30",
"fp32", "fp34", "fp36", "fp38", "fp40", "fp42", "fp44", "fp46",
"fp48", "fp50", "fp52", "fp54", "fp56", "fp58", "fp60", "fp62",
- /* floating point vectors (4 floating point regs) (pseudo) 205-220*/
+ /* floating point vectors (4 floating point regs) (pseudo) 205-220 */
"fv0", "fv4", "fv8", "fv12", "fv16", "fv20", "fv24", "fv28",
"fv32", "fv36", "fv40", "fv44", "fv48", "fv52", "fv56", "fv60",
- /* SH COMPACT MODE (ISA 16) (all pseudo) 221-272*/
+ /* SH COMPACT MODE (ISA 16) (all pseudo) 221-272 */
"r0_c", "r1_c", "r2_c", "r3_c", "r4_c", "r5_c", "r6_c", "r7_c",
"r8_c", "r9_c", "r10_c", "r11_c", "r12_c", "r13_c", "r14_c", "r15_c",
"pc_c",
"gbr_c", "mach_c", "macl_c", "pr_c", "t_c",
"fpscr_c", "fpul_c",
- "fr0_c", "fr1_c", "fr2_c", "fr3_c", "fr4_c", "fr5_c", "fr6_c", "fr7_c",
- "fr8_c", "fr9_c", "fr10_c", "fr11_c", "fr12_c", "fr13_c", "fr14_c", "fr15_c",
- "dr0_c", "dr2_c", "dr4_c", "dr6_c", "dr8_c", "dr10_c", "dr12_c", "dr14_c",
+ "fr0_c", "fr1_c", "fr2_c", "fr3_c",
+ "fr4_c", "fr5_c", "fr6_c", "fr7_c",
+ "fr8_c", "fr9_c", "fr10_c", "fr11_c",
+ "fr12_c", "fr13_c", "fr14_c", "fr15_c",
+ "dr0_c", "dr2_c", "dr4_c", "dr6_c",
+ "dr8_c", "dr10_c", "dr12_c", "dr14_c",
"fv0_c", "fv4_c", "fv8_c", "fv12_c",
- /* FIXME!!!! XF0 XF15, XD0 XD14 ?????*/
+ /* FIXME!!!! XF0 XF15, XD0 XD14 ????? */
};
if (reg_nr < 0)
if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_SH5_ISA32)
{
MSYMBOL_TARGET_FLAG_1 (msym) = 1;
- SYMBOL_VALUE_ADDRESS (msym) |= 1;
+ SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
}
}
static int
pc_is_isa32 (bfd_vma memaddr)
{
- struct minimal_symbol *sym;
+ struct bound_minimal_symbol sym;
/* If bit 0 of the address is set, assume this is a
ISA32 (shmedia) address. */
the high bit of the info field. Use this to decide if the function is
ISA16 or ISA32. */
sym = lookup_minimal_symbol_by_pc (memaddr);
- if (sym)
- return MSYMBOL_IS_SPECIAL (sym);
+ if (sym.minsym)
+ return MSYMBOL_IS_SPECIAL (sym.minsym);
else
return 0;
}
static const unsigned char *
-sh64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+sh64_breakpoint_from_pc (struct gdbarch *gdbarch,
+ CORE_ADDR *pcptr, int *lenptr)
{
/* The BRK instruction for shmedia is
01101111 11110101 11111111 11110000
/* The BRK instruction for shcompact is
00000000 00111011
which translates in big endian mode to 0x0, 0x3b
- and in little endian mode to 0x3b, 0x0*/
+ and in little endian mode to 0x3b, 0x0 */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
if (pc_is_isa32 (*pcptr))
{
- static unsigned char big_breakpoint_media[] = {0x6f, 0xf5, 0xff, 0xf0};
+ static unsigned char big_breakpoint_media[] = {
+ 0x6f, 0xf5, 0xff, 0xf0
+ };
*pcptr = UNMAKE_ISA32_ADDR (*pcptr);
*lenptr = sizeof (big_breakpoint_media);
return big_breakpoint_media;
{
if (pc_is_isa32 (*pcptr))
{
- static unsigned char little_breakpoint_media[] = {0xf0, 0xff, 0xf5, 0x6f};
+ static unsigned char little_breakpoint_media[] = {
+ 0xf0, 0xff, 0xf5, 0x6f
+ };
*pcptr = UNMAKE_ISA32_ADDR (*pcptr);
*lenptr = sizeof (little_breakpoint_media);
return little_breakpoint_media;
R15 + R63 --> R14 */
#define IS_ADD_SP_FP_MEDIA(x) ((x) == 0x00f9fce0)
-#define IS_MOV_SP_FP_MEDIA(x) (IS_ADDL_SP_FP_MEDIA(x) || IS_ADD_SP_FP_MEDIA(x))
+#define IS_MOV_SP_FP_MEDIA(x) \
+ (IS_ADDL_SP_FP_MEDIA(x) || IS_ADD_SP_FP_MEDIA(x))
/* MOV #imm, R0 1110 0000 ssss ssss
#imm-->R0 */
/* ADD Rm,R63,Rn Rm+R63-->Rn 0000 00mm mmmm 1001 1111 11nn nnnn 0000
where Rm is one of r2-r9 which are the argument registers. */
-/* FIXME: Recognize the float and double register moves too! */
+/* FIXME: Recognize the float and double register moves too! */
#define IS_MEDIA_IND_ARG_MOV(x) \
-((((x) & 0xfc0ffc0f) == 0x0009fc00) && (((x) & 0x03f00000) >= 0x00200000 && ((x) & 0x03f00000) <= 0x00900000))
+ ((((x) & 0xfc0ffc0f) == 0x0009fc00) \
+ && (((x) & 0x03f00000) >= 0x00200000 \
+ && ((x) & 0x03f00000) <= 0x00900000))
/* ST.Q Rn,0,Rm Rm-->Rn+0 1010 11nn nnnn 0000 0000 00mm mmmm 0000
or ST.L Rn,0,Rm Rm-->Rn+0 1010 10nn nnnn 0000 0000 00mm mmmm 0000
(((((x) & 0xfc0ffc0f) == 0xac000000) || (((x) & 0xfc0ffc0f) == 0xa8000000)) \
&& (((x) & 0x000003f0) >= 0x00000020 && ((x) & 0x000003f0) <= 0x00000090))
-/* ST.B R14,0,Rn Rn-->(R14+0) 1010 0000 1110 0000 0000 00nn nnnn 0000*/
-/* ST.W R14,0,Rn Rn-->(R14+0) 1010 0100 1110 0000 0000 00nn nnnn 0000*/
-/* ST.L R14,0,Rn Rn-->(R14+0) 1010 1000 1110 0000 0000 00nn nnnn 0000*/
-/* FST.S R14,0,FRn Rn-->(R14+0) 1011 0100 1110 0000 0000 00nn nnnn 0000*/
-/* FST.D R14,0,DRn Rn-->(R14+0) 1011 1100 1110 0000 0000 00nn nnnn 0000*/
+/* ST.B R14,0,Rn Rn-->(R14+0) 1010 0000 1110 0000 0000 00nn nnnn 0000 */
+/* ST.W R14,0,Rn Rn-->(R14+0) 1010 0100 1110 0000 0000 00nn nnnn 0000 */
+/* ST.L R14,0,Rn Rn-->(R14+0) 1010 1000 1110 0000 0000 00nn nnnn 0000 */
+/* FST.S R14,0,FRn Rn-->(R14+0) 1011 0100 1110 0000 0000 00nn nnnn 0000 */
+/* FST.D R14,0,DRn Rn-->(R14+0) 1011 1100 1110 0000 0000 00nn nnnn 0000 */
#define IS_MEDIA_MOV_TO_R14(x) \
((((x) & 0xfffffc0f) == 0xa0e00000) \
|| (((x) & 0xfffffc0f) == 0xa4e00000) \
/* MOV Rm, Rn Rm-->Rn 0110 nnnn mmmm 0011
where Rm is r2-r9 */
#define IS_COMPACT_IND_ARG_MOV(x) \
-((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0020) && (((x) & 0x00f0) <= 0x0090))
+ ((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0020) \
+ && (((x) & 0x00f0) <= 0x0090))
/* compact direct arg move!
MOV.L Rn, @r14 0010 1110 mmmm 0010 */
#define IS_COMPACT_ARG_MOV(x) \
-(((((x) & 0xff0f) == 0x2e02) && (((x) & 0x00f0) >= 0x0020) && ((x) & 0x00f0) <= 0x0090))
+ (((((x) & 0xff0f) == 0x2e02) && (((x) & 0x00f0) >= 0x0020) \
+ && ((x) & 0x00f0) <= 0x0090))
/* MOV.B Rm, @R14 0010 1110 mmmm 0000
MOV.W Rm, @R14 0010 1110 mmmm 0001 */
r15+imm-->r15 */
#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
-/* Skip any prologue before the guts of a function */
+/* Skip any prologue before the guts of a function. */
/* Skip the prologue using the debug information. If this fails we'll
fall back on the 'guess' method below. */
if (IS_MEDIA_IND_ARG_MOV (w))
{
/* This must be followed by a store to r14, so the argument
- is where the debug info says it is. This can happen after
+ is where the debug info says it is. This can happen after
the SP has been saved, unfortunately. */
int next_insn = read_memory_integer (UNMAKE_ISA32_ADDR (here),
if (IS_COMPACT_IND_ARG_MOV (w))
{
/* This must be followed by a store to r14, so the argument
- is where the debug info says it is. This can happen after
+ is where the debug info says it is. This can happen after
the SP has been saved, unfortunately. */
int next_insn = 0xffff & read_memory_integer (here, insn_size,
else if (IS_MOVL_R0 (w))
{
/* There is a function that gcc calls to get the arguments
- passed correctly to the function. Only after this
+ passed correctly to the function. Only after this
function call the arguments will be found at the place
- where they are supposed to be. This happens in case the
+ where they are supposed to be. This happens in case the
argument has to be stored into a 64-bit register (for
instance doubles, long longs). SHcompact doesn't have
access to the full 64-bits, so we store the register in
value in a stack slot and stores the address of the
stack slot in the register. GCC thinks the argument is
just passed by transparent reference, but this is only
- true after the argument decoder is called. Such a call
+ true after the argument decoder is called. Such a call
needs to be considered part of the prologue. */
/* This must be followed by a JSR @r0 instruction and by
- a NOP instruction. After these, the prologue is over! */
+ a NOP instruction. After these, the prologue is over! */
int next_insn = 0xffff & read_memory_integer (here, insn_size,
byte_order);
here += insn_size;
if (IS_STQ_R18_R14 (w) || IS_STQ_R18_R15 (w) || IS_STQ_R14_R15 (w)
|| IS_STL_R14_R15 (w) || IS_STL_R18_R15 (w)
- || IS_ADDIL_SP_MEDIA (w) || IS_ADDI_SP_MEDIA (w) || IS_PTABSL_R18 (w))
+ || IS_ADDIL_SP_MEDIA (w) || IS_ADDI_SP_MEDIA (w)
+ || IS_PTABSL_R18 (w))
{
start_pc = here;
}
return fp_regnum;
}
-/* For double precision floating point registers, i.e 2 fp regs.*/
+/* For double precision floating point registers, i.e 2 fp regs. */
static int
sh64_dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum)
{
return fp_regnum;
}
-/* For pairs of floating point registers */
+/* For pairs of floating point registers. */
static int
sh64_fpp_reg_base_num (struct gdbarch *gdbarch, int fpp_regnum)
{
CORE_ADDR func_pc,
CORE_ADDR current_pc)
{
- int reg_nr;
int pc;
int opc;
int insn;
insn_size, byte_order);
if (IS_MOV_TO_R15 (next_insn))
{
- cache->saved_regs[PR_REGNUM] =
- cache->sp_offset - ((((next_insn & 0xf) ^ 0x8) - 0x8) << 2);
+ cache->saved_regs[PR_REGNUM]
+ = cache->sp_offset - ((((next_insn & 0xf) ^ 0x8)
+ - 0x8) << 2);
pc += insn_size;
}
}
else if (IS_MOV_R0 (insn))
{
/* Put in R0 the offset from SP at which to store some
- registers. We are interested in this value, because it
+ registers. We are interested in this value, because it
will tell us where the given registers are stored within
the frame. */
r0_val = ((insn & 0xff) ^ 0x80) - 0x80;
else if (IS_STS_R0 (insn))
{
- /* Store PR at r0_val-4 from SP. Decrement r0 by 4*/
+ /* Store PR at r0_val-4 from SP. Decrement r0 by 4. */
cache->saved_regs[PR_REGNUM] = cache->sp_offset - (r0_val - 4);
r0_val -= 4;
}
else if (IS_MOV_R14_R0 (insn))
{
- /* Store R14 at r0_val-4 from SP. Decrement r0 by 4 */
+ /* Store R14 at r0_val-4 from SP. Decrement r0 by 4. */
cache->saved_regs[MEDIA_FP_REGNUM] = cache->sp_offset
- (r0_val - 4);
r0_val -= 4;
sign_extend ((((insn & 0xffc00) ^ 0x80000) - 0x80000) >> 10, 9);
else if (IS_STQ_R18_R15 (insn))
- cache->saved_regs[PR_REGNUM] =
- cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
+ cache->saved_regs[PR_REGNUM]
+ = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
+ 9) << 3);
else if (IS_STL_R18_R15 (insn))
- cache->saved_regs[PR_REGNUM] =
- cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
+ cache->saved_regs[PR_REGNUM]
+ = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
+ 9) << 2);
else if (IS_STQ_R14_R15 (insn))
- cache->saved_regs[MEDIA_FP_REGNUM] =
- cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
+ cache->saved_regs[MEDIA_FP_REGNUM]
+ = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
+ 9) << 3);
else if (IS_STL_R14_R15 (insn))
- cache->saved_regs[MEDIA_FP_REGNUM] =
- cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
+ cache->saved_regs[MEDIA_FP_REGNUM]
+ = cache->sp_offset - (sign_extend ((insn & 0xffc00) >> 10,
+ 9) << 2);
else if (IS_MOV_SP_FP_MEDIA (insn))
break;
Arguments that are larger than 4 bytes may be split between two or
more registers. If there are not enough registers free, an argument
may be passed partly in a register (or registers), and partly on the
- stack. This includes doubles, long longs, and larger aggregates.
+ stack. This includes doubles, long longs, and larger aggregates.
As far as I know, there is no upper limit to the size of aggregates
that will be passed in this way; in other words, the convention of
passing a pointer to a large aggregate instead of a copy is not used.
is greater than one byte). In this case, a pointer to the return
value location is passed into the callee in register R2, which does
not displace any of the other arguments passed in via registers R4
- to R7. */
+ to R7. */
/* R2-R9 for integer types and integer equivalent (char, pointers) and
non-scalar (struct, union) elements (even if the elements are
If a float is argument number 3 (for instance) and arguments number
1,2, and 4 are integer, the mapping will be:
- arg1 -->R2, arg2 --> R3, arg3 -->FR0, arg4 --> R5. I.e. R4 is not used.
+ arg1 -->R2, arg2 --> R3, arg3 -->FR0, arg4 --> R5. I.e. R4 is not used.
If a float is argument number 10 (for instance) and arguments number
1 through 10 are integer, the mapping will be:
arg1->R2, arg2->R3, arg3->R4, arg4->R5, arg5->R6, arg6->R7, arg7->R8,
- arg8->R9, arg9->(0,SP)stack(8-byte aligned), arg10->FR0, arg11->stack(16,SP).
- I.e. there is hole in the stack.
+ arg8->R9, arg9->(0,SP)stack(8-byte aligned), arg10->FR0,
+ arg11->stack(16,SP). I.e. there is hole in the stack.
Different rules apply for variable arguments functions, and for functions
for which the prototype is not known. */
int argnum;
struct type *type;
CORE_ADDR regval;
- char *val;
- char valbuf[8];
- char valbuf_tmp[8];
+ const gdb_byte *val;
+ gdb_byte valbuf[8];
int len;
int argreg_size;
int fp_args[12];
memset (fp_args, 0, sizeof (fp_args));
- /* first force sp to a 8-byte alignment */
+ /* First force sp to a 8-byte alignment. */
sp = sh64_frame_align (gdbarch, sp);
/* The "struct return pointer" pseudo-argument has its own dedicated
- register */
+ register. */
if (struct_return)
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
- /* Now make sure there's space on the stack */
+ /* Now make sure there's space on the stack. */
for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
stack_alloc += ((TYPE_LENGTH (value_type (args[argnum])) + 7) & ~7);
- sp -= stack_alloc; /* make room on stack for args */
+ sp -= stack_alloc; /* Make room on stack for args. */
/* Now load as many as possible of the first arguments into
registers, and push the rest onto the stack. There are 64 bytes
if (len < argreg_size)
{
- /* value gets right-justified in the register or stack word */
+ /* value gets right-justified in the register or stack word. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
memcpy (valbuf + argreg_size - len,
- (char *) value_contents (args[argnum]), len);
+ value_contents (args[argnum]), len);
else
- memcpy (valbuf, (char *) value_contents (args[argnum]), len);
+ memcpy (valbuf, value_contents (args[argnum]), len);
val = valbuf;
}
else
- val = (char *) value_contents (args[argnum]);
+ val = value_contents (args[argnum]);
while (len > 0)
{
if (int_argreg > ARGLAST_REGNUM)
{
- /* must go on the stack */
- write_memory (sp + stack_offset, (const bfd_byte *) val,
- argreg_size);
+ /* Must go on the stack. */
+ write_memory (sp + stack_offset, val, argreg_size);
stack_offset += 8;/*argreg_size;*/
}
/* NOTE WELL!!!!! This is not an "else if" clause!!!
AND in the registers! */
if (int_argreg <= ARGLAST_REGNUM)
{
- /* there's room in a register */
+ /* There's room in a register. */
regval = extract_unsigned_integer (val, argreg_size,
byte_order);
- regcache_cooked_write_unsigned (regcache, int_argreg, regval);
+ regcache_cooked_write_unsigned (regcache,
+ int_argreg, regval);
}
/* Store the value 8 bytes at a time. This means that
things larger than 8 bytes may go partly in registers
- and partly on the stack. FIXME: argreg is incremented
+ and partly on the stack. FIXME: argreg is incremented
before we use its size. */
len -= argreg_size;
val += argreg_size;
}
else
{
- val = (char *) value_contents (args[argnum]);
+ val = value_contents (args[argnum]);
if (len == 4)
{
- /* Where is it going to be stored? */
+ /* Where is it going to be stored? */
while (fp_args[float_arg_index])
float_arg_index ++;
/* Now float_argreg points to the register where it
should be stored. Are we still within the allowed
- register set? */
+ register set? */
if (float_arg_index <= FLOAT_ARGLAST_REGNUM)
{
/* Goes in FR0...FR11 */
int_argreg ++;
}
else
- ;
- /* Store it as the integers, 8 bytes at the time, if
- necessary spilling on the stack. */
-
+ {
+ /* Store it as the integers, 8 bytes at the time, if
+ necessary spilling on the stack. */
+ }
}
else if (len == 8)
{
- /* Where is it going to be stored? */
+ /* Where is it going to be stored? */
while (fp_args[double_arg_index])
double_arg_index += 2;
/* Now double_argreg points to the register
where it should be stored.
- Are we still within the allowed register set? */
+ Are we still within the allowed register set? */
if (double_arg_index < FLOAT_ARGLAST_REGNUM)
{
/* Goes in DR0...DR10 */
int_argreg ++;
}
else
- ;
- /* Store it as the integers, 8 bytes at the time, if
- necessary spilling on the stack. */
+ {
+ /* Store it as the integers, 8 bytes at the time, if
+ necessary spilling on the stack. */
+ }
}
}
}
- /* Store return address. */
+ /* Store return address. */
regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
/* Update stack pointer. */
TYPE, and copy that, in virtual format, into VALBUF. */
static void
sh64_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
{
if (len == 4)
{
- /* Return value stored in gdbarch_fp0_regnum */
+ /* Return value stored in gdbarch_fp0_regnum. */
regcache_raw_read (regcache,
gdbarch_fp0_regnum (gdbarch), valbuf);
}
else if (len == 8)
{
- /* return value stored in DR0_REGNUM */
+ /* return value stored in DR0_REGNUM. */
DOUBLEST val;
gdb_byte buf[8];
if (len <= 8)
{
int offset;
- char buf[8];
- /* Result is in register 2. If smaller than 8 bytes, it is padded
+ gdb_byte buf[8];
+ /* Result is in register 2. If smaller than 8 bytes, it is padded
at the most significant end. */
regcache_raw_read (regcache, DEFAULT_RETURN_REGNUM, buf);
of type TYPE, given in virtual format.
If the architecture is sh4 or sh3e, store a function's return value
in the R0 general register or in the FP0 floating point register,
- depending on the type of the return value. In all the other cases
+ depending on the type of the return value. In all the other cases
the result is stored in r0, left-justified. */
static void
sh64_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- char buf[64]; /* more than enough... */
+ gdb_byte buf[64]; /* more than enough... */
int len = TYPE_LENGTH (type);
if (TYPE_CODE (type) == TYPE_CODE_FLT)
for (i = 0; i < len; i += 4)
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
regcache_raw_write (regcache, regnum++,
- (char *) valbuf + len - 4 - i);
+ valbuf + len - 4 - i);
else
- regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
+ regcache_raw_write (regcache, regnum++, valbuf + i);
}
else
{
}
static enum return_value_convention
-sh64_return_value (struct gdbarch *gdbarch, struct type *func_type,
+sh64_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static void
-sh64_show_media_regs (struct frame_info *frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- int i;
-
- printf_filtered
- ("PC=%s SR=%s\n",
- phex (get_frame_register_unsigned (frame,
- gdbarch_pc_regnum (gdbarch)), 8),
- phex (get_frame_register_unsigned (frame, SR_REGNUM), 8));
-
- printf_filtered
- ("SSR=%s SPC=%s\n",
- phex (get_frame_register_unsigned (frame, SSR_REGNUM), 8),
- phex (get_frame_register_unsigned (frame, SPC_REGNUM), 8));
- printf_filtered
- ("FPSCR=%s\n ",
- phex (get_frame_register_unsigned (frame, FPSCR_REGNUM), 8));
-
- for (i = 0; i < 64; i = i + 4)
- printf_filtered
- ("\nR%d-R%d %s %s %s %s\n",
- i, i + 3,
- phex (get_frame_register_unsigned (frame, i + 0), 8),
- phex (get_frame_register_unsigned (frame, i + 1), 8),
- phex (get_frame_register_unsigned (frame, i + 2), 8),
- phex (get_frame_register_unsigned (frame, i + 3), 8));
-
- printf_filtered ("\n");
-
- for (i = 0; i < 64; i = i + 8)
- printf_filtered
- ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- i, i + 7,
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 0),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 1),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 2),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 3),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 4),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 5),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 6),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 7));
-}
-
-static void
-sh64_show_compact_regs (struct frame_info *frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- int i;
-
- printf_filtered
- ("PC=%s\n",
- phex (get_frame_register_unsigned (frame, PC_C_REGNUM), 8));
-
- printf_filtered
- ("GBR=%08lx MACH=%08lx MACL=%08lx PR=%08lx T=%08lx\n",
- (long) get_frame_register_unsigned (frame, GBR_C_REGNUM),
- (long) get_frame_register_unsigned (frame, MACH_C_REGNUM),
- (long) get_frame_register_unsigned (frame, MACL_C_REGNUM),
- (long) get_frame_register_unsigned (frame, PR_C_REGNUM),
- (long) get_frame_register_unsigned (frame, T_C_REGNUM));
- printf_filtered
- ("FPSCR=%08lx FPUL=%08lx\n",
- (long) get_frame_register_unsigned (frame, FPSCR_C_REGNUM),
- (long) get_frame_register_unsigned (frame, FPUL_C_REGNUM));
-
- for (i = 0; i < 16; i = i + 4)
- printf_filtered
- ("\nR%d-R%d %08lx %08lx %08lx %08lx\n",
- i, i + 3,
- (long) get_frame_register_unsigned (frame, i + 0),
- (long) get_frame_register_unsigned (frame, i + 1),
- (long) get_frame_register_unsigned (frame, i + 2),
- (long) get_frame_register_unsigned (frame, i + 3));
-
- printf_filtered ("\n");
-
- for (i = 0; i < 16; i = i + 8)
- printf_filtered
- ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- i, i + 7,
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 0),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 1),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 2),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 3),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 4),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 5),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 6),
- (long) get_frame_register_unsigned
- (frame, gdbarch_fp0_regnum (gdbarch) + i + 7));
-}
-
-/* FIXME!!! This only shows the registers for shmedia, excluding the
- pseudo registers. */
-void
-sh64_show_regs (struct frame_info *frame)
-{
- if (pc_is_isa32 (get_frame_pc (frame)))
- sh64_show_media_regs (frame);
- else
- sh64_show_compact_regs (frame);
-}
-
/* *INDENT-OFF* */
/*
SH MEDIA MODE (ISA 32)
static void
sh64_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum,
- struct type *type, char *from, char *to)
+ struct type *type, gdb_byte *from, gdb_byte *to)
{
if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_LITTLE)
{
"with non DR register number"));
}
-static void
+/* Concatenate PORTIONS contiguous raw registers starting at
+ BASE_REGNUM into BUFFER. */
+
+static enum register_status
+pseudo_register_read_portions (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int portions,
+ int base_regnum, gdb_byte *buffer)
+{
+ int portion;
+
+ for (portion = 0; portion < portions; portion++)
+ {
+ enum register_status status;
+ gdb_byte *b;
+
+ b = buffer + register_size (gdbarch, base_regnum) * portion;
+ status = regcache_raw_read (regcache, base_regnum + portion, b);
+ if (status != REG_VALID)
+ return status;
+ }
+
+ return REG_VALID;
+}
+
+static enum register_status
sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int base_regnum;
- int portion;
int offset = 0;
- char temp_buffer[MAX_REGISTER_SIZE];
+ gdb_byte temp_buffer[MAX_REGISTER_SIZE];
+ enum register_status status;
if (reg_nr >= DR0_REGNUM
&& reg_nr <= DR_LAST_REGNUM)
/* Build the value in the provided buffer. */
/* DR regs are double precision registers obtained by
concatenating 2 single precision floating point registers. */
- for (portion = 0; portion < 2; portion++)
- regcache_raw_read (regcache, base_regnum + portion,
- (temp_buffer
- + register_size (gdbarch, base_regnum) * portion));
-
- /* We must pay attention to the endianness. */
- sh64_register_convert_to_virtual (gdbarch, reg_nr,
- register_type (gdbarch, reg_nr),
- temp_buffer, buffer);
+ status = pseudo_register_read_portions (gdbarch, regcache,
+ 2, base_regnum, temp_buffer);
+ if (status == REG_VALID)
+ {
+ /* We must pay attention to the endianness. */
+ sh64_register_convert_to_virtual (gdbarch, reg_nr,
+ register_type (gdbarch, reg_nr),
+ temp_buffer, buffer);
+ }
+ return status;
}
- else if (reg_nr >= FPP0_REGNUM
+ else if (reg_nr >= FPP0_REGNUM
&& reg_nr <= FPP_LAST_REGNUM)
{
base_regnum = sh64_fpp_reg_base_num (gdbarch, reg_nr);
/* Build the value in the provided buffer. */
/* FPP regs are pairs of single precision registers obtained by
concatenating 2 single precision floating point registers. */
- for (portion = 0; portion < 2; portion++)
- regcache_raw_read (regcache, base_regnum + portion,
- ((char *) buffer
- + register_size (gdbarch, base_regnum) * portion));
+ return pseudo_register_read_portions (gdbarch, regcache,
+ 2, base_regnum, buffer);
}
else if (reg_nr >= FV0_REGNUM
/* Build the value in the provided buffer. */
/* FV regs are vectors of single precision registers obtained by
concatenating 4 single precision floating point registers. */
- for (portion = 0; portion < 4; portion++)
- regcache_raw_read (regcache, base_regnum + portion,
- ((char *) buffer
- + register_size (gdbarch, base_regnum) * portion));
+ return pseudo_register_read_portions (gdbarch, regcache,
+ 4, base_regnum, buffer);
}
- /* sh compact pseudo registers. 1-to-1 with a shmedia register */
+ /* sh compact pseudo registers. 1-to-1 with a shmedia register. */
else if (reg_nr >= R0_C_REGNUM
&& reg_nr <= T_C_REGNUM)
{
base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
/* Build the value in the provided buffer. */
- regcache_raw_read (regcache, base_regnum, temp_buffer);
+ status = regcache_raw_read (regcache, base_regnum, temp_buffer);
+ if (status != REG_VALID)
+ return status;
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
offset = 4;
- memcpy (buffer, temp_buffer + offset, 4); /* get LOWER 32 bits only????*/
+ memcpy (buffer,
+ temp_buffer + offset, 4); /* get LOWER 32 bits only???? */
+ return REG_VALID;
}
else if (reg_nr >= FP0_C_REGNUM
/* Build the value in the provided buffer. */
/* Floating point registers map 1-1 to the media fp regs,
they have the same size and endianness. */
- regcache_raw_read (regcache, base_regnum, buffer);
+ return regcache_raw_read (regcache, base_regnum, buffer);
}
else if (reg_nr >= DR0_C_REGNUM
/* DR_C regs are double precision registers obtained by
concatenating 2 single precision floating point registers. */
- for (portion = 0; portion < 2; portion++)
- regcache_raw_read (regcache, base_regnum + portion,
- (temp_buffer
- + register_size (gdbarch, base_regnum) * portion));
-
- /* We must pay attention to the endianness. */
- sh64_register_convert_to_virtual (gdbarch, reg_nr,
- register_type (gdbarch, reg_nr),
- temp_buffer, buffer);
+ status = pseudo_register_read_portions (gdbarch, regcache,
+ 2, base_regnum, temp_buffer);
+ if (status == REG_VALID)
+ {
+ /* We must pay attention to the endianness. */
+ sh64_register_convert_to_virtual (gdbarch, reg_nr,
+ register_type (gdbarch, reg_nr),
+ temp_buffer, buffer);
+ }
+ return status;
}
else if (reg_nr >= FV0_C_REGNUM
/* Build the value in the provided buffer. */
/* FV_C regs are vectors of single precision registers obtained by
concatenating 4 single precision floating point registers. */
- for (portion = 0; portion < 4; portion++)
- regcache_raw_read (regcache, base_regnum + portion,
- ((char *) buffer
- + register_size (gdbarch, base_regnum) * portion));
+ return pseudo_register_read_portions (gdbarch, regcache,
+ 4, base_regnum, buffer);
}
else if (reg_nr == FPSCR_C_REGNUM)
21-31 reserved
*/
/* *INDENT-ON* */
- /* Get FPSCR into a local buffer */
- regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
+ /* Get FPSCR into a local buffer. */
+ status = regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
+ if (status != REG_VALID)
+ return status;
/* Get value as an int. */
fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
/* Get SR into a local buffer */
- regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
+ status = regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
+ if (status != REG_VALID)
+ return status;
/* Get value as an int. */
sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
/* Build the new value. */
fpscr_c_part1_value = fpscr_value & 0x3fffd;
fpscr_c_part2_value = (sr_value & 0x7000) << 6;
fpscr_c_value = fpscr_c_part1_value | fpscr_c_part2_value;
- /* Store that in out buffer!!! */
+ /* Store that in out buffer!!! */
store_unsigned_integer (buffer, 4, byte_order, fpscr_c_value);
/* FIXME There is surely an endianness gotcha here. */
+
+ return REG_VALID;
}
else if (reg_nr == FPUL_C_REGNUM)
/* FPUL_C register is floating point register 32,
same size, same endianness. */
- regcache_raw_read (regcache, base_regnum, buffer);
+ return regcache_raw_read (regcache, base_regnum, buffer);
}
+ else
+ gdb_assert_not_reached ("invalid pseudo register number");
}
static void
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int base_regnum, portion;
int offset;
- char temp_buffer[MAX_REGISTER_SIZE];
+ gdb_byte temp_buffer[MAX_REGISTER_SIZE];
if (reg_nr >= DR0_REGNUM
&& reg_nr <= DR_LAST_REGNUM)
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
(temp_buffer
- + register_size (gdbarch,
+ + register_size (gdbarch,
base_regnum) * portion));
}
/* Write the real regs for which this one is an alias. */
for (portion = 0; portion < 2; portion++)
regcache_raw_write (regcache, base_regnum + portion,
- ((char *) buffer
- + register_size (gdbarch,
- base_regnum) * portion));
+ (buffer + register_size (gdbarch,
+ base_regnum) * portion));
}
else if (reg_nr >= FV0_REGNUM
/* Write the real regs for which this one is an alias. */
for (portion = 0; portion < 4; portion++)
regcache_raw_write (regcache, base_regnum + portion,
- ((char *) buffer
- + register_size (gdbarch,
- base_regnum) * portion));
+ (buffer + register_size (gdbarch,
+ base_regnum) * portion));
}
- /* sh compact general pseudo registers. 1-to-1 with a shmedia
+ /* sh compact general pseudo registers. 1-to-1 with a shmedia
register but only 4 bytes of it. */
else if (reg_nr >= R0_C_REGNUM
&& reg_nr <= T_C_REGNUM)
buffer, so that overwriting the last four bytes with the new
value of the pseudo will leave the upper 4 bytes unchanged. */
regcache_raw_read (regcache, base_regnum, temp_buffer);
- /* Write as an 8 byte quantity */
+ /* Write as an 8 byte quantity. */
memcpy (temp_buffer + offset, buffer, 4);
regcache_raw_write (regcache, base_regnum, temp_buffer);
}
- /* sh floating point compact pseudo registers. 1-to-1 with a shmedia
- registers. Both are 4 bytes. */
+ /* sh floating point compact pseudo registers. 1-to-1 with a shmedia
+ registers. Both are 4 bytes. */
else if (reg_nr >= FP0_C_REGNUM
&& reg_nr <= FP_LAST_C_REGNUM)
{
for (portion = 0; portion < 4; portion++)
{
regcache_raw_write (regcache, base_regnum + portion,
- ((char *) buffer
+ (buffer
+ register_size (gdbarch,
base_regnum) * portion));
}
static void
sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file,
struct frame_info *frame, int regnum)
-{ /* do values for FP (float) regs */
+{ /* Do values for FP (float) regs. */
unsigned char *raw_buffer;
- double flt; /* double extracted from raw hex data */
+ double flt; /* Double extracted from raw hex data. */
int inv;
int j;
/* Allocate space for the float. */
- raw_buffer = (unsigned char *) alloca
- (register_size (gdbarch,
- gdbarch_fp0_regnum
- (gdbarch)));
+ raw_buffer = (unsigned char *)
+ alloca (register_size (gdbarch, gdbarch_fp0_regnum (gdbarch)));
/* Get the data in raw format. */
- if (!frame_register_read (frame, regnum, raw_buffer))
+ if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
error (_("can't read register %d (%s)"),
regnum, gdbarch_register_name (gdbarch, regnum));
- /* Get the register as a number */
- flt = unpack_double (builtin_type (gdbarch)->builtin_float, raw_buffer, &inv);
+ /* Get the register as a number. */
+ flt = unpack_double (builtin_type (gdbarch)->builtin_float,
+ raw_buffer, &inv);
/* Print the name and some spaces. */
fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
fprintf_filtered (file, "%-10.9g", flt);
/* Print the fp register as hex. */
- fprintf_filtered (file, "\t(raw 0x");
- for (j = 0; j < register_size (gdbarch, regnum); j++)
- {
- int idx = gdbarch_byte_order (gdbarch)
- == BFD_ENDIAN_BIG ? j : register_size
- (gdbarch, regnum) - 1 - j;
- fprintf_filtered (file, "%02x", raw_buffer[idx]);
- }
+ fprintf_filtered (file, "\t(raw ");
+ print_hex_chars (file, raw_buffer,
+ register_size (gdbarch, regnum),
+ gdbarch_byte_order (gdbarch));
fprintf_filtered (file, ")");
fprintf_filtered (file, "\n");
}
(gdbarch, regnum)), file);
/* Get the data in raw format. */
- if (!frame_register_read (frame, regnum, raw_buffer))
- fprintf_filtered (file, "*value not available*\n");
+ if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
+ {
+ fprintf_filtered (file, "*value not available*\n");
+ return;
+ }
get_formatted_print_options (&opts, 'x');
opts.deref_ref = 1;
struct frame_info *frame, int regnum,
int fpregs)
{
- if (regnum != -1) /* do one specified register */
+ if (regnum != -1) /* Do one specified register. */
{
if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
error (_("Not a valid register for the current processor type"));
sh64_print_register (gdbarch, file, frame, regnum);
}
else
- /* do all (or most) registers */
+ /* Do all (or most) registers. */
{
regnum = 0;
while (regnum < gdbarch_num_regs (gdbarch))
{
if (fpregs)
{
- /* true for "INFO ALL-REGISTERS" command */
+ /* true for "INFO ALL-REGISTERS" command. */
sh64_do_fp_register (gdbarch, file, frame, regnum);
regnum ++;
}
struct frame_info *frame, int regnum,
int fpregs)
{
- if (regnum != -1) /* do one specified register */
+ if (regnum != -1) /* Do one specified register. */
{
if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
error (_("Not a valid register for the current processor type"));
sh64_print_register (gdbarch, file, frame, regnum);
}
else
- /* do all compact registers */
+ /* Do all compact registers. */
{
regnum = R0_C_REGNUM;
while (regnum < gdbarch_num_regs (gdbarch)
int i;
if (*this_cache)
- return *this_cache;
+ return (struct sh64_frame_cache *) *this_cache;
gdbarch = get_frame_arch (this_frame);
cache = sh64_alloc_frame_cache ();
which holds the base address for the current stack frame.
However, for functions that don't need it, the frame pointer is
optional. For these "frameless" functions the frame pointer is
- actually the frame pointer of the calling frame. */
+ actually the frame pointer of the calling frame. */
cache->base = get_frame_register_unsigned (this_frame, MEDIA_FP_REGNUM);
if (cache->base == 0)
return cache;
static const struct frame_unwind sh64_frame_unwind = {
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
sh64_frame_this_id,
sh64_frame_prev_register,
NULL,
/* None found, create a new architecture from the information
provided. */
- tdep = XMALLOC (struct gdbarch_tdep);
+ tdep = XNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
/* Determine the ABI */