Commit 1d655fce authored by Jason Molenda's avatar Jason Molenda
Browse files

Upstreaming avx512 register support in debugserver. These changes

were originally written by Chris Bieneman, they've undergone a
number of changes since then.

Also including the debugserver bridgeos support, another arm
environment that runs Darwin akin to ios.  These codepaths are
activated when running in a bridgeos environment which we're not
set up to test today.

There's additional (small) lldb changes to handle bridgeos binaries
that still need to be merged up.

Tested on a darwin system with avx512 hardware and without.

<rdar://problem/36424951>
parent 1c86fe88
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ namespace lldb_private {

class RegisterValue {
public:
  enum { kMaxRegisterByteSize = 32u };
  enum { kMaxRegisterByteSize = 64u };

  enum Type {
    eTypeInvalid,
+18 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ import platform
import re
import sys
import tempfile
import subprocess

# Third-party modules
import six
@@ -741,3 +742,20 @@ def skipIfXmlSupportMissing(func):
    fail_value = True # More likely to notice if something goes wrong
    have_xml = xml.GetValueForKey("value").GetBooleanValue(fail_value)
    return unittest2.skipIf(not have_xml, "requires xml support")(func)

# Call sysctl on darwin to see if a specified hardware feature is available on this machine.
def skipUnlessFeature(feature):
    def is_feature_enabled(self):
        if platform.system() == 'Darwin':
            try:
                DEVNULL = open(os.devnull, 'w')
                output = subprocess.check_output(["/usr/sbin/sysctl", feature], stderr=DEVNULL)
                # If 'feature: 1' was output, then this feature is available and
                # the test should not be skipped.
                if re.match('%s: 1\s*' % feature, output):
                    return None
                else:
                    return "%s is not supported on this system." % feature
            except subprocess.CalledProcessError:
                return "%s is not supported on this system." % feature
    return skipTestIfFn(is_feature_enabled)
+5 −3
Original line number Diff line number Diff line
@@ -21,8 +21,9 @@ class TestYMMRegister(TestBase):
    @skipIfiOSSimulator
    @skipIfTargetAndroid()
    @skipIf(archs=no_match(['i386', 'x86_64']))
    @expectedFailureAll(oslist=["linux"], bugnumber="rdar://30523153")
    def test(self):
        self.build()
        self.build(dictionary={"CFLAGS_EXTRAS": "-march=haswell"})
        self.setTearDownCleanup()

        exe = self.getBuildArtifact("a.out")
@@ -56,9 +57,10 @@ class TestYMMRegister(TestBase):
        else:
            register_range = 8
        for i in range(register_range):
            j = i - ((i / 8) * 8)
            self.runCmd("thread step-inst")

            register_byte = (byte_pattern1 | i)
            register_byte = (byte_pattern1 | j)
            pattern = "ymm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 31 + str(hex(register_byte)) + str('}')

@@ -66,7 +68,7 @@ class TestYMMRegister(TestBase):
                "register read ymm" + str(i),
                substrs=[pattern])

            register_byte = (byte_pattern2 | i)
            register_byte = (byte_pattern2 | j)
            pattern = "ymm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 31 + str(hex(register_byte)) + str('}')

+126 −0
Original line number Diff line number Diff line
"""
Test that we correctly read the YMM registers.
"""

from __future__ import print_function


import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class TestYMMRegister(TestBase):
    mydir = TestBase.compute_mydir(__file__)
    NO_DEBUG_INFO_TESTCASE = True

    @skipUnlessDarwin
    @skipIfiOSSimulator
    @skipIf(archs=no_match(['i386', 'x86_64']))
    @debugserver_test
    @skipUnlessFeature('hw.optional.avx512f')
    def test(self):
        self.build(dictionary={"CFLAGS_EXTRAS": "-mavx512f"})
        self.setTearDownCleanup()

        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTarget(exe)

        self.assertTrue(target, VALID_TARGET)

        byte_pattern1 = 0x80
        byte_pattern2 = 0xFF

        # This test is working with assembly instructions; it'll make
        # it easier to debug the console output if the assembly is
        # displayed.
        self.runCmd("settings set stop-disassembly-display always")

        # Launch the process and stop.
        self.expect("run", PROCESS_STOPPED, substrs=['stopped'])

        # 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("%s sub string: %s" % ('Expecting', str1), file=sbuf)
                print("Matched" if matched else "Not Matched", file=sbuf)
            if matched:
                break
        self.assertTrue(matched, STOPPED_DUE_TO_SIGNAL)

        if self.getArchitecture() == 'x86_64':
            register_range = 16
        else:
            register_range = 8
        for i in range(register_range):
            j = i - ((i / 8) * 8)
            self.runCmd("thread step-inst")

            register_byte = (byte_pattern1 | j)
            pattern = "ymm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 31 + str(hex(register_byte)) + str('}')

            self.expect(
                "register read ymm" + str(i),
                substrs=[pattern])

            register_byte = (byte_pattern2 | j)
            pattern = "ymm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 31 + str(hex(register_byte)) + str('}')

            self.runCmd("thread step-inst")
            self.expect(
                "register read ymm" + str(i),
                substrs=[pattern])
        
        self.expect("continue", PROCESS_STOPPED, substrs=['stopped'])

        # 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("%s sub string: %s" % ('Expecting', str1), file=sbuf)
                print("Matched" if matched else "Not Matched", file=sbuf)
            if matched:
                break
        self.assertTrue(matched, STOPPED_DUE_TO_SIGNAL)

        if self.getArchitecture() == 'x86_64':
            register_range = 32
        else:
            register_range = 8
        for i in range(register_range):
            j = i - ((i / 8) * 8)
            self.runCmd("thread step-inst")
            self.runCmd("thread step-inst")

            register_byte = (byte_pattern2 | j)
            pattern = "zmm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 63 + str(hex(register_byte)) + str('}')

            self.expect(
                "register read zmm" + str(i),
                substrs=[pattern])

            register_byte = (byte_pattern2 | j)
            pattern = "zmm" + str(i) + " = " + str('{') + (
                str(hex(register_byte)) + ' ') * 63 + str(hex(register_byte)) + str('}')

            self.runCmd("thread step-inst")
            self.expect(
                "register read zmm" + str(i),
                substrs=[pattern])
+92 −16
Original line number Diff line number Diff line
@@ -9,15 +9,14 @@

void func() {
  unsigned int ymmvalues[16];
  unsigned char val;
  unsigned char i;
  for (i = 0 ; i < 16 ; i++)
  for (int i = 0 ; i < 16 ; i++)
  {
    val = (0x80 | i);
    unsigned char val = (0x80 | i);
    ymmvalues[i] = (val << 24) | (val << 16) | (val << 8) | val;
  }

  unsigned int ymmallones = 0xFFFFFFFF;
#if defined(__AVX__)
  __asm__("int3;"
          "vbroadcastss %1, %%ymm0;"
          "vbroadcastss %0, %%ymm0;"
@@ -36,32 +35,109 @@ void func() {
          "vbroadcastss %8, %%ymm7;"
          "vbroadcastss %0, %%ymm7;"
#if defined(__x86_64__)
          "vbroadcastss %9, %%ymm8;"
          "vbroadcastss %1, %%ymm8;"
          "vbroadcastss %0, %%ymm8;"
          "vbroadcastss %10, %%ymm9;"
          "vbroadcastss %2, %%ymm9;"
          "vbroadcastss %0, %%ymm9;"
          "vbroadcastss %11, %%ymm10;"
          "vbroadcastss %3, %%ymm10;"
          "vbroadcastss %0, %%ymm10;"
          "vbroadcastss %12, %%ymm11;"
          "vbroadcastss %4, %%ymm11;"
          "vbroadcastss %0, %%ymm11;"
          "vbroadcastss %13, %%ymm12;"
          "vbroadcastss %5, %%ymm12;"
          "vbroadcastss %0, %%ymm12;"
          "vbroadcastss %14, %%ymm13;"
          "vbroadcastss %6, %%ymm13;"
          "vbroadcastss %0, %%ymm13;"
          "vbroadcastss %15, %%ymm14;"
          "vbroadcastss %7, %%ymm14;"
          "vbroadcastss %0, %%ymm14;"
          "vbroadcastss %16, %%ymm15;"
          "vbroadcastss %8, %%ymm15;"
          "vbroadcastss %0, %%ymm15;"
#endif
          ::"m"(ymmallones),
          "m"(ymmvalues[0]), "m"(ymmvalues[1]), "m"(ymmvalues[2]), "m"(ymmvalues[3]),
          "m"(ymmvalues[4]), "m"(ymmvalues[5]), "m"(ymmvalues[6]), "m"(ymmvalues[7])
              );
#endif

#if defined(__AVX512F__)
  unsigned int zmmvalues[32];
  for (int i = 0 ; i < 32 ; i++)
  {
    unsigned char val = (0x80 | i);
    zmmvalues[i] = (val << 24) | (val << 16) | (val << 8) | val;
  }

  __asm__("int3;"
          "vbroadcastss %1, %%zmm0;"
          "vbroadcastss %0, %%zmm0;"
          "vbroadcastss %2, %%zmm1;"
          "vbroadcastss %0, %%zmm1;"
          "vbroadcastss %3, %%zmm2;"
          "vbroadcastss %0, %%zmm2;"
          "vbroadcastss %4, %%zmm3;"
          "vbroadcastss %0, %%zmm3;"
          "vbroadcastss %5, %%zmm4;"
          "vbroadcastss %0, %%zmm4;"
          "vbroadcastss %6, %%zmm5;"
          "vbroadcastss %0, %%zmm5;"
          "vbroadcastss %7, %%zmm6;"
          "vbroadcastss %0, %%zmm6;"
          "vbroadcastss %8, %%zmm7;"
          "vbroadcastss %0, %%zmm7;"
#if defined(__x86_64__)
          ,
          "m"(ymmvalues[8]), "m"(ymmvalues[9]), "m"(ymmvalues[10]), "m"(ymmvalues[11]),
          "m"(ymmvalues[12]), "m"(ymmvalues[13]), "m"(ymmvalues[14]), "m"(ymmvalues[15])
          "vbroadcastss %1, %%zmm8;"
          "vbroadcastss %0, %%zmm8;"
          "vbroadcastss %2, %%zmm9;"
          "vbroadcastss %0, %%zmm9;"
          "vbroadcastss %3, %%zmm10;"
          "vbroadcastss %0, %%zmm10;"
          "vbroadcastss %4, %%zmm11;"
          "vbroadcastss %0, %%zmm11;"
          "vbroadcastss %5, %%zmm12;"
          "vbroadcastss %0, %%zmm12;"
          "vbroadcastss %6, %%zmm13;"
          "vbroadcastss %0, %%zmm13;"
          "vbroadcastss %7, %%zmm14;"
          "vbroadcastss %0, %%zmm14;"
          "vbroadcastss %8, %%zmm15;"
          "vbroadcastss %0, %%zmm15;"
          "vbroadcastss %1, %%zmm16;"
          "vbroadcastss %0, %%zmm16;"
          "vbroadcastss %2, %%zmm17;"
          "vbroadcastss %0, %%zmm17;"
          "vbroadcastss %3, %%zmm18;"
          "vbroadcastss %0, %%zmm18;"
          "vbroadcastss %4, %%zmm19;"
          "vbroadcastss %0, %%zmm19;"
          "vbroadcastss %5, %%zmm20;"
          "vbroadcastss %0, %%zmm20;"
          "vbroadcastss %6, %%zmm21;"
          "vbroadcastss %0, %%zmm21;"
          "vbroadcastss %7, %%zmm22;"
          "vbroadcastss %0, %%zmm22;"
          "vbroadcastss %8, %%zmm23;"
          "vbroadcastss %0, %%zmm23;"
          "vbroadcastss %1, %%zmm24;"
          "vbroadcastss %0, %%zmm24;"
          "vbroadcastss %2, %%zmm25;"
          "vbroadcastss %0, %%zmm25;"
          "vbroadcastss %3, %%zmm26;"
          "vbroadcastss %0, %%zmm26;"
          "vbroadcastss %4, %%zmm27;"
          "vbroadcastss %0, %%zmm27;"
          "vbroadcastss %5, %%zmm28;"
          "vbroadcastss %0, %%zmm28;"
          "vbroadcastss %6, %%zmm29;"
          "vbroadcastss %0, %%zmm29;"
          "vbroadcastss %7, %%zmm30;"
          "vbroadcastss %0, %%zmm30;"
          "vbroadcastss %8, %%zmm31;"
          "vbroadcastss %0, %%zmm31;"
#endif
          ::"m"(ymmallones),
          "m"(zmmvalues[0]), "m"(zmmvalues[1]), "m"(zmmvalues[2]), "m"(zmmvalues[3]),
          "m"(zmmvalues[4]), "m"(zmmvalues[5]), "m"(zmmvalues[6]), "m"(zmmvalues[7])
  );
#endif
}

int main(int argc, char const *argv[]) { func(); }
Loading