1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#!/usr/bin/env python2.7
#
# Copyright 2017 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
import subprocess
import sys
cflags = '-std=c++11 -Os -fomit-frame-pointer'.split()
hsw = '-mavx2 -mfma -mf16c'.split()
subprocess.check_call(['clang++'] + cflags + hsw +
['-c', 'src/splicer/SkSplicer_stages.cpp'] +
['-o', 'hsw.o'])
aarch64 = [
'--target=aarch64-linux-android',
'--sysroot=' +
'/Users/mtklein/brew/opt/android-ndk/platforms/android-21/arch-arm64',
]
subprocess.check_call(['clang++'] + cflags + aarch64 +
['-c', 'src/splicer/SkSplicer_stages.cpp'] +
['-o', 'aarch64.o'])
print '''/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkSplicer_generated_DEFINED
#define SkSplicer_generated_DEFINED
// This file is generated semi-automatically with this command:
// $ src/splicer/build_stages.py > src/splicer/SkSplicer_generated.h
#if defined(__aarch64__)
'''
for line in subprocess.check_output(['gobjdump', '-d',
'aarch64.o']).split('\n'):
line = line.strip()
if not line or line.startswith('aarch64.o') or line.startswith('Disassembly'):
continue
m = re.match('''................ <(.*)>:''', line)
if m:
print 'static const unsigned int kSplice_' + m.group(1) + '[] = {'
continue
_, code, inst, args = line.split('\t')
code = code.strip()
# b done, where done has not yet been filled in by the linker.
if code == '14000000':
print '};'
continue
print ' ', '0x'+code+',' + ' // ' + inst + ' ' + args
print '''
#else
'''
# TODO: port this to gobjdump too
for line in subprocess.check_output(['otool', '-tvj', 'hsw.o']).split('\n'):
line = line.strip()
if line == '' or line == 'hsw.o:' or line == '(__TEXT,__text) section':
continue
m = re.match('_(.*):', line)
if m:
name = m.group(1)
print 'static const unsigned char kSplice_' + m.group(1) + '[] = {'
continue
# Skip the leading 16 byte address and a tab,
# leaving the code, instruction mnemonic, and its arguments.
line = line[17:]
columns = line.split('\t')
code = columns[0].strip()
inst = columns[1]
args = columns[2:]
# We can't splice code that uses rip relative addressing.
for arg in args:
assert 'rip' not in arg
# jmp done, the end of each stage (the address of done is not yet filled in)
if code == 'e9 00 00 00 00':
print '};'
continue
sys.stdout.write(' ')
_bytes = code.split(' ')
# This is the meat of things: copy the code to a C unsigned char array.
for byte in _bytes:
sys.stdout.write('0x' + byte + ',')
# From here on we're just making the generated file readable and pretty.
sys.stdout.write(' ' * (44 - 5*len(_bytes)))
sys.stdout.write('// ' + inst)
if args:
sys.stdout.write(' ' * (13 - len(inst)))
sys.stdout.write(' '.join(args))
sys.stdout.write('\n')
print '''
#endif
'''
print '''#endif//SkSplicer_generated_DEFINED'''
|