forked from OSchip/llvm-project
X86: Change FTAG register size in FXSAVE structure
Summary: - Changed from 16 bits to 8 bits for Intel Architecture -- FXSAVE structure now conforms with the layout of FXSAVE area specified by IA Architecture Software Developer Manual - Modified Linux and FreeBSD specific files to support this change -- MacOSX already uses 8 bits for ftag register - Modified TestRegisters.py and a.cpp: -- Change allows 8 bit comparison of ftag values -- Change resolves Bug 24733: Removed XFAIL for Clang as the test works and passes for Clang compiler as well -- Change provides a Generic/Better way of testing Bug 24457 and Bug 25050 by using 'int3' inline assembly in inferior Signed-off-by: Abhishek Aggarwal <abhishek.a.aggarwal@intel.com> Reviewers: ovyalov, jingham, clayborg Subscribers: tfiala, emaste Differential Revision: http://reviews.llvm.org/D13587 llvm-svn: 250022
This commit is contained in:
parent
c3741ec8d3
commit
b352a1c88f
|
@ -268,6 +268,9 @@ RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_
|
|||
uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 1:
|
||||
value.SetUInt8(*(uint8_t *)src);
|
||||
return true;
|
||||
case 2:
|
||||
value.SetUInt16(*(uint16_t *)src);
|
||||
return true;
|
||||
|
@ -329,6 +332,9 @@ RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg
|
|||
uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 1:
|
||||
*(uint8_t *)dst = value.GetAsUInt8();
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t *)dst = value.GetAsUInt16();
|
||||
break;
|
||||
|
|
|
@ -575,6 +575,9 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
|
|||
uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 1:
|
||||
reg_value.SetUInt8(*(uint8_t *)src);
|
||||
break;
|
||||
case 2:
|
||||
reg_value.SetUInt16(*(uint16_t *)src);
|
||||
break;
|
||||
|
@ -644,6 +647,9 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
|
|||
uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 1:
|
||||
*(uint8_t *)dst = reg_value.GetAsUInt8();
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t *)dst = reg_value.GetAsUInt16();
|
||||
break;
|
||||
|
|
|
@ -38,7 +38,8 @@ struct FPR_i386
|
|||
{
|
||||
uint16_t fctrl; // FPU Control Word (fcw)
|
||||
uint16_t fstat; // FPU Status Word (fsw)
|
||||
uint16_t ftag; // FPU Tag Word (ftw)
|
||||
uint8_t ftag; // FPU Tag Word (ftw)
|
||||
uint8_t reserved_1; // Reserved
|
||||
uint16_t fop; // Last Instruction Opcode (fop)
|
||||
union
|
||||
{
|
||||
|
|
|
@ -244,7 +244,8 @@ struct FXSAVE
|
|||
{
|
||||
uint16_t fctrl; // FPU Control Word (fcw)
|
||||
uint16_t fstat; // FPU Status Word (fsw)
|
||||
uint16_t ftag; // FPU Tag Word (ftw)
|
||||
uint8_t ftag; // FPU Tag Word (ftw)
|
||||
uint8_t reserved_1; // Reserved
|
||||
uint16_t fop; // Last Instruction Opcode (fop)
|
||||
union
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ class RegisterCommandsTestCase(TestBase):
|
|||
self.fp_register_write()
|
||||
|
||||
@expectedFailureAndroid(archs=["i386"]) # "register read fstat" always return 0xffff
|
||||
@expectedFailureClang("llvm.org/pr24733")
|
||||
@skipIfFreeBSD #llvm.org/pr25057
|
||||
def test_fp_special_purpose_register_read(self):
|
||||
"""Test commands that read fpu special purpose registers."""
|
||||
if not self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
|
||||
|
@ -165,14 +165,21 @@ class RegisterCommandsTestCase(TestBase):
|
|||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
# Find the line number to break inside a.cpp.
|
||||
self.line = line_number('a.cpp', '// Set break point at this line.')
|
||||
# Launch the process and stop.
|
||||
self.expect ("run", PROCESS_STOPPED, substrs = ['stopped'])
|
||||
|
||||
# Set breakpoint
|
||||
lldbutil.run_break_set_by_file_and_line (self, "a.cpp", self.line, num_expected_locations=1, loc_exact=True)
|
||||
|
||||
# Launch the process, and do not stop at the entry point.
|
||||
self.runCmd ("run", RUN_SUCCEEDED)
|
||||
# Check stop reason; Should be either signal SIGTRAP or EXC_BREAKPOINT
|
||||
output = self.res.GetOutput()
|
||||
matched = False
|
||||
substrs = ['stop reason = EXC_BREAKPOINT', 'stop reason = signal SIGTRAP']
|
||||
for str1 in substrs:
|
||||
matched = output.find(str1) != -1
|
||||
with recording(self, False) as sbuf:
|
||||
print >> sbuf, "%s sub string: %s" % ('Expecting', str1)
|
||||
print >> sbuf, "Matched" if matched else "Not Matched"
|
||||
if matched:
|
||||
break
|
||||
self.assertTrue(matched, STOPPED_DUE_TO_SIGNAL)
|
||||
|
||||
process = target.GetProcess()
|
||||
self.assertTrue(process.GetState() == lldb.eStateStopped,
|
||||
|
@ -218,7 +225,7 @@ class RegisterCommandsTestCase(TestBase):
|
|||
|
||||
# Verify ftag and save it to be used for verification in next execution of 'si' command
|
||||
self.expect("register read ftag",
|
||||
substrs = ['ftag' + ' = ', str("0x%0.4x" % (reg_value_ftag_initial | (1<< fstat_top_pointer_initial)))])
|
||||
substrs = ['ftag' + ' = ', str("0x%0.2x" % (reg_value_ftag_initial | (1<< fstat_top_pointer_initial)))])
|
||||
reg_value_ftag_initial = reg_value_ftag_initial | (1<< fstat_top_pointer_initial)
|
||||
|
||||
def fp_register_write(self):
|
||||
|
|
|
@ -13,6 +13,7 @@ return_long_double (long double value)
|
|||
{
|
||||
float a=2, b=4,c=8, d=16, e=32, f=64, k=128, l=256, add=0;
|
||||
__asm__ (
|
||||
"int3 ;"
|
||||
"flds %1 ;"
|
||||
"flds %2 ;"
|
||||
"flds %3 ;"
|
||||
|
|
Loading…
Reference in New Issue