]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-regs.c
*** empty log message ***
[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;
6ba8e26f 280 int j, value_chars_wide, item_win_width, cur_y, label_width;
c906108c
SS
281 enum precision_type precision;
282
6d012f14 283 precision = (TUI_DATA_WIN->detail.data_display_info.regs_display_type
c906108c
SS
284 == TUI_DFLOAT_REGS) ?
285 double_precision : unspecified_precision;
286 if (IS_64BIT ||
6d012f14 287 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS)
c906108c 288 {
6ba8e26f
AC
289 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
290 label_width = DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
291 }
292 else
293 {
6d012f14 294 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
295 TUI_SFLOAT_REGS)
296 {
6ba8e26f
AC
297 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
298 label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
299 }
300 else
301 {
6ba8e26f
AC
302 value_chars_wide = SINGLE_VALUE_WIDTH;
303 label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
304 }
305 }
6ba8e26f 306 item_win_width = value_chars_wide + label_width;
c906108c 307 /*
c5aa993b
JM
308 ** Now create each data "sub" window, and write the display into it.
309 */
6ba8e26f 310 cur_y = 1;
6d012f14 311 while (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count &&
6ba8e26f 312 cur_y <= TUI_DATA_WIN->generic.viewport_height)
c906108c
SS
313 {
314 for (j = 0;
6d012f14
AC
315 (j < TUI_DATA_WIN->detail.data_display_info.regs_column_count &&
316 i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); j++)
c906108c 317 {
6ba8e26f
AC
318 struct tui_gen_win_info * data_item_win;
319 struct tui_data_element * data_element_ptr;
c906108c 320
c5aa993b 321 /* create the window if necessary */
6ba8e26f 322 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 323 regs_content[i]->which_element.data_window;
6ba8e26f
AC
324 data_element_ptr = &((struct tui_win_element *)
325 data_item_win->content[0])->which_element.data;
326 if (data_item_win->handle == (WINDOW *) NULL)
c906108c 327 {
6ba8e26f
AC
328 data_item_win->height = 1;
329 data_item_win->width = (precision == double_precision) ?
330 item_win_width + 2 : item_win_width + 1;
331 data_item_win->origin.x = (item_win_width * j) + 1;
332 data_item_win->origin.y = cur_y;
333 tui_make_window (data_item_win, DONT_BOX_WINDOW);
334 scrollok (data_item_win->handle, FALSE);
c906108c 335 }
6ba8e26f 336 touchwin (data_item_win->handle);
fea14702 337
c906108c 338 /*
c5aa993b
JM
339 ** Get the printable representation of the register
340 ** and display it
341 */
6ba8e26f
AC
342 tui_display_register (
343 data_element_ptr->item_no, data_item_win, precision);
c906108c
SS
344 i++; /* next register */
345 }
6ba8e26f 346 cur_y++; /* next row; */
c906108c
SS
347 }
348 }
349
350 return;
55fb0713 351}
c906108c
SS
352
353
6ba8e26f
AC
354/* Function to display the registers in the content from
355 'start_element_no' on 'start_line_no' until the end of the register
356 content or the end of the display height. This function checks
357 that we won't display off the end of the register display. */
c906108c 358void
6ba8e26f 359tui_display_reg_element_at_line (int start_element_no, int start_line_no)
c906108c 360{
6d012f14
AC
361 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL &&
362 TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 363 {
d02c80cd 364 int element_no = start_element_no;
c906108c 365
6ba8e26f 366 if (start_element_no != 0 && start_line_no != 0)
c906108c 367 {
d02c80cd 368 int last_line_no, first_line_on_last_page;
c906108c 369
6ba8e26f
AC
370 last_line_no = tui_last_regs_line_no ();
371 first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2);
372 if (first_line_on_last_page < 0)
373 first_line_on_last_page = 0;
c906108c 374 /*
c5aa993b 375 ** If there is no other data displayed except registers,
6ba8e26f 376 ** and the element_no causes us to scroll past the end of the
c5aa993b
JM
377 ** registers, adjust what element to really start the display at.
378 */
6d012f14 379 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0 &&
6ba8e26f
AC
380 start_line_no > first_line_on_last_page)
381 element_no = tui_first_reg_element_no_inline (first_line_on_last_page);
c906108c 382 }
6ba8e26f 383 tui_display_registers_from (element_no);
c906108c 384 }
6ba8e26f 385}
c906108c
SS
386
387
388
6ba8e26f 389/* Function to display the registers starting at line line_no in the
55fb0713
AC
390 data window. Answers the line number that the display actually
391 started from. If nothing is displayed (-1) is returned. */
c906108c 392int
6ba8e26f 393tui_display_registers_from_line (int line_no, int force_display)
c906108c 394{
6d012f14 395 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
c906108c 396 {
6ba8e26f 397 int line, element_no;
c906108c 398
6ba8e26f 399 if (line_no < 0)
c906108c 400 line = 0;
6ba8e26f 401 else if (force_display)
c906108c 402 { /*
6ba8e26f 403 ** If we must display regs (force_display is true), then make
c5aa993b
JM
404 ** sure that we don't display off the end of the registers.
405 */
6ba8e26f 406 if (line_no >= tui_last_regs_line_no ())
c906108c 407 {
55fb0713 408 if ((line = tui_line_from_reg_element_no (
6d012f14 409 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
c906108c
SS
410 line = 0;
411 }
412 else
6ba8e26f 413 line = line_no;
c906108c
SS
414 }
415 else
6ba8e26f 416 line = line_no;
c906108c 417
6ba8e26f
AC
418 element_no = tui_first_reg_element_no_inline (line);
419 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
420 tui_display_reg_element_at_line (element_no, line);
c906108c
SS
421 else
422 line = (-1);
423
424 return line;
425 }
426
427 return (-1); /* nothing was displayed */
55fb0713 428}
c906108c
SS
429
430
55fb0713
AC
431/* This function check all displayed registers for changes in values,
432 given a particular frame. If the values have changed, they are
433 updated with the new value and highlighted. */
c906108c 434void
55fb0713 435tui_check_register_values (struct frame_info *frame)
c906108c 436{
6d012f14 437 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
c906108c 438 {
6d012f14
AC
439 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count <= 0 &&
440 TUI_DATA_WIN->detail.data_display_info.display_regs)
441 tui_show_registers ((tui_layout_def ())->regs_display_type);
c906108c
SS
442 else
443 {
444 int i, j;
6ba8e26f 445 char raw_buf[MAX_REGISTER_SIZE];
c906108c
SS
446
447 for (i = 0;
6d012f14 448 (i < TUI_DATA_WIN->detail.data_display_info.regs_content_count); i++)
c906108c 449 {
6ba8e26f
AC
450 struct tui_data_element * data_element_ptr;
451 struct tui_gen_win_info * data_item_win_ptr;
452 int was_hilighted;
c906108c 453
6ba8e26f 454 data_item_win_ptr = &TUI_DATA_WIN->detail.data_display_info.
6d012f14 455 regs_content[i]->which_element.data_window;
6ba8e26f
AC
456 data_element_ptr = &((struct tui_win_element *)
457 data_item_win_ptr->content[0])->which_element.data;
458 was_hilighted = data_element_ptr->highlight;
459 data_element_ptr->highlight =
460 tui_reg_value_has_changed (data_element_ptr, frame, &raw_buf[0]);
461 if (data_element_ptr->highlight)
c906108c 462 {
c46cc7df
SC
463 int size;
464
6ba8e26f 465 size = DEPRECATED_REGISTER_RAW_SIZE (data_element_ptr->item_no);
c46cc7df 466 for (j = 0; j < size; j++)
6ba8e26f
AC
467 ((char *) data_element_ptr->value)[j] = raw_buf[j];
468 tui_display_register (
469 data_element_ptr->item_no,
470 data_item_win_ptr,
6d012f14 471 ((TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
472 TUI_DFLOAT_REGS) ?
473 double_precision : unspecified_precision));
474 }
6ba8e26f 475 else if (was_hilighted)
c906108c 476 {
6ba8e26f
AC
477 data_element_ptr->highlight = FALSE;
478 tui_display_register (
479 data_element_ptr->item_no,
480 data_item_win_ptr,
6d012f14 481 ((TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
482 TUI_DFLOAT_REGS) ?
483 double_precision : unspecified_precision));
484 }
485 }
486 }
487 }
488 return;
55fb0713 489}
c906108c
SS
490
491
492/*
6ba8e26f 493 ** tui_toggle_float_regs().
c5aa993b 494 */
c906108c 495void
6ba8e26f 496tui_toggle_float_regs (void)
c906108c 497{
6ba8e26f 498 struct tui_layout_def * layout_def = tui_layout_def ();
c906108c 499
6ba8e26f
AC
500 if (layout_def->float_regs_display_type == TUI_SFLOAT_REGS)
501 layout_def->float_regs_display_type = TUI_DFLOAT_REGS;
c906108c 502 else
6ba8e26f 503 layout_def->float_regs_display_type = TUI_SFLOAT_REGS;
c906108c 504
6d012f14
AC
505 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible &&
506 (TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_SFLOAT_REGS ||
507 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS))
6ba8e26f 508 tui_show_registers (layout_def->float_regs_display_type);
c906108c
SS
509
510 return;
6ba8e26f 511} /* tui_toggle_float_regs */
c906108c
SS
512
513
514void
6ba8e26f 515_initialize_tui_regs (void)
c906108c 516{
41783295 517 if (xdb_commands)
c906108c 518 {
6ba8e26f 519 add_com ("fr", class_tui, tui_show_float_command,
c906108c 520 "Display only floating point registers\n");
6ba8e26f 521 add_com ("gr", class_tui, tui_show_general_command,
c906108c 522 "Display only general registers\n");
6ba8e26f 523 add_com ("sr", class_tui, tui_show_special_command,
c906108c 524 "Display only special registers\n");
6ba8e26f 525 add_com ("+r", class_tui, tui_scroll_regs_forward_command,
c906108c 526 "Scroll the registers window forward\n");
6ba8e26f 527 add_com ("-r", class_tui, tui_scroll_regs_backward_command,
c906108c 528 "Scroll the register window backward\n");
6ba8e26f 529 add_com ("tf", class_tui, _tui_toggle_float_regs_command,
c906108c
SS
530 "Toggle between single and double precision floating point registers.\n");
531 add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
532 class_tui,
6ba8e26f 533 _tui_toggle_float_regs_command,
c906108c
SS
534 "Toggle between single and double precision floating point \
535registers.\n",
536 &togglelist);
537 }
41783295 538}
c906108c
SS
539
540
541/*****************************************
542** STATIC LOCAL FUNCTIONS **
543******************************************/
544
545
546/*
6ba8e26f 547 ** tui_register_name().
c5aa993b
JM
548 ** Return the register name.
549 */
bc77de56 550static const char *
6ba8e26f 551tui_register_name (int reg_num)
c906108c 552{
6ba8e26f 553 return REGISTER_NAME (reg_num);
c46cc7df
SC
554}
555extern int pagination_enabled;
c906108c 556
c46cc7df
SC
557static void
558tui_restore_gdbout (void *ui)
559{
560 ui_file_delete (gdb_stdout);
561 gdb_stdout = (struct ui_file*) ui;
562 pagination_enabled = 1;
563}
c906108c
SS
564
565/*
6ba8e26f 566 ** tui_register_format
c5aa993b
JM
567 ** Function to format the register name and value into a buffer,
568 ** suitable for printing or display
569 */
c906108c 570static void
6ba8e26f
AC
571tui_register_format (char *buf, int buf_len, int reg_num,
572 struct tui_data_element * data_element,
eca6576c 573 enum precision_type precision)
c906108c 574{
d9fcf2fb 575 struct ui_file *stream;
c46cc7df 576 struct ui_file *old_stdout;
bc77de56 577 const char *name;
c46cc7df
SC
578 struct cleanup *cleanups;
579 char *p;
fea14702 580 int pos;
c906108c 581
6ba8e26f 582 name = REGISTER_NAME (reg_num);
c46cc7df
SC
583 if (name == 0)
584 {
585 strcpy (buf, "");
586 return;
587 }
588
589 pagination_enabled = 0;
590 old_stdout = gdb_stdout;
6ba8e26f 591 stream = tui_sfileopen (buf_len);
c46cc7df
SC
592 gdb_stdout = stream;
593 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
6e7f8b9c 594 gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame,
6ba8e26f 595 reg_num, 1);
c906108c 596
c46cc7df 597 /* Save formatted output in the buffer. */
fea14702
SC
598 p = tui_file_get_strbuf (stream);
599 pos = 0;
6ba8e26f 600 while (*p && *p == *name++ && buf_len)
fea14702
SC
601 {
602 *buf++ = *p++;
6ba8e26f 603 buf_len--;
fea14702
SC
604 pos++;
605 }
606 while (*p == ' ')
607 p++;
6ba8e26f 608 while (pos < 8 && buf_len)
fea14702
SC
609 {
610 *buf++ = ' ';
6ba8e26f 611 buf_len--;
fea14702
SC
612 pos++;
613 }
6ba8e26f 614 strncpy (buf, p, buf_len);
c46cc7df
SC
615
616 /* Remove the possible \n. */
617 p = strchr (buf, '\n');
618 if (p)
619 *p = 0;
620
621 do_cleanups (cleanups);
622}
c906108c
SS
623
624
625#define NUM_GENERAL_REGS 32
6ba8e26f
AC
626/* Set the content of the data window to consist of the general
627 registers. */
22940a24 628static enum tui_status
6ba8e26f 629tui_set_general_regs_content (int refresh_values_only)
c906108c 630{
6ba8e26f 631 return (tui_set_regs_content (0,
c906108c 632 NUM_GENERAL_REGS - 1,
6e7f8b9c 633 deprecated_selected_frame,
c906108c 634 TUI_GENERAL_REGS,
6ba8e26f 635 refresh_values_only));
c906108c 636
6ba8e26f 637}
c906108c
SS
638
639
c46cc7df
SC
640#ifndef PCOQ_HEAD_REGNUM
641#define START_SPECIAL_REGS 0
642#else
c906108c 643#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
c46cc7df
SC
644#endif
645
6ba8e26f
AC
646/* Set the content of the data window to consist of the special
647 registers. */
22940a24 648static enum tui_status
6ba8e26f 649tui_set_special_regs_content (int refresh_values_only)
c906108c 650{
22940a24 651 enum tui_status ret = TUI_FAILURE;
6ba8e26f 652 int end_reg_num;
c906108c 653
6ba8e26f
AC
654 end_reg_num = FP0_REGNUM - 1;
655 ret = tui_set_regs_content (START_SPECIAL_REGS,
656 end_reg_num,
6e7f8b9c 657 deprecated_selected_frame,
c906108c 658 TUI_SPECIAL_REGS,
6ba8e26f 659 refresh_values_only);
c906108c
SS
660
661 return ret;
6ba8e26f 662}
c906108c
SS
663
664
6ba8e26f
AC
665/* Set the content of the data window to consist of the special
666 registers. */
22940a24 667static enum tui_status
6ba8e26f 668tui_set_general_and_special_regs_content (int refresh_values_only)
c906108c 669{
22940a24 670 enum tui_status ret = TUI_FAILURE;
6ba8e26f 671 int end_reg_num = (-1);
c906108c 672
6ba8e26f
AC
673 end_reg_num = FP0_REGNUM - 1;
674 ret = tui_set_regs_content (
675 0, end_reg_num, deprecated_selected_frame, TUI_SPECIAL_REGS, refresh_values_only);
c906108c
SS
676
677 return ret;
6ba8e26f 678}
c906108c 679
6ba8e26f
AC
680/* Set the content of the data window to consist of the float
681 registers. */
22940a24 682static enum tui_status
6ba8e26f
AC
683tui_set_float_regs_content (enum tui_register_display_type dpy_type,
684 int refresh_values_only)
c906108c 685{
22940a24 686 enum tui_status ret = TUI_FAILURE;
6ba8e26f 687 int start_reg_num;
c906108c 688
6ba8e26f
AC
689 start_reg_num = FP0_REGNUM;
690 ret = tui_set_regs_content (start_reg_num,
a728f042 691 NUM_REGS - 1,
6e7f8b9c 692 deprecated_selected_frame,
6ba8e26f
AC
693 dpy_type,
694 refresh_values_only);
c906108c
SS
695
696 return ret;
6ba8e26f 697}
c906108c
SS
698
699
6ba8e26f
AC
700/* Answer TRUE if the register's value has changed, FALSE otherwise.
701 If TRUE, new_value is filled in with the new value. */
c906108c 702static int
6ba8e26f
AC
703tui_reg_value_has_changed (struct tui_data_element * data_element,
704 struct frame_info *frame, char *new_value)
c906108c 705{
6ba8e26f 706 int has_changed = FALSE;
c906108c 707
6ba8e26f
AC
708 if (data_element->item_no != UNDEFINED_ITEM &&
709 tui_register_name (data_element->item_no) != (char *) NULL)
c906108c 710 {
6ba8e26f 711 char raw_buf[MAX_REGISTER_SIZE];
c906108c
SS
712 int i;
713
6ba8e26f 714 if (tui_get_register_raw_value (data_element->item_no, raw_buf, frame) == TUI_SUCCESS)
c906108c 715 {
6ba8e26f 716 int size = DEPRECATED_REGISTER_RAW_SIZE (data_element->item_no);
c46cc7df 717
6ba8e26f
AC
718 for (i = 0; (i < size && !has_changed); i++)
719 has_changed = (((char *) data_element->value)[i] != raw_buf[i]);
720 if (has_changed && new_value != (char *) NULL)
c906108c 721 {
c46cc7df 722 for (i = 0; i < size; i++)
6ba8e26f 723 new_value[i] = raw_buf[i];
c906108c
SS
724 }
725 }
726 }
6ba8e26f
AC
727 return has_changed;
728}
c906108c
SS
729
730
731
6ba8e26f 732/* Get the register raw value. The raw value is returned in reg_value. */
22940a24 733static enum tui_status
6ba8e26f 734tui_get_register_raw_value (int reg_num, char *reg_value, struct frame_info *frame)
c906108c 735{
22940a24 736 enum tui_status ret = TUI_FAILURE;
c906108c
SS
737
738 if (target_has_registers)
739 {
6ba8e26f 740 get_frame_register (frame, reg_num, reg_value);
ac2adee5
AC
741 /* NOTE: cagney/2003-03-13: This is bogus. It is refering to
742 the register cache and not the frame which could have pulled
743 the register value off the stack. */
6ba8e26f 744 if (register_cached (reg_num) >= 0)
c46cc7df 745 ret = TUI_SUCCESS;
c906108c 746 }
c906108c 747 return ret;
6ba8e26f 748}
c906108c
SS
749
750
751
6ba8e26f
AC
752/* Function to initialize a data element with the input and the
753 register value. */
c906108c 754static void
6ba8e26f
AC
755tui_set_register_element (int reg_num, struct frame_info *frame,
756 struct tui_data_element * data_element,
757 int refresh_value_only)
c906108c 758{
6ba8e26f 759 if (data_element != (struct tui_data_element *) NULL)
c906108c 760 {
6ba8e26f 761 if (!refresh_value_only)
c906108c 762 {
6ba8e26f
AC
763 data_element->item_no = reg_num;
764 data_element->name = tui_register_name (reg_num);
765 data_element->highlight = FALSE;
c906108c 766 }
6ba8e26f
AC
767 if (data_element->value == NULL)
768 data_element->value = xmalloc (MAX_REGISTER_SIZE);
769 if (data_element->value != NULL)
770 tui_get_register_raw_value (reg_num, data_element->value, frame);
c906108c 771 }
6ba8e26f 772}
c906108c
SS
773
774
6ba8e26f
AC
775/* Set the content of the data window to consist of the registers
776 numbered from start_reg_num to end_reg_num. Note that if
777 refresh_values_only is TRUE, start_reg_num and end_reg_num are
778 ignored. */
22940a24 779static enum tui_status
6ba8e26f 780tui_set_regs_content (int start_reg_num, int end_reg_num,
eca6576c 781 struct frame_info *frame,
6ba8e26f
AC
782 enum tui_register_display_type dpy_type,
783 int refresh_values_only)
c906108c 784{
22940a24 785 enum tui_status ret = TUI_FAILURE;
6ba8e26f
AC
786 int num_regs = end_reg_num - start_reg_num + 1;
787 int allocated_here = FALSE;
c906108c 788
6d012f14 789 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0 &&
6ba8e26f 790 !refresh_values_only)
c906108c 791 {
6d012f14
AC
792 tui_free_data_content (TUI_DATA_WIN->detail.data_display_info.regs_content,
793 TUI_DATA_WIN->detail.data_display_info.regs_content_count);
794 TUI_DATA_WIN->detail.data_display_info.regs_content_count = 0;
c906108c 795 }
6d012f14 796 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count <= 0)
c906108c 797 {
6d012f14 798 TUI_DATA_WIN->detail.data_display_info.regs_content =
6ba8e26f
AC
799 tui_alloc_content (num_regs, DATA_WIN);
800 allocated_here = TRUE;
c906108c
SS
801 }
802
6d012f14 803 if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL)
c906108c
SS
804 {
805 int i;
806
6ba8e26f 807 if (!refresh_values_only || allocated_here)
c906108c 808 {
6d012f14
AC
809 TUI_DATA_WIN->generic.content = NULL;
810 TUI_DATA_WIN->generic.content_size = 0;
6ba8e26f 811 tui_add_content_elements (&TUI_DATA_WIN->generic, num_regs);
6d012f14
AC
812 TUI_DATA_WIN->detail.data_display_info.regs_content =
813 (tui_win_content) TUI_DATA_WIN->generic.content;
6ba8e26f 814 TUI_DATA_WIN->detail.data_display_info.regs_content_count = num_regs;
c906108c
SS
815 }
816 /*
c5aa993b
JM
817 ** Now set the register names and values
818 */
6ba8e26f 819 for (i = start_reg_num; (i <= end_reg_num); i++)
c906108c 820 {
6ba8e26f 821 struct tui_gen_win_info * data_item_win;
c906108c 822
6ba8e26f
AC
823 data_item_win = &TUI_DATA_WIN->detail.data_display_info.
824 regs_content[i - start_reg_num]->which_element.data_window;
825 tui_set_register_element (
c906108c
SS
826 i,
827 frame,
6ba8e26f
AC
828 &((struct tui_win_element *) data_item_win->content[0])->which_element.data,
829 !allocated_here && refresh_values_only);
c906108c 830 }
6d012f14 831 TUI_DATA_WIN->detail.data_display_info.regs_column_count =
6ba8e26f 832 tui_calculate_regs_column_count (dpy_type);
c906108c 833#ifdef LATER
6d012f14 834 if (TUI_DATA_WIN->detail.data_display_info.data_content_count > 0)
c906108c
SS
835 {
836 /* delete all the windows? */
6d012f14 837 /* realloc content equal to data_content_count + regs_content_count */
6ba8e26f 838 /* append TUI_DATA_WIN->detail.data_display_info.data_content to content */
c906108c
SS
839 }
840#endif
6d012f14
AC
841 TUI_DATA_WIN->generic.content_size =
842 TUI_DATA_WIN->detail.data_display_info.regs_content_count +
843 TUI_DATA_WIN->detail.data_display_info.data_content_count;
c906108c
SS
844 ret = TUI_SUCCESS;
845 }
846
847 return ret;
6ba8e26f 848}
c906108c
SS
849
850
6ba8e26f
AC
851/* Function to display a register in a window. If hilite is TRUE,
852 than the value will be displayed in reverse video. */
c906108c 853static void
6ba8e26f
AC
854tui_display_register (int reg_num,
855 struct tui_gen_win_info * win_info, /* the data item window */
eca6576c 856 enum precision_type precision)
c906108c 857{
6ba8e26f 858 if (win_info->handle != (WINDOW *) NULL)
c906108c 859 {
c46cc7df
SC
860 int i;
861 char buf[40];
6ba8e26f
AC
862 int value_chars_wide, label_width;
863 struct tui_data_element * data_element_ptr = &((tui_win_content)
864 win_info->content)[0]->which_element.data;
c906108c
SS
865
866 if (IS_64BIT ||
6d012f14 867 TUI_DATA_WIN->detail.data_display_info.regs_display_type == TUI_DFLOAT_REGS)
c906108c 868 {
6ba8e26f
AC
869 value_chars_wide = DOUBLE_FLOAT_VALUE_WIDTH;
870 label_width = DOUBLE_FLOAT_LABEL_WIDTH;
c906108c
SS
871 }
872 else
873 {
6d012f14 874 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type ==
c906108c
SS
875 TUI_SFLOAT_REGS)
876 {
6ba8e26f
AC
877 value_chars_wide = SINGLE_FLOAT_VALUE_WIDTH;
878 label_width = SINGLE_FLOAT_LABEL_WIDTH;
c906108c
SS
879 }
880 else
881 {
6ba8e26f
AC
882 value_chars_wide = SINGLE_VALUE_WIDTH;
883 label_width = SINGLE_LABEL_WIDTH;
c906108c
SS
884 }
885 }
886
887 buf[0] = (char) 0;
6ba8e26f
AC
888 tui_register_format (buf,
889 value_chars_wide + label_width,
890 reg_num,
891 data_element_ptr,
c906108c 892 precision);
c46cc7df 893
6ba8e26f
AC
894 if (data_element_ptr->highlight)
895 wstandout (win_info->handle);
c906108c 896
6ba8e26f
AC
897 wmove (win_info->handle, 0, 0);
898 for (i = 1; i < win_info->width; i++)
899 waddch (win_info->handle, ' ');
900 wmove (win_info->handle, 0, 0);
901 waddstr (win_info->handle, buf);
c906108c 902
6ba8e26f
AC
903 if (data_element_ptr->highlight)
904 wstandend (win_info->handle);
905 tui_refresh_win (win_info);
c906108c 906 }
6ba8e26f 907}
c906108c
SS
908
909
910static void
6ba8e26f 911tui_v_show_registers_command_support (enum tui_register_display_type dpy_type)
c906108c 912{
c906108c 913
6d012f14 914 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
c906108c 915 { /* Data window already displayed, show the registers */
6ba8e26f
AC
916 if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != dpy_type)
917 tui_show_registers (dpy_type);
c906108c
SS
918 }
919 else
6ba8e26f 920 (tui_layout_def ())->regs_display_type = dpy_type;
c906108c
SS
921
922 return;
6ba8e26f 923}
c906108c
SS
924
925
926static void
6ba8e26f 927tui_show_float_command (char *arg, int from_tty)
c906108c 928{
6d012f14
AC
929 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible ||
930 (TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_SFLOAT_REGS &&
931 TUI_DATA_WIN->detail.data_display_info.regs_display_type != TUI_DFLOAT_REGS))
6ba8e26f
AC
932 tui_v_show_registers_command_support ((tui_layout_def ())->float_regs_display_type);
933}
c906108c
SS
934
935
936static void
6ba8e26f 937tui_show_general_command (char *arg, int from_tty)
c906108c 938{
6ba8e26f 939 tui_v_show_registers_command_support (TUI_GENERAL_REGS);
e8b915dc 940}
c906108c
SS
941
942
943static void
6ba8e26f 944tui_show_special_command (char *arg, int from_tty)
c906108c 945{
6ba8e26f 946 tui_v_show_registers_command_support (TUI_SPECIAL_REGS);
e8b915dc 947}
c906108c
SS
948
949
950static void
6ba8e26f 951_tui_toggle_float_regs_command (char *arg, int from_tty)
c906108c 952{
6d012f14 953 if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible)
6ba8e26f 954 tui_toggle_float_regs ();
c906108c
SS
955 else
956 {
6ba8e26f 957 struct tui_layout_def * layout_def = tui_layout_def ();
c906108c 958
6ba8e26f
AC
959 if (layout_def->float_regs_display_type == TUI_SFLOAT_REGS)
960 layout_def->float_regs_display_type = TUI_DFLOAT_REGS;
c906108c 961 else
6ba8e26f 962 layout_def->float_regs_display_type = TUI_SFLOAT_REGS;
c906108c 963 }
6ba8e26f 964}
c906108c
SS
965
966
967static void
6ba8e26f 968tui_scroll_regs_forward_command (char *arg, int from_tty)
c906108c 969{
6d012f14 970 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 971}
c906108c
SS
972
973
974static void
6ba8e26f 975tui_scroll_regs_backward_command (char *arg, int from_tty)
c906108c 976{
6d012f14 977 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
e8b915dc 978}