2004-02-07 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / tui / tui-regs.c
CommitLineData
f377b406 1/* TUI display registers in window.
f33c6cbf 2
55fb0713
AC
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4 Foundation, Inc.
f33c6cbf 5
f377b406 6 Contributed by Hewlett-Packard Company.
c906108c 7
f377b406 8 This file is part of GDB.
c906108c 9
f377b406
SC
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
c906108c
SS
24
25#include "defs.h"
d7b2e967
AC
26#include "tui/tui.h"
27#include "tui/tui-data.h"
c906108c
SS
28#include "symtab.h"
29#include "gdbtypes.h"
30#include "gdbcmd.h"
31#include "frame.h"
bc77de56 32#include "regcache.h"
c906108c
SS
33#include "inferior.h"
34#include "target.h"
6d012f14 35#include "gdb_string.h"
d7b2e967
AC
36#include "tui/tui-layout.h"
37#include "tui/tui-win.h"
38#include "tui/tui-windata.h"
39#include "tui/tui-wingeneral.h"
40#include "tui/tui-file.h"
c906108c 41
96ec9981
DJ
42#ifdef HAVE_NCURSES_H
43#include <ncurses.h>
44#else
45#ifdef HAVE_CURSES_H
46#include <curses.h>
47#endif
48#endif
49
c906108c
SS
50/*****************************************
51** LOCAL DEFINITIONS **
52******************************************/
53#define DOUBLE_FLOAT_LABEL_WIDTH 6
54#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
55#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
56
57#define SINGLE_FLOAT_LABEL_WIDTH 6
58#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
59#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
60
c46cc7df 61#define SINGLE_LABEL_WIDTH 16
c906108c 62#define SINGLE_LABEL_FMT "%10.10s: "
c46cc7df 63#define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
c906108c
SS
64
65/* In the code HP gave Cygnus, this was actually a function call to a
66 PA-specific function, which was supposed to determine whether the
67 target was a 64-bit or 32-bit processor. However, the 64-bit
68 support wasn't complete, so we didn't merge that in, so we leave
69 this here as a stub. */
70#define IS_64BIT 0
71
72/*****************************************
73** STATIC DATA **
74******************************************/
75
76
77/*****************************************
78** STATIC LOCAL FUNCTIONS FORWARD DECLS **
79******************************************/
6ba8e26f 80static enum tui_status tui_set_regs_content
2a8854a7 81 (int, int, struct frame_info *, enum tui_register_display_type, int);
6ba8e26f
AC
82static const char *tui_register_name (int);
83static enum tui_status tui_get_register_raw_value (int, char *, struct frame_info *);
84static void tui_set_register_element
2a8854a7 85 (int, struct frame_info *, struct tui_data_element *, int);
6ba8e26f
AC
86static void tui_display_register (int, struct tui_gen_win_info *, enum precision_type);
87static void tui_register_format
2a8854a7 88 (char *, int, int, struct tui_data_element *, enum precision_type);
6ba8e26f
AC
89static enum tui_status tui_set_general_regs_content (int);
90static enum tui_status tui_set_special_regs_content (int);
91static enum tui_status tui_set_general_and_special_regs_content (int);
92static enum tui_status tui_set_float_regs_content (enum tui_register_display_type, int);
93static int tui_reg_value_has_changed
2a8854a7 94 (struct tui_data_element *, struct frame_info *, char *);
6ba8e26f
AC
95static void tui_show_float_command (char *, int);
96static void tui_show_general_command (char *, int);
97static void tui_show_special_command (char *, int);
98static void tui_v_show_registers_command_support (enum tui_register_display_type);
99static void _tui_toggle_float_regs_command (char *, int);
100static void tui_scroll_regs_forward_command (char *, int);
101static void tui_scroll_regs_backward_command (char *, int);
c906108c
SS
102
103
104
105/*****************************************
106** PUBLIC FUNCTIONS **
107******************************************/
108
55fb0713
AC
109/* Answer the number of the last line in the regs display. If there
110 are no registers (-1) is returned. */
c906108c 111int
55fb0713 112tui_last_regs_line_no (void)
c906108c 113{
6ba8e26f 114 register int num_lines = (-1);
c906108c 115
6d012f14 116 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 117 {
6ba8e26f 118 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
6d012f14
AC
119 TUI_DATA_WIN->detail.data_display_info.regs_column_count);
120 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
121 TUI_DATA_WIN->detail.data_display_info.regs_column_count)
6ba8e26f 122 num_lines++;
c906108c 123 }
6ba8e26f 124 return num_lines;
55fb0713 125}
c906108c
SS
126
127
6ba8e26f
AC
128/* Answer the line number that the register element at element_no is
129 on. If element_no is greater than the number of register elements
55fb0713 130 there are, -1 is returned. */
c906108c 131int
6ba8e26f 132tui_line_from_reg_element_no (int element_no)
c906108c 133{
6ba8e26f 134 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
c906108c
SS
135 {
136 int i, line = (-1);
137
138 i = 1;
139 while (line == (-1))
140 {
6ba8e26f 141 if (element_no <
6d012f14 142 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
c906108c
SS
143 line = i - 1;
144 else
145 i++;
146 }
147
148 return line;
149 }
150 else
151 return (-1);
55fb0713 152}
c906108c
SS
153
154
6ba8e26f 155/* Answer the index of the first element in line_no. If line_no is past
55fb0713 156 the register area (-1) is returned. */
c906108c 157int
6ba8e26f 158tui_first_reg_element_no_inline (int line_no)
c906108c 159{
6ba8e26f 160 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
6d012f14 161 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
6ba8e26f 162 return ((line_no + 1) *
6d012f14
AC
163 TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
164 TUI_DATA_WIN->detail.data_display_info.regs_column_count;
c906108c
SS
165 else
166 return (-1);
55fb0713 167}
c906108c
SS
168
169
6ba8e26f
AC
170/* Answer the index of the last element in line_no. If line_no is
171 past the register area (-1) is returned. */
c906108c 172int
6ba8e26f 173tui_last_reg_element_no_in_line (int line_no)
c906108c 174{
6ba8e26f 175 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <=
6d012f14 176 TUI_DATA_WIN->detail.data_display_info.regs_content_count)
6ba8e26f 177 return ((line_no + 1) *
6d012f14 178 TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1;
c906108c
SS
179 else
180 return (-1);
6ba8e26f 181}
c906108c
SS
182
183
55fb0713
AC
184/* Calculate the number of columns that should be used to display the
185 registers. */
c906108c 186int
6ba8e26f 187tui_calculate_regs_column_count (enum tui_register_display_type dpy_type)
c906108c 188{
6ba8e26f 189 int col_count, col_width;
c906108c 190
6ba8e26f
AC
191 if (IS_64BIT || dpy_type == TUI_DFLOAT_REGS)
192 col_width = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
193 else
194 {
6ba8e26f
AC
195 if (dpy_type == TUI_SFLOAT_REGS)
196 col_width = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
c906108c 197 else
6ba8e26f 198 col_width = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
c906108c 199 }
6ba8e26f 200 col_count = (TUI_DATA_WIN->generic.width - 2) / col_width;
c906108c 201
6ba8e26f
AC
202 return col_count;
203}
c906108c
SS
204
205
6ba8e26f 206/* Show the registers int the data window as indicated by dpy_type. If
55fb0713 207 there is any other registers being displayed, then they are
6ba8e26f 208 cleared. What registers are displayed is dependent upon dpy_type. */
c906108c 209void
6ba8e26f 210tui_show_registers (enum tui_register_display_type dpy_type)
c906108c 211{
22940a24 212 enum tui_status ret = TUI_FAILURE;
6ba8e26f 213 int refresh_values_only = FALSE;
c906108c
SS
214
215 /* Say that registers should be displayed, even if there is a problem */
6d012f14 216 TUI_DATA_WIN->detail.data_display_info.display_regs = TRUE;
c906108c
SS
217
218 if (target_has_registers)
219 {
6ba8e26f
AC
220 refresh_values_only =
221 (dpy_type == TUI_DATA_WIN->detail.data_display_info.regs_display_type);
222 switch (dpy_type)
c906108c
SS
223 {
224 case TUI_GENERAL_REGS:
6ba8e26f 225 ret = tui_set_general_regs_content (refresh_values_only);
c906108c
SS
226 break;
227 case TUI_SFLOAT_REGS:
228 case TUI_DFLOAT_REGS:
6ba8e26f 229 ret = tui_set_float_regs_content (dpy_type, refresh_values_only);
c906108c
SS
230 break;
231
232/* could ifdef out */
233
234 case TUI_SPECIAL_REGS:
6ba8e26f 235 ret = tui_set_special_regs_content (refresh_values_only);
c906108c
SS
236 break;
237 case TUI_GENERAL_AND_SPECIAL_REGS:
6ba8e26f 238 ret = tui_set_general_and_special_regs_content (refresh_values_only);
c906108c
SS
239 break;
240
241/* end of potential if def */
242
243 default:
244 break;
245 }
246 }
247 if (ret == TUI_FAILURE)
248 {
6d012f14 249 TUI_DATA_WIN->detail.data_display_info.regs_display_type = TUI_UNDEFINED_REGS;
edae1ccf 250 tui_erase_data_content (NO_REGS_STRING);
c906108c
SS
251 }
252 else
253 {
254 int i;
255
256 /* Clear all notation of changed values */
6d012f14 257 for (i = 0; (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); i++)
c906108c 258 {
6ba8e26f 259 struct tui_gen_win_info * data_item_win;
c906108c 260
6ba8e26f 261 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 262 regs_content[i]->which_element.data_window;
2a8854a7 263 (&((struct tui_win_element *)
6ba8e26f 264 data_item_win->content[0])->which_element.data)->highlight = FALSE;
c906108c 265 }
6ba8e26f 266 TUI_DATA_WIN->detail.data_display_info.regs_display_type = dpy_type;
edae1ccf 267 tui_display_all_data ();
c906108c 268 }
6ba8e26f 269 (tui_layout_def ())->regs_display_type = dpy_type;
c906108c
SS
270
271 return;
55fb0713 272}
c906108c
SS
273
274
55fb0713 275/* Function to display the registers in the content from
6ba8e26f 276 'start_element_no' until the end of the register content or the end
55fb0713
AC
277 of the display height. No checking for displaying past the end of
278 the registers is done here. */
c906108c 279void
6ba8e26f 280tui_display_registers_from (int start_element_no)
c906108c 281{
6d012f14
AC
282 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL &&
283 TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 284 {
6ba8e26f
AC
285 register int i = start_element_no;
286 int j, value_chars_wide, item_win_width, cur_y, label_width;
c906108c
SS
287 enum precision_type precision;
288
6d012f14 289 precision = (TUI_DATA_WIN->detail.data_display_info.regs_display_type
c906108c
SS
290 == TUI_DFLOAT_REGS) ?
291 double_precision : unspecified_precision;
292 if (IS_64BIT ||
6d012f14 293 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS)
c906108c 294 {
6ba8e26f
AC
295 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
296 label_width = DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
297 }
298 else
299 {
6d012f14 300 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
301 TUI_SFLOAT_REGS)
302 {
6ba8e26f
AC
303 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
304 label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
305 }
306 else
307 {
6ba8e26f
AC
308 value_chars_wide = SINGLE_VALUE_WIDTH;
309 label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
310 }
311 }
6ba8e26f 312 item_win_width = value_chars_wide + label_width;
c906108c 313 /*
c5aa993b
JM
314 ** Now create each data "sub" window, and write the display into it.
315 */
6ba8e26f 316 cur_y = 1;
6d012f14 317 while (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count &&
6ba8e26f 318 cur_y <= TUI_DATA_WIN->generic.viewport_height)
c906108c
SS
319 {
320 for (j = 0;
6d012f14
AC
321 (j < TUI_DATA_WIN->detail.data_display_info.regs_column_count &&
322 i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); j++)
c906108c 323 {
6ba8e26f
AC
324 struct tui_gen_win_info * data_item_win;
325 struct tui_data_element * data_element_ptr;
c906108c 326
c5aa993b 327 /* create the window if necessary */
6ba8e26f 328 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 329 regs_content[i]->which_element.data_window;
6ba8e26f
AC
330 data_element_ptr = &((struct tui_win_element *)
331 data_item_win->content[0])->which_element.data;
332 if (data_item_win->handle == (WINDOW *) NULL)
c906108c 333 {
6ba8e26f
AC
334 data_item_win->height = 1;
335 data_item_win->width = (precision == double_precision) ?
336 item_win_width + 2 : item_win_width + 1;
337 data_item_win->origin.x = (item_win_width * j) + 1;
338 data_item_win->origin.y = cur_y;
339 tui_make_window (data_item_win, DONT_BOX_WINDOW);
340 scrollok (data_item_win->handle, FALSE);
c906108c 341 }
6ba8e26f 342 touchwin (data_item_win->handle);
fea14702 343
c906108c 344 /*
c5aa993b
JM
345 ** Get the printable representation of the register
346 ** and display it
347 */
6ba8e26f
AC
348 tui_display_register (
349 data_element_ptr->item_no, data_item_win, precision);
c906108c
SS
350 i++; /* next register */
351 }
6ba8e26f 352 cur_y++; /* next row; */
c906108c
SS
353 }
354 }
355
356 return;
55fb0713 357}
c906108c
SS
358
359
6ba8e26f
AC
360/* Function to display the registers in the content from
361 'start_element_no' on 'start_line_no' until the end of the register
362 content or the end of the display height. This function checks
363 that we won't display off the end of the register display. */
c906108c 364void
6ba8e26f 365tui_display_reg_element_at_line (int start_element_no, int start_line_no)
c906108c 366{
6d012f14
AC
367 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL &&
368 TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 369 {
6ba8e26f 370 register int element_no = start_element_no;
c906108c 371
6ba8e26f 372 if (start_element_no != 0 && start_line_no != 0)
c906108c 373 {
6ba8e26f 374 register int last_line_no, first_line_on_last_page;
c906108c 375
6ba8e26f
AC
376 last_line_no = tui_last_regs_line_no ();
377 first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2);
378 if (first_line_on_last_page < 0)
379 first_line_on_last_page = 0;
c906108c 380 /*
c5aa993b 381 ** If there is no other data displayed except registers,
6ba8e26f 382 ** and the element_no causes us to scroll past the end of the
c5aa993b
JM
383 ** registers, adjust what element to really start the display at.
384 */
6d012f14 385 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0 &&
6ba8e26f
AC
386 start_line_no > first_line_on_last_page)
387 element_no = tui_first_reg_element_no_inline (first_line_on_last_page);
c906108c 388 }
6ba8e26f 389 tui_display_registers_from (element_no);
c906108c 390 }
6ba8e26f 391}
c906108c
SS
392
393
394
6ba8e26f 395/* Function to display the registers starting at line line_no in the
55fb0713
AC
396 data window. Answers the line number that the display actually
397 started from. If nothing is displayed (-1) is returned. */
c906108c 398int
6ba8e26f 399tui_display_registers_from_line (int line_no, int force_display)
c906108c 400{
6d012f14 401 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 402 {
6ba8e26f 403 int line, element_no;
c906108c 404
6ba8e26f 405 if (line_no < 0)
c906108c 406 line = 0;
6ba8e26f 407 else if (force_display)
c906108c 408 { /*
6ba8e26f 409 ** If we must display regs (force_display is true), then make
c5aa993b
JM
410 ** sure that we don't display off the end of the registers.
411 */
6ba8e26f 412 if (line_no >= tui_last_regs_line_no ())
c906108c 413 {
55fb0713 414 if ((line = tui_line_from_reg_element_no (
6d012f14 415 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
c906108c
SS
416 line = 0;
417 }
418 else
6ba8e26f 419 line = line_no;
c906108c
SS
420 }
421 else
6ba8e26f 422 line = line_no;
c906108c 423
6ba8e26f
AC
424 element_no = tui_first_reg_element_no_inline (line);
425 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
426 tui_display_reg_element_at_line (element_no, line);
c906108c
SS
427 else
428 line = (-1);
429
430 return line;
431 }
432
433 return (-1); /* nothing was displayed */
55fb0713 434}
c906108c
SS
435
436
55fb0713
AC
437/* This function check all displayed registers for changes in values,
438 given a particular frame. If the values have changed, they are
439 updated with the new value and highlighted. */
c906108c 440void
55fb0713 441tui_check_register_values (struct frame_info *frame)
c906108c 442{
6d012f14 443 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
c906108c 444 {
6d012f14
AC
445 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count <= 0 &&
446 TUI_DATA_WIN->detail.data_display_info.display_regs)
447 tui_show_registers ((tui_layout_def ())->regs_display_type);
c906108c
SS
448 else
449 {
450 int i, j;
6ba8e26f 451 char raw_buf[MAX_REGISTER_SIZE];
c906108c
SS
452
453 for (i = 0;
6d012f14 454 (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); i++)
c906108c 455 {
6ba8e26f
AC
456 struct tui_data_element * data_element_ptr;
457 struct tui_gen_win_info * data_item_win_ptr;
458 int was_hilighted;
c906108c 459
6ba8e26f 460 data_item_win_ptr = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 461 regs_content[i]->which_element.data_window;
6ba8e26f
AC
462 data_element_ptr = &((struct tui_win_element *)
463 data_item_win_ptr->content[0])->which_element.data;
464 was_hilighted = data_element_ptr->highlight;
465 data_element_ptr->highlight =
466 tui_reg_value_has_changed (data_element_ptr, frame, &raw_buf[0]);
467 if (data_element_ptr->highlight)
c906108c 468 {
c46cc7df
SC
469 int size;
470
6ba8e26f 471 size = DEPRECATED_REGISTER_RAW_SIZE (data_element_ptr->item_no);
c46cc7df 472 for (j = 0; j < size; j++)
6ba8e26f
AC
473 ((char *) data_element_ptr->value)[j] = raw_buf[j];
474 tui_display_register (
475 data_element_ptr->item_no,
476 data_item_win_ptr,
6d012f14 477 ((TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
478 TUI_DFLOAT_REGS) ?
479 double_precision : unspecified_precision));
480 }
6ba8e26f 481 else if (was_hilighted)
c906108c 482 {
6ba8e26f
AC
483 data_element_ptr->highlight = FALSE;
484 tui_display_register (
485 data_element_ptr->item_no,
486 data_item_win_ptr,
6d012f14 487 ((TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
488 TUI_DFLOAT_REGS) ?
489 double_precision : unspecified_precision));
490 }
491 }
492 }
493 }
494 return;
55fb0713 495}
c906108c
SS
496
497
498/*
6ba8e26f 499 ** tui_toggle_float_regs().
c5aa993b 500 */
c906108c 501void
6ba8e26f 502tui_toggle_float_regs (void)
c906108c 503{
6ba8e26f 504 struct tui_layout_def * layout_def = tui_layout_def ();
c906108c 505
6ba8e26f
AC
506 if (layout_def->float_regs_display_type == TUI_SFLOAT_REGS)
507 layout_def->float_regs_display_type = TUI_DFLOAT_REGS;
c906108c 508 else
6ba8e26f 509 layout_def->float_regs_display_type = TUI_SFLOAT_REGS;
c906108c 510
6d012f14
AC
511 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible &&
512 (TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_SFLOAT_REGS ||
513 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS))
6ba8e26f 514 tui_show_registers (layout_def->float_regs_display_type);
c906108c
SS
515
516 return;
6ba8e26f 517} /* tui_toggle_float_regs */
c906108c
SS
518
519
520void
6ba8e26f 521_initialize_tui_regs (void)
c906108c 522{
41783295 523 if (xdb_commands)
c906108c 524 {
6ba8e26f 525 add_com ("fr", class_tui, tui_show_float_command,
c906108c 526 "Display only floating point registers\n");
6ba8e26f 527 add_com ("gr", class_tui, tui_show_general_command,
c906108c 528 "Display only general registers\n");
6ba8e26f 529 add_com ("sr", class_tui, tui_show_special_command,
c906108c 530 "Display only special registers\n");
6ba8e26f 531 add_com ("+r", class_tui, tui_scroll_regs_forward_command,
c906108c 532 "Scroll the registers window forward\n");
6ba8e26f 533 add_com ("-r", class_tui, tui_scroll_regs_backward_command,
c906108c 534 "Scroll the register window backward\n");
6ba8e26f 535 add_com ("tf", class_tui, _tui_toggle_float_regs_command,
c906108c
SS
536 "Toggle between single and double precision floating point registers.\n");
537 add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
538 class_tui,
6ba8e26f 539 _tui_toggle_float_regs_command,
c906108c
SS
540 "Toggle between single and double precision floating point \
541registers.\n",
542 &togglelist);
543 }
41783295 544}
c906108c
SS
545
546
547/*****************************************
548** STATIC LOCAL FUNCTIONS **
549******************************************/
550
551
552/*
6ba8e26f 553 ** tui_register_name().
c5aa993b
JM
554 ** Return the register name.
555 */
bc77de56 556static const char *
6ba8e26f 557tui_register_name (int reg_num)
c906108c 558{
6ba8e26f 559 return REGISTER_NAME (reg_num);
c46cc7df
SC
560}
561extern int pagination_enabled;
c906108c 562
c46cc7df
SC
563static void
564tui_restore_gdbout (void *ui)
565{
566 ui_file_delete (gdb_stdout);
567 gdb_stdout = (struct ui_file*) ui;
568 pagination_enabled = 1;
569}
c906108c
SS
570
571/*
6ba8e26f 572 ** tui_register_format
c5aa993b
JM
573 ** Function to format the register name and value into a buffer,
574 ** suitable for printing or display
575 */
c906108c 576static void
6ba8e26f
AC
577tui_register_format (char *buf, int buf_len, int reg_num,
578 struct tui_data_element * data_element,
eca6576c 579 enum precision_type precision)
c906108c 580{
d9fcf2fb 581 struct ui_file *stream;
c46cc7df 582 struct ui_file *old_stdout;
bc77de56 583 const char *name;
c46cc7df
SC
584 struct cleanup *cleanups;
585 char *p;
fea14702 586 int pos;
c906108c 587
6ba8e26f 588 name = REGISTER_NAME (reg_num);
c46cc7df
SC
589 if (name == 0)
590 {
591 strcpy (buf, "");
592 return;
593 }
594
595 pagination_enabled = 0;
596 old_stdout = gdb_stdout;
6ba8e26f 597 stream = tui_sfileopen (buf_len);
c46cc7df
SC
598 gdb_stdout = stream;
599 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
6e7f8b9c 600 gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame,
6ba8e26f 601 reg_num, 1);
c906108c 602
c46cc7df 603 /* Save formatted output in the buffer. */
fea14702
SC
604 p = tui_file_get_strbuf (stream);
605 pos = 0;
6ba8e26f 606 while (*p && *p == *name++ && buf_len)
fea14702
SC
607 {
608 *buf++ = *p++;
6ba8e26f 609 buf_len--;
fea14702
SC
610 pos++;
611 }
612 while (*p == ' ')
613 p++;
6ba8e26f 614 while (pos < 8 && buf_len)
fea14702
SC
615 {
616 *buf++ = ' ';
6ba8e26f 617 buf_len--;
fea14702
SC
618 pos++;
619 }
6ba8e26f 620 strncpy (buf, p, buf_len);
c46cc7df
SC
621
622 /* Remove the possible \n. */
623 p = strchr (buf, '\n');
624 if (p)
625 *p = 0;
626
627 do_cleanups (cleanups);
628}
c906108c
SS
629
630
631#define NUM_GENERAL_REGS 32
6ba8e26f
AC
632/* Set the content of the data window to consist of the general
633 registers. */
22940a24 634static enum tui_status
6ba8e26f 635tui_set_general_regs_content (int refresh_values_only)
c906108c 636{
6ba8e26f 637 return (tui_set_regs_content (0,
c906108c 638 NUM_GENERAL_REGS - 1,
6e7f8b9c 639 deprecated_selected_frame,
c906108c 640 TUI_GENERAL_REGS,
6ba8e26f 641 refresh_values_only));
c906108c 642
6ba8e26f 643}
c906108c
SS
644
645
c46cc7df
SC
646#ifndef PCOQ_HEAD_REGNUM
647#define START_SPECIAL_REGS 0
648#else
c906108c 649#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
c46cc7df
SC
650#endif
651
6ba8e26f
AC
652/* Set the content of the data window to consist of the special
653 registers. */
22940a24 654static enum tui_status
6ba8e26f 655tui_set_special_regs_content (int refresh_values_only)
c906108c 656{
22940a24 657 enum tui_status ret = TUI_FAILURE;
6ba8e26f 658 int end_reg_num;
c906108c 659
6ba8e26f
AC
660 end_reg_num = FP0_REGNUM - 1;
661 ret = tui_set_regs_content (START_SPECIAL_REGS,
662 end_reg_num,
6e7f8b9c 663 deprecated_selected_frame,
c906108c 664 TUI_SPECIAL_REGS,
6ba8e26f 665 refresh_values_only);
c906108c
SS
666
667 return ret;
6ba8e26f 668}
c906108c
SS
669
670
6ba8e26f
AC
671/* Set the content of the data window to consist of the special
672 registers. */
22940a24 673static enum tui_status
6ba8e26f 674tui_set_general_and_special_regs_content (int refresh_values_only)
c906108c 675{
22940a24 676 enum tui_status ret = TUI_FAILURE;
6ba8e26f 677 int end_reg_num = (-1);
c906108c 678
6ba8e26f
AC
679 end_reg_num = FP0_REGNUM - 1;
680 ret = tui_set_regs_content (
681 0, end_reg_num, deprecated_selected_frame, TUI_SPECIAL_REGS, refresh_values_only);
c906108c
SS
682
683 return ret;
6ba8e26f 684}
c906108c 685
6ba8e26f
AC
686/* Set the content of the data window to consist of the float
687 registers. */
22940a24 688static enum tui_status
6ba8e26f
AC
689tui_set_float_regs_content (enum tui_register_display_type dpy_type,
690 int refresh_values_only)
c906108c 691{
22940a24 692 enum tui_status ret = TUI_FAILURE;
6ba8e26f 693 int start_reg_num;
c906108c 694
6ba8e26f
AC
695 start_reg_num = FP0_REGNUM;
696 ret = tui_set_regs_content (start_reg_num,
a728f042 697 NUM_REGS - 1,
6e7f8b9c 698 deprecated_selected_frame,
6ba8e26f
AC
699 dpy_type,
700 refresh_values_only);
c906108c
SS
701
702 return ret;
6ba8e26f 703}
c906108c
SS
704
705
6ba8e26f
AC
706/* Answer TRUE if the register's value has changed, FALSE otherwise.
707 If TRUE, new_value is filled in with the new value. */
c906108c 708static int
6ba8e26f
AC
709tui_reg_value_has_changed (struct tui_data_element * data_element,
710 struct frame_info *frame, char *new_value)
c906108c 711{
6ba8e26f 712 int has_changed = FALSE;
c906108c 713
6ba8e26f
AC
714 if (data_element->item_no != UNDEFINED_ITEM &&
715 tui_register_name (data_element->item_no) != (char *) NULL)
c906108c 716 {
6ba8e26f 717 char raw_buf[MAX_REGISTER_SIZE];
c906108c
SS
718 int i;
719
6ba8e26f 720 if (tui_get_register_raw_value (data_element->item_no, raw_buf, frame) == TUI_SUCCESS)
c906108c 721 {
6ba8e26f 722 int size = DEPRECATED_REGISTER_RAW_SIZE (data_element->item_no);
c46cc7df 723
6ba8e26f
AC
724 for (i = 0; (i < size && !has_changed); i++)
725 has_changed = (((char *) data_element->value)[i] != raw_buf[i]);
726 if (has_changed && new_value != (char *) NULL)
c906108c 727 {
c46cc7df 728 for (i = 0; i < size; i++)
6ba8e26f 729 new_value[i] = raw_buf[i];
c906108c
SS
730 }
731 }
732 }
6ba8e26f
AC
733 return has_changed;
734}
c906108c
SS
735
736
737
6ba8e26f 738/* Get the register raw value. The raw value is returned in reg_value. */
22940a24 739static enum tui_status
6ba8e26f 740tui_get_register_raw_value (int reg_num, char *reg_value, struct frame_info *frame)
c906108c 741{
22940a24 742 enum tui_status ret = TUI_FAILURE;
c906108c
SS
743
744 if (target_has_registers)
745 {
6ba8e26f 746 get_frame_register (frame, reg_num, reg_value);
ac2adee5
AC
747 /* NOTE: cagney/2003-03-13: This is bogus. It is refering to
748 the register cache and not the frame which could have pulled
749 the register value off the stack. */
6ba8e26f 750 if (register_cached (reg_num) >= 0)
c46cc7df 751 ret = TUI_SUCCESS;
c906108c 752 }
c906108c 753 return ret;
6ba8e26f 754}
c906108c
SS
755
756
757
6ba8e26f
AC
758/* Function to initialize a data element with the input and the
759 register value. */
c906108c 760static void
6ba8e26f
AC
761tui_set_register_element (int reg_num, struct frame_info *frame,
762 struct tui_data_element * data_element,
763 int refresh_value_only)
c906108c 764{
6ba8e26f 765 if (data_element != (struct tui_data_element *) NULL)
c906108c 766 {
6ba8e26f 767 if (!refresh_value_only)
c906108c 768 {
6ba8e26f
AC
769 data_element->item_no = reg_num;
770 data_element->name = tui_register_name (reg_num);
771 data_element->highlight = FALSE;
c906108c 772 }
6ba8e26f
AC
773 if (data_element->value == NULL)
774 data_element->value = xmalloc (MAX_REGISTER_SIZE);
775 if (data_element->value != NULL)
776 tui_get_register_raw_value (reg_num, data_element->value, frame);
c906108c 777 }
6ba8e26f 778}
c906108c
SS
779
780
6ba8e26f
AC
781/* Set the content of the data window to consist of the registers
782 numbered from start_reg_num to end_reg_num. Note that if
783 refresh_values_only is TRUE, start_reg_num and end_reg_num are
784 ignored. */
22940a24 785static enum tui_status
6ba8e26f 786tui_set_regs_content (int start_reg_num, int end_reg_num,
eca6576c 787 struct frame_info *frame,
6ba8e26f
AC
788 enum tui_register_display_type dpy_type,
789 int refresh_values_only)
c906108c 790{
22940a24 791 enum tui_status ret = TUI_FAILURE;
6ba8e26f
AC
792 int num_regs = end_reg_num - start_reg_num + 1;
793 int allocated_here = FALSE;
c906108c 794
6d012f14 795 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0 &&
6ba8e26f 796 !refresh_values_only)
c906108c 797 {
6d012f14
AC
798 tui_free_data_content (TUI_DATA_WIN->detail.data_display_info.regs_content,
799 TUI_DATA_WIN->detail.data_display_info.regs_content_count);
800 TUI_DATA_WIN->detail.data_display_info.regs_content_count = 0;
c906108c 801 }
6d012f14 802 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count <= 0)
c906108c 803 {
6d012f14 804 TUI_DATA_WIN->detail.data_display_info.regs_content =
6ba8e26f
AC
805 tui_alloc_content (num_regs, DATA_WIN);
806 allocated_here = TRUE;
c906108c
SS
807 }
808
6d012f14 809 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL)
c906108c
SS
810 {
811 int i;
812
6ba8e26f 813 if (!refresh_values_only || allocated_here)
c906108c 814 {
6d012f14
AC
815 TUI_DATA_WIN->generic.content = NULL;
816 TUI_DATA_WIN->generic.content_size = 0;
6ba8e26f 817 tui_add_content_elements (&TUI_DATA_WIN->generic, num_regs);
6d012f14
AC
818 TUI_DATA_WIN->detail.data_display_info.regs_content =
819 (tui_win_content) TUI_DATA_WIN->generic.content;
6ba8e26f 820 TUI_DATA_WIN->detail.data_display_info.regs_content_count = num_regs;
c906108c
SS
821 }
822 /*
c5aa993b
JM
823 ** Now set the register names and values
824 */
6ba8e26f 825 for (i = start_reg_num; (i <= end_reg_num); i++)
c906108c 826 {
6ba8e26f 827 struct tui_gen_win_info * data_item_win;
c906108c 828
6ba8e26f
AC
829 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
830 regs_content[i - start_reg_num]->which_element.data_window;
831 tui_set_register_element (
c906108c
SS
832 i,
833 frame,
6ba8e26f
AC
834 &((struct tui_win_element *) data_item_win->content[0])->which_element.data,
835 !allocated_here && refresh_values_only);
c906108c 836 }
6d012f14 837 TUI_DATA_WIN->detail.data_display_info.regs_column_count =
6ba8e26f 838 tui_calculate_regs_column_count (dpy_type);
c906108c 839#ifdef LATER
6d012f14 840 if (TUI_DATA_WIN->detail.data_display_info.data_content_count > 0)
c906108c
SS
841 {
842 /* delete all the windows? */
6d012f14 843 /* realloc content equal to data_content_count + regs_content_count */
6ba8e26f 844 /* append TUI_DATA_WIN->detail.data_display_info.data_content to content */
c906108c
SS
845 }
846#endif
6d012f14
AC
847 TUI_DATA_WIN->generic.content_size =
848 TUI_DATA_WIN->detail.data_display_info.regs_content_count +
849 TUI_DATA_WIN->detail.data_display_info.data_content_count;
c906108c
SS
850 ret = TUI_SUCCESS;
851 }
852
853 return ret;
6ba8e26f 854}
c906108c
SS
855
856
6ba8e26f
AC
857/* Function to display a register in a window. If hilite is TRUE,
858 than the value will be displayed in reverse video. */
c906108c 859static void
6ba8e26f
AC
860tui_display_register (int reg_num,
861 struct tui_gen_win_info * win_info, /* the data item window */
eca6576c 862 enum precision_type precision)
c906108c 863{
6ba8e26f 864 if (win_info->handle != (WINDOW *) NULL)
c906108c 865 {
c46cc7df
SC
866 int i;
867 char buf[40];
6ba8e26f
AC
868 int value_chars_wide, label_width;
869 struct tui_data_element * data_element_ptr = &((tui_win_content)
870 win_info->content)[0]->which_element.data;
c906108c
SS
871
872 if (IS_64BIT ||
6d012f14 873 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS)
c906108c 874 {
6ba8e26f
AC
875 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
876 label_width = DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
877 }
878 else
879 {
6d012f14 880 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
881 TUI_SFLOAT_REGS)
882 {
6ba8e26f
AC
883 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
884 label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
885 }
886 else
887 {
6ba8e26f
AC
888 value_chars_wide = SINGLE_VALUE_WIDTH;
889 label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
890 }
891 }
892
893 buf[0] = (char) 0;
6ba8e26f
AC
894 tui_register_format (buf,
895 value_chars_wide + label_width,
896 reg_num,
897 data_element_ptr,
c906108c 898 precision);
c46cc7df 899
6ba8e26f
AC
900 if (data_element_ptr->highlight)
901 wstandout (win_info->handle);
c906108c 902
6ba8e26f
AC
903 wmove (win_info->handle, 0, 0);
904 for (i = 1; i < win_info->width; i++)
905 waddch (win_info->handle, ' ');
906 wmove (win_info->handle, 0, 0);
907 waddstr (win_info->handle, buf);
c906108c 908
6ba8e26f
AC
909 if (data_element_ptr->highlight)
910 wstandend (win_info->handle);
911 tui_refresh_win (win_info);
c906108c 912 }
6ba8e26f 913}
c906108c
SS
914
915
916static void
6ba8e26f 917tui_v_show_registers_command_support (enum tui_register_display_type dpy_type)
c906108c 918{
c906108c 919
6d012f14 920 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
c906108c 921 { /* Data window already displayed, show the registers */
6ba8e26f
AC
922 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != dpy_type)
923 tui_show_registers (dpy_type);
c906108c
SS
924 }
925 else
6ba8e26f 926 (tui_layout_def ())->regs_display_type = dpy_type;
c906108c
SS
927
928 return;
6ba8e26f 929}
c906108c
SS
930
931
932static void
6ba8e26f 933tui_show_float_command (char *arg, int from_tty)
c906108c 934{
6d012f14
AC
935 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible ||
936 (TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_SFLOAT_REGS &&
937 TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_DFLOAT_REGS))
6ba8e26f
AC
938 tui_v_show_registers_command_support ((tui_layout_def ())->float_regs_display_type);
939}
c906108c
SS
940
941
942static void
6ba8e26f 943tui_show_general_command (char *arg, int from_tty)
c906108c 944{
6ba8e26f 945 tui_v_show_registers_command_support (TUI_GENERAL_REGS);
e8b915dc 946}
c906108c
SS
947
948
949static void
6ba8e26f 950tui_show_special_command (char *arg, int from_tty)
c906108c 951{
6ba8e26f 952 tui_v_show_registers_command_support (TUI_SPECIAL_REGS);
e8b915dc 953}
c906108c
SS
954
955
956static void
6ba8e26f 957_tui_toggle_float_regs_command (char *arg, int from_tty)
c906108c 958{
6d012f14 959 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
6ba8e26f 960 tui_toggle_float_regs ();
c906108c
SS
961 else
962 {
6ba8e26f 963 struct tui_layout_def * layout_def = tui_layout_def ();
c906108c 964
6ba8e26f
AC
965 if (layout_def->float_regs_display_type == TUI_SFLOAT_REGS)
966 layout_def->float_regs_display_type = TUI_DFLOAT_REGS;
c906108c 967 else
6ba8e26f 968 layout_def->float_regs_display_type = TUI_SFLOAT_REGS;
c906108c 969 }
6ba8e26f 970}
c906108c
SS
971
972
973static void
6ba8e26f 974tui_scroll_regs_forward_command (char *arg, int from_tty)
c906108c 975{
6d012f14 976 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 977}
c906108c
SS
978
979
980static void
6ba8e26f 981tui_scroll_regs_backward_command (char *arg, int from_tty)
c906108c 982{
6d012f14 983 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 984}
This page took 0.516711 seconds and 4 git commands to generate.