1205 lines
31 KiB
C
1205 lines
31 KiB
C
|
|
/*
|
|
** tuiRegs.c
|
|
** This module contains functions to support display of registers
|
|
** in the data window.
|
|
*/
|
|
|
|
|
|
#include "defs.h"
|
|
#include "tui.h"
|
|
#include "tuiData.h"
|
|
#include "symtab.h"
|
|
#include "gdbtypes.h"
|
|
#include "gdbcmd.h"
|
|
#include "frame.h"
|
|
#include "inferior.h"
|
|
#include "target.h"
|
|
#include "tuiLayout.h"
|
|
#include "tuiWin.h"
|
|
|
|
|
|
/*****************************************
|
|
** LOCAL DEFINITIONS **
|
|
******************************************/
|
|
#define DOUBLE_FLOAT_LABEL_WIDTH 6
|
|
#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
|
|
#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
|
|
|
|
#define SINGLE_FLOAT_LABEL_WIDTH 6
|
|
#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
|
|
#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
|
|
|
|
#define SINGLE_LABEL_WIDTH 10
|
|
#define SINGLE_LABEL_FMT "%10.10s: "
|
|
#define SINGLE_VALUE_WIDTH 14 /* minimum of 8 but may be in sci notation */
|
|
|
|
/* In the code HP gave Cygnus, this was actually a function call to a
|
|
PA-specific function, which was supposed to determine whether the
|
|
target was a 64-bit or 32-bit processor. However, the 64-bit
|
|
support wasn't complete, so we didn't merge that in, so we leave
|
|
this here as a stub. */
|
|
#define IS_64BIT 0
|
|
|
|
/*****************************************
|
|
** STATIC DATA **
|
|
******************************************/
|
|
|
|
|
|
/*****************************************
|
|
** STATIC LOCAL FUNCTIONS FORWARD DECLS **
|
|
******************************************/
|
|
static TuiStatus _tuiSetRegsContent
|
|
(int, int, struct frame_info *, TuiRegisterDisplayType, int);
|
|
static char *_tuiRegisterName (int);
|
|
static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
|
|
static void _tuiSetRegisterElement
|
|
(int, struct frame_info *, TuiDataElementPtr, int);
|
|
static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
|
|
static void _tuiRegisterFormat
|
|
(char *, int, int, TuiDataElementPtr, enum precision_type);
|
|
static TuiStatus _tuiSetGeneralRegsContent (int);
|
|
static TuiStatus _tuiSetSpecialRegsContent (int);
|
|
static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
|
|
static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
|
|
static int _tuiRegValueHasChanged
|
|
(TuiDataElementPtr, struct frame_info *, char *);
|
|
static void _tuiShowFloat_command (char *, int);
|
|
static void _tuiShowGeneral_command (char *, int);
|
|
static void _tuiShowSpecial_command (char *, int);
|
|
static void _tui_vShowRegisters_commandSupport (va_list);
|
|
static void _tuiToggleFloatRegs_command (char *, int);
|
|
static void _tuiScrollRegsForward_command (char *, int);
|
|
static void _tuiScrollRegsBackward_command (char *, int);
|
|
static void _tui_vShowRegisters_commandSupport (va_list);
|
|
|
|
|
|
|
|
/*****************************************
|
|
** PUBLIC FUNCTIONS **
|
|
******************************************/
|
|
|
|
/*
|
|
** tuiLastRegsLineNo()
|
|
** Answer the number of the last line in the regs display.
|
|
** If there are no registers (-1) is returned.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiLastRegsLineNo (void)
|
|
#else
|
|
tuiLastRegsLineNo ()
|
|
#endif
|
|
{
|
|
register int numLines = (-1);
|
|
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
|
|
{
|
|
numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount);
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount %
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount)
|
|
numLines++;
|
|
}
|
|
return numLines;
|
|
} /* tuiLastRegsLineNo */
|
|
|
|
|
|
/*
|
|
** tuiLineFromRegElementNo()
|
|
** Answer the line number that the register element at elementNo is
|
|
** on. If elementNo is greater than the number of register elements
|
|
** there are, -1 is returned.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiLineFromRegElementNo (
|
|
int elementNo)
|
|
#else
|
|
tuiLineFromRegElementNo (elementNo)
|
|
int elementNo;
|
|
#endif
|
|
{
|
|
if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
|
|
{
|
|
int i, line = (-1);
|
|
|
|
i = 1;
|
|
while (line == (-1))
|
|
{
|
|
if (elementNo <
|
|
(dataWin->detail.dataDisplayInfo.regsColumnCount * i))
|
|
line = i - 1;
|
|
else
|
|
i++;
|
|
}
|
|
|
|
return line;
|
|
}
|
|
else
|
|
return (-1);
|
|
} /* tuiLineFromRegElementNo */
|
|
|
|
|
|
/*
|
|
** tuiFirstRegElementNoInLine()
|
|
** Answer the index of the first element in lineNo. If lineNo is
|
|
** past the register area (-1) is returned.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiFirstRegElementNoInLine (
|
|
int lineNo)
|
|
#else
|
|
tuiFirstRegElementNoInLine (lineNo)
|
|
int lineNo;
|
|
#endif
|
|
{
|
|
if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
|
|
<= dataWin->detail.dataDisplayInfo.regsContentCount)
|
|
return ((lineNo + 1) *
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount) -
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount;
|
|
else
|
|
return (-1);
|
|
} /* tuiFirstRegElementNoInLine */
|
|
|
|
|
|
/*
|
|
** tuiLastRegElementNoInLine()
|
|
** Answer the index of the last element in lineNo. If lineNo is past
|
|
** the register area (-1) is returned.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiLastRegElementNoInLine (
|
|
int lineNo)
|
|
#else
|
|
tuiLastRegElementNoInLine (lineNo)
|
|
int lineNo;
|
|
#endif
|
|
{
|
|
if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
|
|
dataWin->detail.dataDisplayInfo.regsContentCount)
|
|
return ((lineNo + 1) *
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
|
|
else
|
|
return (-1);
|
|
} /* tuiLastRegElementNoInLine */
|
|
|
|
|
|
/*
|
|
** tuiCalculateRegsColumnCount
|
|
** Calculate the number of columns that should be used to display
|
|
** the registers.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiCalculateRegsColumnCount (
|
|
TuiRegisterDisplayType dpyType)
|
|
#else
|
|
tuiCalculateRegsColumnCount (dpyType)
|
|
TuiRegisterDisplayType dpyType;
|
|
#endif
|
|
{
|
|
int colCount, colWidth;
|
|
|
|
if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
|
|
colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
|
|
else
|
|
{
|
|
if (dpyType == TUI_SFLOAT_REGS)
|
|
colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
|
|
else
|
|
colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
|
|
}
|
|
colCount = (dataWin->generic.width - 2) / colWidth;
|
|
|
|
return colCount;
|
|
} /* tuiCalulateRegsColumnCount */
|
|
|
|
|
|
/*
|
|
** tuiShowRegisters().
|
|
** Show the registers int the data window as indicated by dpyType.
|
|
** If there is any other registers being displayed, then they are
|
|
** cleared. What registers are displayed is dependent upon dpyType.
|
|
*/
|
|
void
|
|
#ifdef __STDC__
|
|
tuiShowRegisters (
|
|
TuiRegisterDisplayType dpyType)
|
|
#else
|
|
tuiShowRegisters (dpyType)
|
|
TuiRegisterDisplayType dpyType;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
int refreshValuesOnly = FALSE;
|
|
|
|
/* Say that registers should be displayed, even if there is a problem */
|
|
dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
|
|
|
|
if (target_has_registers)
|
|
{
|
|
refreshValuesOnly =
|
|
(dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
|
|
switch (dpyType)
|
|
{
|
|
case TUI_GENERAL_REGS:
|
|
ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
|
|
break;
|
|
case TUI_SFLOAT_REGS:
|
|
case TUI_DFLOAT_REGS:
|
|
ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
|
|
break;
|
|
|
|
/* could ifdef out */
|
|
|
|
case TUI_SPECIAL_REGS:
|
|
ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
|
|
break;
|
|
case TUI_GENERAL_AND_SPECIAL_REGS:
|
|
ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
|
|
break;
|
|
|
|
/* end of potential if def */
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (ret == TUI_FAILURE)
|
|
{
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
|
|
tuiEraseDataContent (NO_REGS_STRING);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
/* Clear all notation of changed values */
|
|
for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
|
|
{
|
|
TuiGenWinInfoPtr dataItemWin;
|
|
|
|
dataItemWin = &dataWin->detail.dataDisplayInfo.
|
|
regsContent[i]->whichElement.dataWindow;
|
|
(&((TuiWinElementPtr)
|
|
dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
|
|
}
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
|
|
tuiDisplayAllData ();
|
|
}
|
|
(tuiLayoutDef ())->regsDisplayType = dpyType;
|
|
|
|
return;
|
|
} /* tuiShowRegisters */
|
|
|
|
|
|
/*
|
|
** tuiDisplayRegistersFrom().
|
|
** Function to display the registers in the content from
|
|
** 'startElementNo' until the end of the register content or the
|
|
** end of the display height. No checking for displaying past
|
|
** the end of the registers is done here.
|
|
*/
|
|
void
|
|
#ifdef __STDC__
|
|
tuiDisplayRegistersFrom (
|
|
int startElementNo)
|
|
#else
|
|
tuiDisplayRegistersFrom (startElementNo)
|
|
int startElementNo;
|
|
#endif
|
|
{
|
|
if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
|
|
dataWin->detail.dataDisplayInfo.regsContentCount > 0)
|
|
{
|
|
register int i = startElementNo;
|
|
int j, valueCharsWide, charsWide, itemWinWidth, curY, labelWidth;
|
|
enum precision_type precision;
|
|
|
|
precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
|
|
== TUI_DFLOAT_REGS) ?
|
|
double_precision : unspecified_precision;
|
|
if (IS_64BIT ||
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
|
|
{
|
|
valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
|
|
labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
|
|
}
|
|
else
|
|
{
|
|
if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
|
|
TUI_SFLOAT_REGS)
|
|
{
|
|
valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
|
|
labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
|
|
}
|
|
else
|
|
{
|
|
valueCharsWide = SINGLE_VALUE_WIDTH;
|
|
labelWidth = SINGLE_LABEL_WIDTH;
|
|
}
|
|
}
|
|
itemWinWidth = valueCharsWide + labelWidth;
|
|
/*
|
|
** Now create each data "sub" window, and write the display into it.
|
|
*/
|
|
curY = 1;
|
|
while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
|
|
curY <= dataWin->generic.viewportHeight)
|
|
{
|
|
for (j = 0;
|
|
(j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
|
|
i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
|
|
{
|
|
TuiGenWinInfoPtr dataItemWin;
|
|
TuiDataElementPtr dataElementPtr;
|
|
|
|
/* create the window if necessary */
|
|
dataItemWin = &dataWin->detail.dataDisplayInfo.
|
|
regsContent[i]->whichElement.dataWindow;
|
|
dataElementPtr = &((TuiWinElementPtr)
|
|
dataItemWin->content[0])->whichElement.data;
|
|
if (dataItemWin->handle == (WINDOW *) NULL)
|
|
{
|
|
dataItemWin->height = 1;
|
|
dataItemWin->width = (precision == double_precision) ?
|
|
itemWinWidth + 2 : itemWinWidth + 1;
|
|
dataItemWin->origin.x = (itemWinWidth * j) + 1;
|
|
dataItemWin->origin.y = curY;
|
|
makeWindow (dataItemWin, DONT_BOX_WINDOW);
|
|
}
|
|
/*
|
|
** Get the printable representation of the register
|
|
** and display it
|
|
*/
|
|
_tuiDisplayRegister (
|
|
dataElementPtr->itemNo, dataItemWin, precision);
|
|
i++; /* next register */
|
|
}
|
|
curY++; /* next row; */
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* tuiDisplayRegistersFrom */
|
|
|
|
|
|
/*
|
|
** tuiDisplayRegElementAtLine().
|
|
** Function to display the registers in the content from
|
|
** 'startElementNo' on 'startLineNo' until the end of the
|
|
** register content or the end of the display height.
|
|
** This function checks that we won't display off the end
|
|
** of the register display.
|
|
*/
|
|
void
|
|
#ifdef __STDC__
|
|
tuiDisplayRegElementAtLine (
|
|
int startElementNo,
|
|
int startLineNo)
|
|
#else
|
|
tuiDisplayRegElementAtLine (startElementNo, startLineNo)
|
|
int startElementNo;
|
|
int startLineNo;
|
|
#endif
|
|
{
|
|
if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
|
|
dataWin->detail.dataDisplayInfo.regsContentCount > 0)
|
|
{
|
|
register int elementNo = startElementNo;
|
|
|
|
if (startElementNo != 0 && startLineNo != 0)
|
|
{
|
|
register int lastLineNo, firstLineOnLastPage;
|
|
|
|
lastLineNo = tuiLastRegsLineNo ();
|
|
firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
|
|
if (firstLineOnLastPage < 0)
|
|
firstLineOnLastPage = 0;
|
|
/*
|
|
** If there is no other data displayed except registers,
|
|
** and the elementNo causes us to scroll past the end of the
|
|
** registers, adjust what element to really start the display at.
|
|
*/
|
|
if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
|
|
startLineNo > firstLineOnLastPage)
|
|
elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
|
|
}
|
|
tuiDisplayRegistersFrom (elementNo);
|
|
}
|
|
|
|
return;
|
|
} /* tuiDisplayRegElementAtLine */
|
|
|
|
|
|
|
|
/*
|
|
** tuiDisplayRegistersFromLine().
|
|
** Function to display the registers starting at line lineNo in
|
|
** the data window. Answers the line number that the display
|
|
** actually started from. If nothing is displayed (-1) is returned.
|
|
*/
|
|
int
|
|
#ifdef __STDC__
|
|
tuiDisplayRegistersFromLine (
|
|
int lineNo,
|
|
int forceDisplay)
|
|
#else
|
|
tuiDisplayRegistersFromLine (lineNo, forceDisplay)
|
|
int lineNo;
|
|
int forceDisplay;
|
|
#endif
|
|
{
|
|
int elementNo;
|
|
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
|
|
{
|
|
int line, elementNo;
|
|
|
|
if (lineNo < 0)
|
|
line = 0;
|
|
else if (forceDisplay)
|
|
{ /*
|
|
** If we must display regs (forceDisplay is true), then make
|
|
** sure that we don't display off the end of the registers.
|
|
*/
|
|
if (lineNo >= tuiLastRegsLineNo ())
|
|
{
|
|
if ((line = tuiLineFromRegElementNo (
|
|
dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
|
|
line = 0;
|
|
}
|
|
else
|
|
line = lineNo;
|
|
}
|
|
else
|
|
line = lineNo;
|
|
|
|
elementNo = tuiFirstRegElementNoInLine (line);
|
|
if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
|
|
tuiDisplayRegElementAtLine (elementNo, line);
|
|
else
|
|
line = (-1);
|
|
|
|
return line;
|
|
}
|
|
|
|
return (-1); /* nothing was displayed */
|
|
} /* tuiDisplayRegistersFromLine */
|
|
|
|
|
|
/*
|
|
** tuiCheckRegisterValues()
|
|
** This function check all displayed registers for changes in
|
|
** values, given a particular frame. If the values have changed,
|
|
** they are updated with the new value and highlighted.
|
|
*/
|
|
void
|
|
#ifdef __STDC__
|
|
tuiCheckRegisterValues (
|
|
struct frame_info *frame)
|
|
#else
|
|
tuiCheckRegisterValues (frame)
|
|
struct frame_info *frame;
|
|
#endif
|
|
{
|
|
if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
|
|
{
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
|
|
dataWin->detail.dataDisplayInfo.displayRegs)
|
|
tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
|
|
else
|
|
{
|
|
int i, j;
|
|
char rawBuf[MAX_REGISTER_RAW_SIZE];
|
|
|
|
for (i = 0;
|
|
(i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
|
|
{
|
|
TuiDataElementPtr dataElementPtr;
|
|
TuiGenWinInfoPtr dataItemWinPtr;
|
|
int wasHilighted;
|
|
|
|
dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
|
|
regsContent[i]->whichElement.dataWindow;
|
|
dataElementPtr = &((TuiWinElementPtr)
|
|
dataItemWinPtr->content[0])->whichElement.data;
|
|
wasHilighted = dataElementPtr->highlight;
|
|
dataElementPtr->highlight =
|
|
_tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
|
|
if (dataElementPtr->highlight)
|
|
{
|
|
for (j = 0; j < MAX_REGISTER_RAW_SIZE; j++)
|
|
((char *) dataElementPtr->value)[j] = rawBuf[j];
|
|
_tuiDisplayRegister (
|
|
dataElementPtr->itemNo,
|
|
dataItemWinPtr,
|
|
((dataWin->detail.dataDisplayInfo.regsDisplayType ==
|
|
TUI_DFLOAT_REGS) ?
|
|
double_precision : unspecified_precision));
|
|
}
|
|
else if (wasHilighted)
|
|
{
|
|
dataElementPtr->highlight = FALSE;
|
|
_tuiDisplayRegister (
|
|
dataElementPtr->itemNo,
|
|
dataItemWinPtr,
|
|
((dataWin->detail.dataDisplayInfo.regsDisplayType ==
|
|
TUI_DFLOAT_REGS) ?
|
|
double_precision : unspecified_precision));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
} /* tuiCheckRegisterValues */
|
|
|
|
|
|
/*
|
|
** tuiToggleFloatRegs().
|
|
*/
|
|
void
|
|
#ifdef __STDC__
|
|
tuiToggleFloatRegs (void)
|
|
#else
|
|
tuiToggleFloatRegs ()
|
|
#endif
|
|
{
|
|
TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
|
|
|
|
if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
|
|
layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
|
|
else
|
|
layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
|
|
|
|
if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
|
|
(dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
|
|
tuiShowRegisters (layoutDef->floatRegsDisplayType);
|
|
|
|
return;
|
|
} /* tuiToggleFloatRegs */
|
|
|
|
|
|
void
|
|
_initialize_tuiRegs (void)
|
|
{
|
|
if (tui_version && xdb_commands)
|
|
{
|
|
add_com ("fr", class_tui, _tuiShowFloat_command,
|
|
"Display only floating point registers\n");
|
|
add_com ("gr", class_tui, _tuiShowGeneral_command,
|
|
"Display only general registers\n");
|
|
add_com ("sr", class_tui, _tuiShowSpecial_command,
|
|
"Display only special registers\n");
|
|
add_com ("+r", class_tui, _tuiScrollRegsForward_command,
|
|
"Scroll the registers window forward\n");
|
|
add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
|
|
"Scroll the register window backward\n");
|
|
add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
|
|
"Toggle between single and double precision floating point registers.\n");
|
|
add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
|
|
class_tui,
|
|
_tuiToggleFloatRegs_command,
|
|
"Toggle between single and double precision floating point \
|
|
registers.\n",
|
|
&togglelist);
|
|
}
|
|
|
|
return;
|
|
} /* _initialize_tuiRegs */
|
|
|
|
|
|
/*****************************************
|
|
** STATIC LOCAL FUNCTIONS **
|
|
******************************************/
|
|
|
|
|
|
/*
|
|
** _tuiRegisterName().
|
|
** Return the register name.
|
|
*/
|
|
static char *
|
|
#ifdef __STDC__
|
|
_tuiRegisterName (
|
|
int regNum)
|
|
#else
|
|
_tuiRegisterName (regNum)
|
|
int regNum;
|
|
#endif
|
|
{
|
|
if (reg_names[regNum] != (char *) NULL && *(reg_names[regNum]) != (char) 0)
|
|
return reg_names[regNum];
|
|
else
|
|
return ((char *) NULL);
|
|
} /* tuiGetRegisterName */
|
|
|
|
|
|
/*
|
|
** _tuiRegisterFormat
|
|
** Function to format the register name and value into a buffer,
|
|
** suitable for printing or display
|
|
*/
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiRegisterFormat (
|
|
char *buf,
|
|
int bufLen,
|
|
int regNum,
|
|
TuiDataElementPtr dataElement,
|
|
enum precision_type precision)
|
|
#else
|
|
_tuiRegisterFormat (buf, bufLen, regNum, dataElement, precision)
|
|
char *buf;
|
|
int bufLen;
|
|
int regNum;
|
|
TuiDataElementPtr dataElement;
|
|
enum precision_type precision;
|
|
#endif
|
|
{
|
|
char tmpBuf[15];
|
|
char *fmt;
|
|
struct ui_file *stream;
|
|
|
|
stream = tui_sfileopen (bufLen);
|
|
pa_do_strcat_registers_info (regNum, 0, stream, precision);
|
|
strcpy (buf, tui_file_get_strbuf (stream));
|
|
ui_file_delete (stream);
|
|
|
|
return;
|
|
} /* _tuiRegisterFormat */
|
|
|
|
|
|
#define NUM_GENERAL_REGS 32
|
|
/*
|
|
** _tuiSetGeneralRegsContent().
|
|
** Set the content of the data window to consist of the general registers.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiSetGeneralRegsContent (
|
|
int refreshValuesOnly)
|
|
#else
|
|
_tuiSetGeneralRegsContent (refreshValuesOnly)
|
|
int refreshValuesOnly;
|
|
#endif
|
|
{
|
|
return (_tuiSetRegsContent (0,
|
|
NUM_GENERAL_REGS - 1,
|
|
selected_frame,
|
|
TUI_GENERAL_REGS,
|
|
refreshValuesOnly));
|
|
|
|
} /* _tuiSetGeneralRegsContent */
|
|
|
|
|
|
#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
|
|
/*
|
|
** _tuiSetSpecialRegsContent().
|
|
** Set the content of the data window to consist of the special registers.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiSetSpecialRegsContent (
|
|
int refreshValuesOnly)
|
|
#else
|
|
_tuiSetSpecialRegsContent (refreshValuesOnly)
|
|
int refreshValuesOnly;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
int i, endRegNum;
|
|
|
|
endRegNum = FP0_REGNUM - 1;
|
|
#if 0
|
|
endRegNum = (-1);
|
|
for (i = START_SPECIAL_REGS; (i < NUM_REGS && endRegNum < 0); i++)
|
|
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
|
|
endRegNum = i - 1;
|
|
#endif
|
|
ret = _tuiSetRegsContent (START_SPECIAL_REGS,
|
|
endRegNum,
|
|
selected_frame,
|
|
TUI_SPECIAL_REGS,
|
|
refreshValuesOnly);
|
|
|
|
return ret;
|
|
} /* _tuiSetSpecialRegsContent */
|
|
|
|
|
|
/*
|
|
** _tuiSetGeneralAndSpecialRegsContent().
|
|
** Set the content of the data window to consist of the special registers.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiSetGeneralAndSpecialRegsContent (
|
|
int refreshValuesOnly)
|
|
#else
|
|
_tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly)
|
|
int refreshValuesOnly;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
int i, endRegNum = (-1);
|
|
|
|
endRegNum = FP0_REGNUM - 1;
|
|
#if 0
|
|
endRegNum = (-1);
|
|
for (i = 0; (i < NUM_REGS && endRegNum < 0); i++)
|
|
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
|
|
endRegNum = i - 1;
|
|
#endif
|
|
ret = _tuiSetRegsContent (
|
|
0, endRegNum, selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
|
|
|
|
return ret;
|
|
} /* _tuiSetGeneralAndSpecialRegsContent */
|
|
|
|
/*
|
|
** _tuiSetFloatRegsContent().
|
|
** Set the content of the data window to consist of the float registers.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiSetFloatRegsContent (
|
|
TuiRegisterDisplayType dpyType,
|
|
int refreshValuesOnly)
|
|
#else
|
|
_tuiSetFloatRegsContent (dpyType, refreshValuesOnly)
|
|
TuiRegisterDisplayType dpyType;
|
|
int refreshValuesOnly;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
int i, startRegNum;
|
|
|
|
startRegNum = FP0_REGNUM;
|
|
#if 0
|
|
startRegNum = (-1);
|
|
for (i = NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--)
|
|
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT)
|
|
startRegNum = i + 1;
|
|
#endif
|
|
ret = _tuiSetRegsContent (startRegNum,
|
|
NUM_REGS - 1,
|
|
selected_frame,
|
|
dpyType,
|
|
refreshValuesOnly);
|
|
|
|
return ret;
|
|
} /* _tuiSetFloatRegsContent */
|
|
|
|
|
|
/*
|
|
** _tuiRegValueHasChanged().
|
|
** Answer TRUE if the register's value has changed, FALSE otherwise.
|
|
** If TRUE, newValue is filled in with the new value.
|
|
*/
|
|
static int
|
|
#ifdef __STDC__
|
|
_tuiRegValueHasChanged (
|
|
TuiDataElementPtr dataElement,
|
|
struct frame_info *frame,
|
|
char *newValue)
|
|
#else
|
|
_tuiRegValueHasChanged (dataElement, frame, newValue)
|
|
TuiDataElementPtr dataElement;
|
|
struct frame_info *frame;
|
|
char *newValue;
|
|
#endif
|
|
{
|
|
int hasChanged = FALSE;
|
|
|
|
if (dataElement->itemNo != UNDEFINED_ITEM &&
|
|
_tuiRegisterName (dataElement->itemNo) != (char *) NULL)
|
|
{
|
|
char rawBuf[MAX_REGISTER_RAW_SIZE];
|
|
int i;
|
|
|
|
if (_tuiGetRegisterRawValue (
|
|
dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
|
|
{
|
|
for (i = 0; (i < MAX_REGISTER_RAW_SIZE && !hasChanged); i++)
|
|
hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
|
|
if (hasChanged && newValue != (char *) NULL)
|
|
{
|
|
for (i = 0; (i < MAX_REGISTER_RAW_SIZE); i++)
|
|
newValue[i] = rawBuf[i];
|
|
}
|
|
}
|
|
}
|
|
return hasChanged;
|
|
} /* _tuiRegValueHasChanged */
|
|
|
|
|
|
|
|
/*
|
|
** _tuiGetRegisterRawValue().
|
|
** Get the register raw value. The raw value is returned in regValue.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiGetRegisterRawValue (
|
|
int regNum,
|
|
char *regValue,
|
|
struct frame_info *frame)
|
|
#else
|
|
_tuiGetRegisterRawValue (regNum, regValue, frame)
|
|
int regNum;
|
|
char *regValue;
|
|
struct frame_info *frame;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
|
|
if (target_has_registers)
|
|
{
|
|
read_relative_register_raw_bytes_for_frame (regNum, regValue, frame);
|
|
ret = TUI_SUCCESS;
|
|
}
|
|
|
|
return ret;
|
|
} /* _tuiGetRegisterRawValue */
|
|
|
|
|
|
|
|
/*
|
|
** _tuiSetRegisterElement().
|
|
** Function to initialize a data element with the input and
|
|
** the register value.
|
|
*/
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiSetRegisterElement (
|
|
int regNum,
|
|
struct frame_info *frame,
|
|
TuiDataElementPtr dataElement,
|
|
int refreshValueOnly)
|
|
#else
|
|
_tuiSetRegisterElement (regNum, frame, dataElement, refreshValueOnly)
|
|
int regNum;
|
|
struct frame_info *frame;
|
|
TuiDataElementPtr dataElement;
|
|
int refreshValueOnly;
|
|
#endif
|
|
{
|
|
if (dataElement != (TuiDataElementPtr) NULL)
|
|
{
|
|
if (!refreshValueOnly)
|
|
{
|
|
dataElement->itemNo = regNum;
|
|
dataElement->name = _tuiRegisterName (regNum);
|
|
dataElement->highlight = FALSE;
|
|
}
|
|
if (dataElement->value == (Opaque) NULL)
|
|
dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE);
|
|
if (dataElement->value != (Opaque) NULL)
|
|
_tuiGetRegisterRawValue (regNum, dataElement->value, frame);
|
|
}
|
|
|
|
return;
|
|
} /* _tuiSetRegisterElement */
|
|
|
|
|
|
/*
|
|
** _tuiSetRegsContent().
|
|
** Set the content of the data window to consist of the registers
|
|
** numbered from startRegNum to endRegNum. Note that if
|
|
** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
|
|
*/
|
|
static TuiStatus
|
|
#ifdef __STDC__
|
|
_tuiSetRegsContent (
|
|
int startRegNum,
|
|
int endRegNum,
|
|
struct frame_info *frame,
|
|
TuiRegisterDisplayType dpyType,
|
|
int refreshValuesOnly)
|
|
#else
|
|
_tuiSetRegsContent (startRegNum, endRegNum, frame, dpyType, refreshValuesOnly)
|
|
int startRegNum;
|
|
int endRegNum;
|
|
struct frame_info *frame;
|
|
TuiRegisterDisplayType dpyType;
|
|
int refreshValuesOnly;
|
|
#endif
|
|
{
|
|
TuiStatus ret = TUI_FAILURE;
|
|
int numRegs = endRegNum - startRegNum + 1;
|
|
int allocatedHere = FALSE;
|
|
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
|
|
!refreshValuesOnly)
|
|
{
|
|
freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
|
|
dataWin->detail.dataDisplayInfo.regsContentCount);
|
|
dataWin->detail.dataDisplayInfo.regsContentCount = 0;
|
|
}
|
|
if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
|
|
{
|
|
dataWin->detail.dataDisplayInfo.regsContent =
|
|
allocContent (numRegs, DATA_WIN);
|
|
allocatedHere = TRUE;
|
|
}
|
|
|
|
if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
|
|
{
|
|
int i;
|
|
|
|
if (!refreshValuesOnly || allocatedHere)
|
|
{
|
|
dataWin->generic.content = (OpaquePtr) NULL;
|
|
dataWin->generic.contentSize = 0;
|
|
addContentElements (&dataWin->generic, numRegs);
|
|
dataWin->detail.dataDisplayInfo.regsContent =
|
|
(TuiWinContent) dataWin->generic.content;
|
|
dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
|
|
}
|
|
/*
|
|
** Now set the register names and values
|
|
*/
|
|
for (i = startRegNum; (i <= endRegNum); i++)
|
|
{
|
|
TuiGenWinInfoPtr dataItemWin;
|
|
|
|
dataItemWin = &dataWin->detail.dataDisplayInfo.
|
|
regsContent[i - startRegNum]->whichElement.dataWindow;
|
|
_tuiSetRegisterElement (
|
|
i,
|
|
frame,
|
|
&((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
|
|
!allocatedHere && refreshValuesOnly);
|
|
}
|
|
dataWin->detail.dataDisplayInfo.regsColumnCount =
|
|
tuiCalculateRegsColumnCount (dpyType);
|
|
#ifdef LATER
|
|
if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
|
|
{
|
|
/* delete all the windows? */
|
|
/* realloc content equal to dataContentCount + regsContentCount */
|
|
/* append dataWin->detail.dataDisplayInfo.dataContent to content */
|
|
}
|
|
#endif
|
|
dataWin->generic.contentSize =
|
|
dataWin->detail.dataDisplayInfo.regsContentCount +
|
|
dataWin->detail.dataDisplayInfo.dataContentCount;
|
|
ret = TUI_SUCCESS;
|
|
}
|
|
|
|
return ret;
|
|
} /* _tuiSetRegsContent */
|
|
|
|
|
|
/*
|
|
** _tuiDisplayRegister().
|
|
** Function to display a register in a window. If hilite is TRUE,
|
|
** than the value will be displayed in reverse video
|
|
*/
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiDisplayRegister (
|
|
int regNum,
|
|
TuiGenWinInfoPtr winInfo, /* the data item window */
|
|
enum precision_type precision)
|
|
#else
|
|
_tuiDisplayRegister (regNum, winInfo, precision)
|
|
int regNum;
|
|
TuiGenWinInfoPtr winInfo; /* the data item window */
|
|
enum precision_type precision;
|
|
#endif
|
|
{
|
|
if (winInfo->handle != (WINDOW *) NULL)
|
|
{
|
|
char buf[100];
|
|
int valueCharsWide, labelWidth;
|
|
TuiDataElementPtr dataElementPtr = &((TuiWinContent)
|
|
winInfo->content)[0]->whichElement.data;
|
|
|
|
if (IS_64BIT ||
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
|
|
{
|
|
valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
|
|
labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
|
|
}
|
|
else
|
|
{
|
|
if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
|
|
TUI_SFLOAT_REGS)
|
|
{
|
|
valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
|
|
labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
|
|
}
|
|
else
|
|
{
|
|
valueCharsWide = SINGLE_VALUE_WIDTH;
|
|
labelWidth = SINGLE_LABEL_WIDTH;
|
|
}
|
|
}
|
|
|
|
buf[0] = (char) 0;
|
|
_tuiRegisterFormat (buf,
|
|
valueCharsWide + labelWidth,
|
|
regNum,
|
|
dataElementPtr,
|
|
precision);
|
|
if (dataElementPtr->highlight)
|
|
wstandout (winInfo->handle);
|
|
|
|
werase (winInfo->handle);
|
|
wmove (winInfo->handle, 0, 0);
|
|
waddstr (winInfo->handle, buf);
|
|
|
|
if (dataElementPtr->highlight)
|
|
wstandend (winInfo->handle);
|
|
tuiRefreshWin (winInfo);
|
|
}
|
|
return;
|
|
} /* _tuiDisplayRegister */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tui_vShowRegisters_commandSupport (
|
|
va_list args)
|
|
#else
|
|
_tui_vShowRegisters_commandSupport (args)
|
|
va_list args;
|
|
#endif
|
|
{
|
|
TuiRegisterDisplayType dpyType = va_arg (args, TuiRegisterDisplayType);
|
|
|
|
if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
|
|
{ /* Data window already displayed, show the registers */
|
|
if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
|
|
tuiShowRegisters (dpyType);
|
|
}
|
|
else
|
|
(tuiLayoutDef ())->regsDisplayType = dpyType;
|
|
|
|
return;
|
|
} /* _tui_vShowRegisters_commandSupport */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiShowFloat_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiShowFloat_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
|
|
(dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
|
|
dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
|
|
tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
|
|
(tuiLayoutDef ())->floatRegsDisplayType);
|
|
|
|
return;
|
|
} /* _tuiShowFloat_command */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiShowGeneral_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiShowGeneral_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
|
|
TUI_GENERAL_REGS);
|
|
|
|
return;
|
|
} /* _tuiShowGeneral_command */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiShowSpecial_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiShowSpecial_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
|
|
TUI_SPECIAL_REGS);
|
|
|
|
return;
|
|
} /* _tuiShowSpecial_command */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiToggleFloatRegs_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiToggleFloatRegs_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
|
|
tuiDo ((TuiOpaqueFuncPtr) tuiToggleFloatRegs);
|
|
else
|
|
{
|
|
TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
|
|
|
|
if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
|
|
layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
|
|
else
|
|
layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
|
|
}
|
|
|
|
|
|
return;
|
|
} /* _tuiToggleFloatRegs_command */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiScrollRegsForward_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiScrollRegsForward_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, FORWARD_SCROLL, dataWin, 1);
|
|
|
|
return;
|
|
} /* _tuiScrollRegsForward_command */
|
|
|
|
|
|
static void
|
|
#ifdef __STDC__
|
|
_tuiScrollRegsBackward_command (
|
|
char *arg,
|
|
int fromTTY)
|
|
#else
|
|
_tuiScrollRegsBackward_command (arg, fromTTY)
|
|
char *arg;
|
|
int fromTTY;
|
|
#endif
|
|
{
|
|
tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, BACKWARD_SCROLL, dataWin, 1);
|
|
|
|
return;
|
|
} /* _tuiScrollRegsBackward_command */
|