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