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:
Abhishek Aggarwal 2015-10-12 09:57:00 +00:00
parent c3741ec8d3
commit b352a1c88f
6 changed files with 33 additions and 11 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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
{

View File

@ -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
{

View File

@ -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):

View File

@ -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 ;"