* elf64-alpha.c (INSN_UNOP): Encode with RB as $sp.
[deliverable/binutils-gdb.git] / gdb / tui / tuiRegs.c
1 /* TUI display registers in window.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include "defs.h"
23 #include "tui.h"
24 #include "tuiData.h"
25 #include "symtab.h"
26 #include "gdbtypes.h"
27 #include "gdbcmd.h"
28 #include "frame.h"
29 #include "inferior.h"
30 #include "target.h"
31 #include "tuiLayout.h"
32 #include "tuiWin.h"
33 #include "tuiDataWin.h"
34 #include "tuiGeneralWin.h"
35 #include "tui-file.h"
36
37 /*****************************************
38 ** LOCAL DEFINITIONS **
39 ******************************************/
40 #define DOUBLE_FLOAT_LABEL_WIDTH 6
41 #define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
42 #define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
43
44 #define SINGLE_FLOAT_LABEL_WIDTH 6
45 #define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
46 #define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
47
48 #define SINGLE_LABEL_WIDTH 16
49 #define SINGLE_LABEL_FMT "%10.10s: "
50 #define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
51
52 /* In the code HP gave Cygnus, this was actually a function call to a
53 PA-specific function, which was supposed to determine whether the
54 target was a 64-bit or 32-bit processor. However, the 64-bit
55 support wasn't complete, so we didn't merge that in, so we leave
56 this here as a stub. */
57 #define IS_64BIT 0
58
59 /*****************************************
60 ** STATIC DATA **
61 ******************************************/
62
63
64 /*****************************************
65 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
66 ******************************************/
67 static TuiStatus _tuiSetRegsContent
68 (int, int, struct frame_info *, TuiRegisterDisplayType, int);
69 static char *_tuiRegisterName (int);
70 static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
71 static void _tuiSetRegisterElement
72 (int, struct frame_info *, TuiDataElementPtr, int);
73 static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
74 static void _tuiRegisterFormat
75 (char *, int, int, TuiDataElementPtr, enum precision_type);
76 static TuiStatus _tuiSetGeneralRegsContent (int);
77 static TuiStatus _tuiSetSpecialRegsContent (int);
78 static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
79 static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
80 static int _tuiRegValueHasChanged
81 (TuiDataElementPtr, struct frame_info *, char *);
82 static void _tuiShowFloat_command (char *, int);
83 static void _tuiShowGeneral_command (char *, int);
84 static void _tuiShowSpecial_command (char *, int);
85 static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType);
86 static void _tuiToggleFloatRegs_command (char *, int);
87 static void _tuiScrollRegsForward_command (char *, int);
88 static void _tuiScrollRegsBackward_command (char *, int);
89
90
91
92 /*****************************************
93 ** PUBLIC FUNCTIONS **
94 ******************************************/
95
96 /*
97 ** tuiLastRegsLineNo()
98 ** Answer the number of the last line in the regs display.
99 ** If there are no registers (-1) is returned.
100 */
101 int
102 tuiLastRegsLineNo (void)
103 {
104 register int numLines = (-1);
105
106 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
107 {
108 numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
109 dataWin->detail.dataDisplayInfo.regsColumnCount);
110 if (dataWin->detail.dataDisplayInfo.regsContentCount %
111 dataWin->detail.dataDisplayInfo.regsColumnCount)
112 numLines++;
113 }
114 return numLines;
115 } /* tuiLastRegsLineNo */
116
117
118 /*
119 ** tuiLineFromRegElementNo()
120 ** Answer the line number that the register element at elementNo is
121 ** on. If elementNo is greater than the number of register elements
122 ** there are, -1 is returned.
123 */
124 int
125 tuiLineFromRegElementNo (int elementNo)
126 {
127 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
128 {
129 int i, line = (-1);
130
131 i = 1;
132 while (line == (-1))
133 {
134 if (elementNo <
135 (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
136 line = i - 1;
137 else
138 i++;
139 }
140
141 return line;
142 }
143 else
144 return (-1);
145 } /* tuiLineFromRegElementNo */
146
147
148 /*
149 ** tuiFirstRegElementNoInLine()
150 ** Answer the index of the first element in lineNo. If lineNo is
151 ** past the register area (-1) is returned.
152 */
153 int
154 tuiFirstRegElementNoInLine (int lineNo)
155 {
156 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
157 <= dataWin->detail.dataDisplayInfo.regsContentCount)
158 return ((lineNo + 1) *
159 dataWin->detail.dataDisplayInfo.regsColumnCount) -
160 dataWin->detail.dataDisplayInfo.regsColumnCount;
161 else
162 return (-1);
163 } /* tuiFirstRegElementNoInLine */
164
165
166 /*
167 ** tuiLastRegElementNoInLine()
168 ** Answer the index of the last element in lineNo. If lineNo is past
169 ** the register area (-1) is returned.
170 */
171 int
172 tuiLastRegElementNoInLine (int lineNo)
173 {
174 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
175 dataWin->detail.dataDisplayInfo.regsContentCount)
176 return ((lineNo + 1) *
177 dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
178 else
179 return (-1);
180 } /* tuiLastRegElementNoInLine */
181
182
183 /*
184 ** tuiCalculateRegsColumnCount
185 ** Calculate the number of columns that should be used to display
186 ** the registers.
187 */
188 int
189 tuiCalculateRegsColumnCount (TuiRegisterDisplayType dpyType)
190 {
191 int colCount, colWidth;
192
193 if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
194 colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
195 else
196 {
197 if (dpyType == TUI_SFLOAT_REGS)
198 colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
199 else
200 colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
201 }
202 colCount = (dataWin->generic.width - 2) / colWidth;
203
204 return colCount;
205 } /* tuiCalulateRegsColumnCount */
206
207
208 /*
209 ** tuiShowRegisters().
210 ** Show the registers int the data window as indicated by dpyType.
211 ** If there is any other registers being displayed, then they are
212 ** cleared. What registers are displayed is dependent upon dpyType.
213 */
214 void
215 tuiShowRegisters (TuiRegisterDisplayType dpyType)
216 {
217 TuiStatus ret = TUI_FAILURE;
218 int refreshValuesOnly = FALSE;
219
220 /* Say that registers should be displayed, even if there is a problem */
221 dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
222
223 if (target_has_registers)
224 {
225 refreshValuesOnly =
226 (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
227 switch (dpyType)
228 {
229 case TUI_GENERAL_REGS:
230 ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
231 break;
232 case TUI_SFLOAT_REGS:
233 case TUI_DFLOAT_REGS:
234 ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
235 break;
236
237 /* could ifdef out */
238
239 case TUI_SPECIAL_REGS:
240 ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
241 break;
242 case TUI_GENERAL_AND_SPECIAL_REGS:
243 ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
244 break;
245
246 /* end of potential if def */
247
248 default:
249 break;
250 }
251 }
252 if (ret == TUI_FAILURE)
253 {
254 dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
255 tuiEraseDataContent (NO_REGS_STRING);
256 }
257 else
258 {
259 int i;
260
261 /* Clear all notation of changed values */
262 for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
263 {
264 TuiGenWinInfoPtr dataItemWin;
265
266 dataItemWin = &dataWin->detail.dataDisplayInfo.
267 regsContent[i]->whichElement.dataWindow;
268 (&((TuiWinElementPtr)
269 dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
270 }
271 dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
272 tuiDisplayAllData ();
273 }
274 (tuiLayoutDef ())->regsDisplayType = dpyType;
275
276 return;
277 } /* tuiShowRegisters */
278
279
280 /*
281 ** tuiDisplayRegistersFrom().
282 ** Function to display the registers in the content from
283 ** 'startElementNo' until the end of the register content or the
284 ** end of the display height. No checking for displaying past
285 ** the end of the registers is done here.
286 */
287 void
288 tuiDisplayRegistersFrom (int startElementNo)
289 {
290 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
291 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
292 {
293 register int i = startElementNo;
294 int j, valueCharsWide, charsWide, itemWinWidth, curY, labelWidth;
295 enum precision_type precision;
296
297 precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
298 == TUI_DFLOAT_REGS) ?
299 double_precision : unspecified_precision;
300 if (IS_64BIT ||
301 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
302 {
303 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
304 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
305 }
306 else
307 {
308 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
309 TUI_SFLOAT_REGS)
310 {
311 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
312 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
313 }
314 else
315 {
316 valueCharsWide = SINGLE_VALUE_WIDTH;
317 labelWidth = SINGLE_LABEL_WIDTH;
318 }
319 }
320 itemWinWidth = valueCharsWide + labelWidth;
321 /*
322 ** Now create each data "sub" window, and write the display into it.
323 */
324 curY = 1;
325 while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
326 curY <= dataWin->generic.viewportHeight)
327 {
328 for (j = 0;
329 (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
330 i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
331 {
332 TuiGenWinInfoPtr dataItemWin;
333 TuiDataElementPtr dataElementPtr;
334
335 /* create the window if necessary */
336 dataItemWin = &dataWin->detail.dataDisplayInfo.
337 regsContent[i]->whichElement.dataWindow;
338 dataElementPtr = &((TuiWinElementPtr)
339 dataItemWin->content[0])->whichElement.data;
340 if (dataItemWin->handle == (WINDOW *) NULL)
341 {
342 dataItemWin->height = 1;
343 dataItemWin->width = (precision == double_precision) ?
344 itemWinWidth + 2 : itemWinWidth + 1;
345 dataItemWin->origin.x = (itemWinWidth * j) + 1;
346 dataItemWin->origin.y = curY;
347 makeWindow (dataItemWin, DONT_BOX_WINDOW);
348 scrollok (dataItemWin->handle, FALSE);
349 }
350 touchwin (dataItemWin->handle);
351
352 /*
353 ** Get the printable representation of the register
354 ** and display it
355 */
356 _tuiDisplayRegister (
357 dataElementPtr->itemNo, dataItemWin, precision);
358 i++; /* next register */
359 }
360 curY++; /* next row; */
361 }
362 }
363
364 return;
365 } /* tuiDisplayRegistersFrom */
366
367
368 /*
369 ** tuiDisplayRegElementAtLine().
370 ** Function to display the registers in the content from
371 ** 'startElementNo' on 'startLineNo' until the end of the
372 ** register content or the end of the display height.
373 ** This function checks that we won't display off the end
374 ** of the register display.
375 */
376 void
377 tuiDisplayRegElementAtLine (int startElementNo, int startLineNo)
378 {
379 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
380 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
381 {
382 register int elementNo = startElementNo;
383
384 if (startElementNo != 0 && startLineNo != 0)
385 {
386 register int lastLineNo, firstLineOnLastPage;
387
388 lastLineNo = tuiLastRegsLineNo ();
389 firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
390 if (firstLineOnLastPage < 0)
391 firstLineOnLastPage = 0;
392 /*
393 ** If there is no other data displayed except registers,
394 ** and the elementNo causes us to scroll past the end of the
395 ** registers, adjust what element to really start the display at.
396 */
397 if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
398 startLineNo > firstLineOnLastPage)
399 elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
400 }
401 tuiDisplayRegistersFrom (elementNo);
402 }
403
404 return;
405 } /* tuiDisplayRegElementAtLine */
406
407
408
409 /*
410 ** tuiDisplayRegistersFromLine().
411 ** Function to display the registers starting at line lineNo in
412 ** the data window. Answers the line number that the display
413 ** actually started from. If nothing is displayed (-1) is returned.
414 */
415 int
416 tuiDisplayRegistersFromLine (int lineNo, int forceDisplay)
417 {
418 int elementNo;
419
420 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
421 {
422 int line, elementNo;
423
424 if (lineNo < 0)
425 line = 0;
426 else if (forceDisplay)
427 { /*
428 ** If we must display regs (forceDisplay is true), then make
429 ** sure that we don't display off the end of the registers.
430 */
431 if (lineNo >= tuiLastRegsLineNo ())
432 {
433 if ((line = tuiLineFromRegElementNo (
434 dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
435 line = 0;
436 }
437 else
438 line = lineNo;
439 }
440 else
441 line = lineNo;
442
443 elementNo = tuiFirstRegElementNoInLine (line);
444 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
445 tuiDisplayRegElementAtLine (elementNo, line);
446 else
447 line = (-1);
448
449 return line;
450 }
451
452 return (-1); /* nothing was displayed */
453 } /* tuiDisplayRegistersFromLine */
454
455
456 /*
457 ** tuiCheckRegisterValues()
458 ** This function check all displayed registers for changes in
459 ** values, given a particular frame. If the values have changed,
460 ** they are updated with the new value and highlighted.
461 */
462 void
463 tuiCheckRegisterValues (struct frame_info *frame)
464 {
465 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
466 {
467 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
468 dataWin->detail.dataDisplayInfo.displayRegs)
469 tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
470 else
471 {
472 int i, j;
473 char rawBuf[MAX_REGISTER_RAW_SIZE];
474
475 for (i = 0;
476 (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
477 {
478 TuiDataElementPtr dataElementPtr;
479 TuiGenWinInfoPtr dataItemWinPtr;
480 int wasHilighted;
481
482 dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
483 regsContent[i]->whichElement.dataWindow;
484 dataElementPtr = &((TuiWinElementPtr)
485 dataItemWinPtr->content[0])->whichElement.data;
486 wasHilighted = dataElementPtr->highlight;
487 dataElementPtr->highlight =
488 _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
489 if (dataElementPtr->highlight)
490 {
491 int size;
492
493 size = REGISTER_RAW_SIZE (dataElementPtr->itemNo);
494 for (j = 0; j < size; j++)
495 ((char *) dataElementPtr->value)[j] = rawBuf[j];
496 _tuiDisplayRegister (
497 dataElementPtr->itemNo,
498 dataItemWinPtr,
499 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
500 TUI_DFLOAT_REGS) ?
501 double_precision : unspecified_precision));
502 }
503 else if (wasHilighted)
504 {
505 dataElementPtr->highlight = FALSE;
506 _tuiDisplayRegister (
507 dataElementPtr->itemNo,
508 dataItemWinPtr,
509 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
510 TUI_DFLOAT_REGS) ?
511 double_precision : unspecified_precision));
512 }
513 }
514 }
515 }
516 return;
517 } /* tuiCheckRegisterValues */
518
519
520 /*
521 ** tuiToggleFloatRegs().
522 */
523 void
524 tuiToggleFloatRegs (void)
525 {
526 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
527
528 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
529 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
530 else
531 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
532
533 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
534 (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
535 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
536 tuiShowRegisters (layoutDef->floatRegsDisplayType);
537
538 return;
539 } /* tuiToggleFloatRegs */
540
541
542 void
543 _initialize_tuiRegs (void)
544 {
545 if (xdb_commands)
546 {
547 add_com ("fr", class_tui, _tuiShowFloat_command,
548 "Display only floating point registers\n");
549 add_com ("gr", class_tui, _tuiShowGeneral_command,
550 "Display only general registers\n");
551 add_com ("sr", class_tui, _tuiShowSpecial_command,
552 "Display only special registers\n");
553 add_com ("+r", class_tui, _tuiScrollRegsForward_command,
554 "Scroll the registers window forward\n");
555 add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
556 "Scroll the register window backward\n");
557 add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
558 "Toggle between single and double precision floating point registers.\n");
559 add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
560 class_tui,
561 _tuiToggleFloatRegs_command,
562 "Toggle between single and double precision floating point \
563 registers.\n",
564 &togglelist);
565 }
566 }
567
568
569 /*****************************************
570 ** STATIC LOCAL FUNCTIONS **
571 ******************************************/
572
573
574 /*
575 ** _tuiRegisterName().
576 ** Return the register name.
577 */
578 static char *
579 _tuiRegisterName (int regNum)
580 {
581 return REGISTER_NAME (regNum);
582 }
583 extern int pagination_enabled;
584
585 static void
586 tui_restore_gdbout (void *ui)
587 {
588 ui_file_delete (gdb_stdout);
589 gdb_stdout = (struct ui_file*) ui;
590 pagination_enabled = 1;
591 }
592
593 /*
594 ** _tuiRegisterFormat
595 ** Function to format the register name and value into a buffer,
596 ** suitable for printing or display
597 */
598 static void
599 _tuiRegisterFormat (char *buf, int bufLen, int regNum,
600 TuiDataElementPtr dataElement,
601 enum precision_type precision)
602 {
603 struct ui_file *stream;
604 struct ui_file *old_stdout;
605 char *name;
606 struct cleanup *cleanups;
607 char *p;
608 int pos;
609
610 name = REGISTER_NAME (regNum);
611 if (name == 0)
612 {
613 strcpy (buf, "");
614 return;
615 }
616
617 pagination_enabled = 0;
618 old_stdout = gdb_stdout;
619 stream = tui_sfileopen (bufLen);
620 gdb_stdout = stream;
621 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
622 do_registers_info (regNum, 0);
623
624 /* Save formatted output in the buffer. */
625 p = tui_file_get_strbuf (stream);
626 pos = 0;
627 while (*p && *p == *name++ && bufLen)
628 {
629 *buf++ = *p++;
630 bufLen--;
631 pos++;
632 }
633 while (*p == ' ')
634 p++;
635 while (pos < 8 && bufLen)
636 {
637 *buf++ = ' ';
638 bufLen--;
639 pos++;
640 }
641 strncpy (buf, p, bufLen);
642
643 /* Remove the possible \n. */
644 p = strchr (buf, '\n');
645 if (p)
646 *p = 0;
647
648 do_cleanups (cleanups);
649 }
650
651
652 #define NUM_GENERAL_REGS 32
653 /*
654 ** _tuiSetGeneralRegsContent().
655 ** Set the content of the data window to consist of the general registers.
656 */
657 static TuiStatus
658 _tuiSetGeneralRegsContent (int refreshValuesOnly)
659 {
660 return (_tuiSetRegsContent (0,
661 NUM_GENERAL_REGS - 1,
662 selected_frame,
663 TUI_GENERAL_REGS,
664 refreshValuesOnly));
665
666 } /* _tuiSetGeneralRegsContent */
667
668
669 #ifndef PCOQ_HEAD_REGNUM
670 #define START_SPECIAL_REGS 0
671 #else
672 #define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
673 #endif
674
675 /*
676 ** _tuiSetSpecialRegsContent().
677 ** Set the content of the data window to consist of the special registers.
678 */
679 static TuiStatus
680 _tuiSetSpecialRegsContent (int refreshValuesOnly)
681 {
682 TuiStatus ret = TUI_FAILURE;
683 int i, endRegNum;
684
685 endRegNum = FP0_REGNUM - 1;
686 #if 0
687 endRegNum = (-1);
688 for (i = START_SPECIAL_REGS; (i < NUM_REGS && endRegNum < 0); i++)
689 if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
690 endRegNum = i - 1;
691 #endif
692 ret = _tuiSetRegsContent (START_SPECIAL_REGS,
693 endRegNum,
694 selected_frame,
695 TUI_SPECIAL_REGS,
696 refreshValuesOnly);
697
698 return ret;
699 } /* _tuiSetSpecialRegsContent */
700
701
702 /*
703 ** _tuiSetGeneralAndSpecialRegsContent().
704 ** Set the content of the data window to consist of the special registers.
705 */
706 static TuiStatus
707 _tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly)
708 {
709 TuiStatus ret = TUI_FAILURE;
710 int i, endRegNum = (-1);
711
712 endRegNum = FP0_REGNUM - 1;
713 #if 0
714 endRegNum = (-1);
715 for (i = 0; (i < NUM_REGS && endRegNum < 0); i++)
716 if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
717 endRegNum = i - 1;
718 #endif
719 ret = _tuiSetRegsContent (
720 0, endRegNum, selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
721
722 return ret;
723 } /* _tuiSetGeneralAndSpecialRegsContent */
724
725 /*
726 ** _tuiSetFloatRegsContent().
727 ** Set the content of the data window to consist of the float registers.
728 */
729 static TuiStatus
730 _tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly)
731 {
732 TuiStatus ret = TUI_FAILURE;
733 int i, startRegNum;
734
735 startRegNum = FP0_REGNUM;
736 #if 0
737 startRegNum = (-1);
738 for (i = NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--)
739 if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT)
740 startRegNum = i + 1;
741 #endif
742 ret = _tuiSetRegsContent (startRegNum,
743 NUM_REGS - 1,
744 selected_frame,
745 dpyType,
746 refreshValuesOnly);
747
748 return ret;
749 } /* _tuiSetFloatRegsContent */
750
751
752 /*
753 ** _tuiRegValueHasChanged().
754 ** Answer TRUE if the register's value has changed, FALSE otherwise.
755 ** If TRUE, newValue is filled in with the new value.
756 */
757 static int
758 _tuiRegValueHasChanged (TuiDataElementPtr dataElement,
759 struct frame_info *frame,
760 char *newValue)
761 {
762 int hasChanged = FALSE;
763
764 if (dataElement->itemNo != UNDEFINED_ITEM &&
765 _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
766 {
767 char rawBuf[MAX_REGISTER_RAW_SIZE];
768 int i;
769
770 if (_tuiGetRegisterRawValue (
771 dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
772 {
773 int size = REGISTER_RAW_SIZE (dataElement->itemNo);
774
775 for (i = 0; (i < size && !hasChanged); i++)
776 hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
777 if (hasChanged && newValue != (char *) NULL)
778 {
779 for (i = 0; i < size; i++)
780 newValue[i] = rawBuf[i];
781 }
782 }
783 }
784 return hasChanged;
785 } /* _tuiRegValueHasChanged */
786
787
788
789 /*
790 ** _tuiGetRegisterRawValue().
791 ** Get the register raw value. The raw value is returned in regValue.
792 */
793 static TuiStatus
794 _tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame)
795 {
796 TuiStatus ret = TUI_FAILURE;
797
798 if (target_has_registers)
799 {
800 int opt;
801
802 get_saved_register (regValue, &opt, (CORE_ADDR*) NULL, frame,
803 regNum, (enum lval_type*) NULL);
804 if (register_cached (regNum) >= 0)
805 ret = TUI_SUCCESS;
806 }
807 return ret;
808 } /* _tuiGetRegisterRawValue */
809
810
811
812 /*
813 ** _tuiSetRegisterElement().
814 ** Function to initialize a data element with the input and
815 ** the register value.
816 */
817 static void
818 _tuiSetRegisterElement (int regNum, struct frame_info *frame,
819 TuiDataElementPtr dataElement,
820 int refreshValueOnly)
821 {
822 if (dataElement != (TuiDataElementPtr) NULL)
823 {
824 if (!refreshValueOnly)
825 {
826 dataElement->itemNo = regNum;
827 dataElement->name = _tuiRegisterName (regNum);
828 dataElement->highlight = FALSE;
829 }
830 if (dataElement->value == (Opaque) NULL)
831 dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE);
832 if (dataElement->value != (Opaque) NULL)
833 _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
834 }
835
836 return;
837 } /* _tuiSetRegisterElement */
838
839
840 /*
841 ** _tuiSetRegsContent().
842 ** Set the content of the data window to consist of the registers
843 ** numbered from startRegNum to endRegNum. Note that if
844 ** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
845 */
846 static TuiStatus
847 _tuiSetRegsContent (int startRegNum, int endRegNum,
848 struct frame_info *frame,
849 TuiRegisterDisplayType dpyType,
850 int refreshValuesOnly)
851 {
852 TuiStatus ret = TUI_FAILURE;
853 int numRegs = endRegNum - startRegNum + 1;
854 int allocatedHere = FALSE;
855
856 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
857 !refreshValuesOnly)
858 {
859 freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
860 dataWin->detail.dataDisplayInfo.regsContentCount);
861 dataWin->detail.dataDisplayInfo.regsContentCount = 0;
862 }
863 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
864 {
865 dataWin->detail.dataDisplayInfo.regsContent =
866 allocContent (numRegs, DATA_WIN);
867 allocatedHere = TRUE;
868 }
869
870 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
871 {
872 int i;
873
874 if (!refreshValuesOnly || allocatedHere)
875 {
876 dataWin->generic.content = (OpaquePtr) NULL;
877 dataWin->generic.contentSize = 0;
878 addContentElements (&dataWin->generic, numRegs);
879 dataWin->detail.dataDisplayInfo.regsContent =
880 (TuiWinContent) dataWin->generic.content;
881 dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
882 }
883 /*
884 ** Now set the register names and values
885 */
886 for (i = startRegNum; (i <= endRegNum); i++)
887 {
888 TuiGenWinInfoPtr dataItemWin;
889
890 dataItemWin = &dataWin->detail.dataDisplayInfo.
891 regsContent[i - startRegNum]->whichElement.dataWindow;
892 _tuiSetRegisterElement (
893 i,
894 frame,
895 &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
896 !allocatedHere && refreshValuesOnly);
897 }
898 dataWin->detail.dataDisplayInfo.regsColumnCount =
899 tuiCalculateRegsColumnCount (dpyType);
900 #ifdef LATER
901 if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
902 {
903 /* delete all the windows? */
904 /* realloc content equal to dataContentCount + regsContentCount */
905 /* append dataWin->detail.dataDisplayInfo.dataContent to content */
906 }
907 #endif
908 dataWin->generic.contentSize =
909 dataWin->detail.dataDisplayInfo.regsContentCount +
910 dataWin->detail.dataDisplayInfo.dataContentCount;
911 ret = TUI_SUCCESS;
912 }
913
914 return ret;
915 } /* _tuiSetRegsContent */
916
917
918 /*
919 ** _tuiDisplayRegister().
920 ** Function to display a register in a window. If hilite is TRUE,
921 ** than the value will be displayed in reverse video
922 */
923 static void
924 _tuiDisplayRegister (int regNum,
925 TuiGenWinInfoPtr winInfo, /* the data item window */
926 enum precision_type precision)
927 {
928 if (winInfo->handle != (WINDOW *) NULL)
929 {
930 int i;
931 char buf[40];
932 int valueCharsWide, labelWidth;
933 TuiDataElementPtr dataElementPtr = &((TuiWinContent)
934 winInfo->content)[0]->whichElement.data;
935
936 if (IS_64BIT ||
937 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
938 {
939 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
940 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
941 }
942 else
943 {
944 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
945 TUI_SFLOAT_REGS)
946 {
947 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
948 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
949 }
950 else
951 {
952 valueCharsWide = SINGLE_VALUE_WIDTH;
953 labelWidth = SINGLE_LABEL_WIDTH;
954 }
955 }
956
957 buf[0] = (char) 0;
958 _tuiRegisterFormat (buf,
959 valueCharsWide + labelWidth,
960 regNum,
961 dataElementPtr,
962 precision);
963
964 if (dataElementPtr->highlight)
965 wstandout (winInfo->handle);
966
967 wmove (winInfo->handle, 0, 0);
968 for (i = 1; i < winInfo->width; i++)
969 waddch (winInfo->handle, ' ');
970 wmove (winInfo->handle, 0, 0);
971 waddstr (winInfo->handle, buf);
972
973 if (dataElementPtr->highlight)
974 wstandend (winInfo->handle);
975 tuiRefreshWin (winInfo);
976 }
977 return;
978 } /* _tuiDisplayRegister */
979
980
981 static void
982 _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType)
983 {
984
985 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
986 { /* Data window already displayed, show the registers */
987 if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
988 tuiShowRegisters (dpyType);
989 }
990 else
991 (tuiLayoutDef ())->regsDisplayType = dpyType;
992
993 return;
994 } /* _tui_vShowRegisters_commandSupport */
995
996
997 static void
998 _tuiShowFloat_command (char *arg, int fromTTY)
999 {
1000 if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
1001 (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
1002 dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
1003 _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType);
1004
1005 return;
1006 } /* _tuiShowFloat_command */
1007
1008
1009 static void
1010 _tuiShowGeneral_command (char *arg, int fromTTY)
1011 {
1012 _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS);
1013 }
1014
1015
1016 static void
1017 _tuiShowSpecial_command (char *arg, int fromTTY)
1018 {
1019 _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS);
1020 }
1021
1022
1023 static void
1024 _tuiToggleFloatRegs_command (char *arg, int fromTTY)
1025 {
1026 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
1027 tuiToggleFloatRegs ();
1028 else
1029 {
1030 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
1031
1032 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
1033 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
1034 else
1035 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
1036 }
1037
1038
1039 return;
1040 } /* _tuiToggleFloatRegs_command */
1041
1042
1043 static void
1044 _tuiScrollRegsForward_command (char *arg, int fromTTY)
1045 {
1046 tui_scroll (FORWARD_SCROLL, dataWin, 1);
1047 }
1048
1049
1050 static void
1051 _tuiScrollRegsBackward_command (char *arg, int fromTTY)
1052 {
1053 tui_scroll (BACKWARD_SCROLL, dataWin, 1);
1054 }
This page took 0.051863 seconds and 4 git commands to generate.