]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-regs.c
* NEWS (New native configurations): Mention OpenBSD/amd64.
[thirdparty/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
6a83354a 42#include "gdb_curses.h"
96ec9981 43
c906108c
SS
44/*****************************************
45** LOCAL DEFINITIONS **
46******************************************/
47#define DOUBLE_FLOAT_LABEL_WIDTH 6
48#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
49#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
50
51#define SINGLE_FLOAT_LABEL_WIDTH 6
52#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
53#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
54
c46cc7df 55#define SINGLE_LABEL_WIDTH 16
c906108c 56#define SINGLE_LABEL_FMT "%10.10s: "
c46cc7df 57#define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
c906108c
SS
58
59/* In the code HP gave Cygnus, this was actually a function call to a
60 PA-specific function, which was supposed to determine whether the
61 target was a 64-bit or 32-bit processor. However, the 64-bit
62 support wasn't complete, so we didn't merge that in, so we leave
63 this here as a stub. */
64#define IS_64BIT 0
65
66/*****************************************
67** STATIC DATA **
68******************************************/
69
70
71/*****************************************
72** STATIC LOCAL FUNCTIONS FORWARD DECLS **
73******************************************/
6ba8e26f 74static enum tui_status tui_set_regs_content
2a8854a7 75 (int, int, struct frame_info *, enum tui_register_display_type, int);
6ba8e26f
AC
76static const char *tui_register_name (int);
77static enum tui_status tui_get_register_raw_value (int, char *, struct frame_info *);
78static void tui_set_register_element
2a8854a7 79 (int, struct frame_info *, struct tui_data_element *, int);
6ba8e26f
AC
80static void tui_display_register (int, struct tui_gen_win_info *, enum precision_type);
81static void tui_register_format
2a8854a7 82 (char *, int, int, struct tui_data_element *, enum precision_type);
6ba8e26f
AC
83static enum tui_status tui_set_general_regs_content (int);
84static enum tui_status tui_set_special_regs_content (int);
85static enum tui_status tui_set_general_and_special_regs_content (int);
86static enum tui_status tui_set_float_regs_content (enum tui_register_display_type, int);
87static int tui_reg_value_has_changed
2a8854a7 88 (struct tui_data_element *, struct frame_info *, char *);
6ba8e26f
AC
89static void tui_show_float_command (char *, int);
90static void tui_show_general_command (char *, int);
91static void tui_show_special_command (char *, int);
92static void tui_v_show_registers_command_support (enum tui_register_display_type);
93static void _tui_toggle_float_regs_command (char *, int);
94static void tui_scroll_regs_forward_command (char *, int);
95static void tui_scroll_regs_backward_command (char *, int);
c906108c
SS
96
97
98
99/*****************************************
100** PUBLIC FUNCTIONS **
101******************************************/
102
55fb0713
AC
103/* Answer the number of the last line in the regs display. If there
104 are no registers (-1) is returned. */
c906108c 105int
55fb0713 106tui_last_regs_line_no (void)
c906108c 107{
d02c80cd 108 int num_lines = (-1);
c906108c 109
6d012f14 110 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 111 {
6ba8e26f 112 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
6d012f14
AC
113 TUI_DATA_WIN->detail.data_display_info.regs_column_count);
114 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
115 TUI_DATA_WIN->detail.data_display_info.regs_column_count)
6ba8e26f 116 num_lines++;
c906108c 117 }
6ba8e26f 118 return num_lines;
55fb0713 119}
c906108c
SS
120
121
6ba8e26f
AC
122/* Answer the line number that the register element at element_no is
123 on. If element_no is greater than the number of register elements
55fb0713 124 there are, -1 is returned. */
c906108c 125int
6ba8e26f 126tui_line_from_reg_element_no (int element_no)
c906108c 127{
6ba8e26f 128 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
c906108c
SS
129 {
130 int i, line = (-1);
131
132 i = 1;
133 while (line == (-1))
134 {
6ba8e26f 135 if (element_no <
6d012f14 136 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
c906108c
SS
137 line = i - 1;
138 else
139 i++;
140 }
141
142 return line;
143 }
144 else
145 return (-1);
55fb0713 146}
c906108c
SS
147
148
6ba8e26f 149/* Answer the index of the first element in line_no. If line_no is past
55fb0713 150 the register area (-1) is returned. */
c906108c 151int
6ba8e26f 152tui_first_reg_element_no_inline (int line_no)
c906108c 153{
6ba8e26f 154 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
6d012f14 155 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
6ba8e26f 156 return ((line_no + 1) *
6d012f14
AC
157 TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
158 TUI_DATA_WIN->detail.data_display_info.regs_column_count;
c906108c
SS
159 else
160 return (-1);
55fb0713 161}
c906108c
SS
162
163
6ba8e26f
AC
164/* Answer the index of the last element in line_no. If line_no is
165 past the register area (-1) is returned. */
c906108c 166int
6ba8e26f 167tui_last_reg_element_no_in_line (int line_no)
c906108c 168{
6ba8e26f 169 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <=
6d012f14 170 TUI_DATA_WIN->detail.data_display_info.regs_content_count)
6ba8e26f 171 return ((line_no + 1) *
6d012f14 172 TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1;
c906108c
SS
173 else
174 return (-1);
6ba8e26f 175}
c906108c
SS
176
177
55fb0713
AC
178/* Calculate the number of columns that should be used to display the
179 registers. */
c906108c 180int
6ba8e26f 181tui_calculate_regs_column_count (enum tui_register_display_type dpy_type)
c906108c 182{
6ba8e26f 183 int col_count, col_width;
c906108c 184
6ba8e26f
AC
185 if (IS_64BIT || dpy_type == TUI_DFLOAT_REGS)
186 col_width = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
187 else
188 {
6ba8e26f
AC
189 if (dpy_type == TUI_SFLOAT_REGS)
190 col_width = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
c906108c 191 else
6ba8e26f 192 col_width = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
c906108c 193 }
6ba8e26f 194 col_count = (TUI_DATA_WIN->generic.width - 2) / col_width;
c906108c 195
6ba8e26f
AC
196 return col_count;
197}
c906108c
SS
198
199
6ba8e26f 200/* Show the registers int the data window as indicated by dpy_type. If
55fb0713 201 there is any other registers being displayed, then they are
6ba8e26f 202 cleared. What registers are displayed is dependent upon dpy_type. */
c906108c 203void
6ba8e26f 204tui_show_registers (enum tui_register_display_type dpy_type)
c906108c 205{
22940a24 206 enum tui_status ret = TUI_FAILURE;
6ba8e26f 207 int refresh_values_only = FALSE;
c906108c
SS
208
209 /* Say that registers should be displayed, even if there is a problem */
6d012f14 210 TUI_DATA_WIN->detail.data_display_info.display_regs = TRUE;
c906108c
SS
211
212 if (target_has_registers)
213 {
6ba8e26f
AC
214 refresh_values_only =
215 (dpy_type == TUI_DATA_WIN->detail.data_display_info.regs_display_type);
216 switch (dpy_type)
c906108c
SS
217 {
218 case TUI_GENERAL_REGS:
6ba8e26f 219 ret = tui_set_general_regs_content (refresh_values_only);
c906108c
SS
220 break;
221 case TUI_SFLOAT_REGS:
222 case TUI_DFLOAT_REGS:
6ba8e26f 223 ret = tui_set_float_regs_content (dpy_type, refresh_values_only);
c906108c
SS
224 break;
225
226/* could ifdef out */
227
228 case TUI_SPECIAL_REGS:
6ba8e26f 229 ret = tui_set_special_regs_content (refresh_values_only);
c906108c
SS
230 break;
231 case TUI_GENERAL_AND_SPECIAL_REGS:
6ba8e26f 232 ret = tui_set_general_and_special_regs_content (refresh_values_only);
c906108c
SS
233 break;
234
235/* end of potential if def */
236
237 default:
238 break;
239 }
240 }
241 if (ret == TUI_FAILURE)
242 {
6d012f14 243 TUI_DATA_WIN->detail.data_display_info.regs_display_type = TUI_UNDEFINED_REGS;
edae1ccf 244 tui_erase_data_content (NO_REGS_STRING);
c906108c
SS
245 }
246 else
247 {
248 int i;
249
250 /* Clear all notation of changed values */
6d012f14 251 for (i = 0; (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); i++)
c906108c 252 {
6ba8e26f 253 struct tui_gen_win_info * data_item_win;
c906108c 254
6ba8e26f 255 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 256 regs_content[i]->which_element.data_window;
2a8854a7 257 (&((struct tui_win_element *)
6ba8e26f 258 data_item_win->content[0])->which_element.data)->highlight = FALSE;
c906108c 259 }
6ba8e26f 260 TUI_DATA_WIN->detail.data_display_info.regs_display_type = dpy_type;
edae1ccf 261 tui_display_all_data ();
c906108c 262 }
6ba8e26f 263 (tui_layout_def ())->regs_display_type = dpy_type;
c906108c
SS
264
265 return;
55fb0713 266}
c906108c
SS
267
268
55fb0713 269/* Function to display the registers in the content from
6ba8e26f 270 'start_element_no' until the end of the register content or the end
55fb0713
AC
271 of the display height. No checking for displaying past the end of
272 the registers is done here. */
c906108c 273void
6ba8e26f 274tui_display_registers_from (int start_element_no)
c906108c 275{
6d012f14
AC
276 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL &&
277 TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 278 {
d02c80cd 279 int i = start_element_no;
4cfcaf21 280 int j, value_chars_wide, item_win_width, cur_y;
c906108c
SS
281 enum precision_type precision;
282
4cfcaf21
JB
283 /* Do not rename the following variable into "label_width".
284 Unfortunately, term.h on AiX systems defines a macro with
285 the same name, which causes a build failure if we use the
286 same name for this variable. */
287 int tui_label_width;
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 295 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
4cfcaf21 296 tui_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 303 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
4cfcaf21 304 tui_label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
305 }
306 else
307 {
6ba8e26f 308 value_chars_wide = SINGLE_VALUE_WIDTH;
4cfcaf21 309 tui_label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
310 }
311 }
4cfcaf21 312 item_win_width = value_chars_wide + tui_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 {
d02c80cd 370 int element_no = start_element_no;
c906108c 371
6ba8e26f 372 if (start_element_no != 0 && start_line_no != 0)
c906108c 373 {
d02c80cd 374 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];
4cfcaf21 868 int value_chars_wide;
6ba8e26f
AC
869 struct tui_data_element * data_element_ptr = &((tui_win_content)
870 win_info->content)[0]->which_element.data;
c906108c 871
4cfcaf21
JB
872 /* Do not rename the following variable into "label_width".
873 Unfortunately, term.h on AiX systems defines a macro with
874 the same name, which causes a build failure if we use the
875 same name for this variable. */
876 int tui_label_width;
877
c906108c 878 if (IS_64BIT ||
6d012f14 879 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS)
c906108c 880 {
6ba8e26f 881 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
4cfcaf21 882 tui_label_width = DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
883 }
884 else
885 {
6d012f14 886 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
887 TUI_SFLOAT_REGS)
888 {
6ba8e26f 889 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
4cfcaf21 890 tui_label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
891 }
892 else
893 {
6ba8e26f 894 value_chars_wide = SINGLE_VALUE_WIDTH;
4cfcaf21 895 tui_label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
896 }
897 }
898
899 buf[0] = (char) 0;
6ba8e26f 900 tui_register_format (buf,
4cfcaf21 901 value_chars_wide + tui_label_width,
6ba8e26f
AC
902 reg_num,
903 data_element_ptr,
c906108c 904 precision);
c46cc7df 905
6ba8e26f
AC
906 if (data_element_ptr->highlight)
907 wstandout (win_info->handle);
c906108c 908
6ba8e26f
AC
909 wmove (win_info->handle, 0, 0);
910 for (i = 1; i < win_info->width; i++)
911 waddch (win_info->handle, ' ');
912 wmove (win_info->handle, 0, 0);
913 waddstr (win_info->handle, buf);
c906108c 914
6ba8e26f
AC
915 if (data_element_ptr->highlight)
916 wstandend (win_info->handle);
917 tui_refresh_win (win_info);
c906108c 918 }
6ba8e26f 919}
c906108c
SS
920
921
922static void
6ba8e26f 923tui_v_show_registers_command_support (enum tui_register_display_type dpy_type)
c906108c 924{
c906108c 925
6d012f14 926 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
c906108c 927 { /* Data window already displayed, show the registers */
6ba8e26f
AC
928 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != dpy_type)
929 tui_show_registers (dpy_type);
c906108c
SS
930 }
931 else
6ba8e26f 932 (tui_layout_def ())->regs_display_type = dpy_type;
c906108c
SS
933
934 return;
6ba8e26f 935}
c906108c
SS
936
937
938static void
6ba8e26f 939tui_show_float_command (char *arg, int from_tty)
c906108c 940{
6d012f14
AC
941 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible ||
942 (TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_SFLOAT_REGS &&
943 TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_DFLOAT_REGS))
6ba8e26f
AC
944 tui_v_show_registers_command_support ((tui_layout_def ())->float_regs_display_type);
945}
c906108c
SS
946
947
948static void
6ba8e26f 949tui_show_general_command (char *arg, int from_tty)
c906108c 950{
6ba8e26f 951 tui_v_show_registers_command_support (TUI_GENERAL_REGS);
e8b915dc 952}
c906108c
SS
953
954
955static void
6ba8e26f 956tui_show_special_command (char *arg, int from_tty)
c906108c 957{
6ba8e26f 958 tui_v_show_registers_command_support (TUI_SPECIAL_REGS);
e8b915dc 959}
c906108c
SS
960
961
962static void
6ba8e26f 963_tui_toggle_float_regs_command (char *arg, int from_tty)
c906108c 964{
6d012f14 965 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
6ba8e26f 966 tui_toggle_float_regs ();
c906108c
SS
967 else
968 {
6ba8e26f 969 struct tui_layout_def * layout_def = tui_layout_def ();
c906108c 970
6ba8e26f
AC
971 if (layout_def->float_regs_display_type == TUI_SFLOAT_REGS)
972 layout_def->float_regs_display_type = TUI_DFLOAT_REGS;
c906108c 973 else
6ba8e26f 974 layout_def->float_regs_display_type = TUI_SFLOAT_REGS;
c906108c 975 }
6ba8e26f 976}
c906108c
SS
977
978
979static void
6ba8e26f 980tui_scroll_regs_forward_command (char *arg, int from_tty)
c906108c 981{
6d012f14 982 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 983}
c906108c
SS
984
985
986static void
6ba8e26f 987tui_scroll_regs_backward_command (char *arg, int from_tty)
c906108c 988{
6d012f14 989 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 990}