1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package config
16
17import (
18	"fmt"
19	"strings"
20
21	"android/soong/android"
22)
23
24var (
25	armToolchainCflags = []string{
26		"-msoft-float",
27	}
28
29	armCflags = []string{
30		"-fomit-frame-pointer",
31		// Revert this after b/322359235 is fixed
32		"-mllvm", "-enable-shrink-wrap=false",
33	}
34
35	armCppflags = []string{
36		// Revert this after b/322359235 is fixed
37		"-mllvm", "-enable-shrink-wrap=false",
38	}
39
40	armLdflags = []string{
41		"-Wl,-m,armelf",
42		// Revert this after b/322359235 is fixed
43		"-Wl,-mllvm", "-Wl,-enable-shrink-wrap=false",
44	}
45
46	armLldflags = armLdflags
47
48	armFixCortexA8LdFlags = []string{"-Wl,--fix-cortex-a8"}
49
50	armNoFixCortexA8LdFlags = []string{"-Wl,--no-fix-cortex-a8"}
51
52	armArmCflags = []string{}
53
54	armThumbCflags = []string{
55		"-mthumb",
56		"-Os",
57	}
58
59	armArchVariantCflags = map[string][]string{
60		"armv7-a": []string{
61			"-march=armv7-a",
62			"-mfloat-abi=softfp",
63			"-mfpu=vfpv3-d16",
64		},
65		"armv7-a-neon": []string{
66			"-march=armv7-a",
67			"-mfloat-abi=softfp",
68			"-mfpu=neon",
69		},
70		"armv8-a": []string{
71			"-march=armv8-a",
72			"-mfloat-abi=softfp",
73			"-mfpu=neon-fp-armv8",
74		},
75		"armv8-2a": []string{
76			"-march=armv8.2-a",
77			"-mfloat-abi=softfp",
78			"-mfpu=neon-fp-armv8",
79		},
80	}
81
82	armCpuVariantCflags = map[string][]string{
83		"cortex-a7": []string{
84			"-mcpu=cortex-a7",
85			"-mfpu=neon-vfpv4",
86			// Fake an ARM compiler flag as these processors support LPAE which clang
87			// don't advertise.
88			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
89			// better solution comes around. See Bug 27340895
90			"-D__ARM_FEATURE_LPAE=1",
91		},
92		"cortex-a8": []string{
93			"-mcpu=cortex-a8",
94		},
95		"cortex-a15": []string{
96			"-mcpu=cortex-a15",
97			"-mfpu=neon-vfpv4",
98			// Fake an ARM compiler flag as these processors support LPAE which clang
99			// don't advertise.
100			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
101			// better solution comes around. See Bug 27340895
102			"-D__ARM_FEATURE_LPAE=1",
103		},
104		"cortex-a32": []string{
105			"-mcpu=cortex-a32",
106			"-mfpu=neon-vfpv4",
107			// Fake an ARM compiler flag as these processors support LPAE which clang
108			// don't advertise.
109			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
110			// better solution comes around. See Bug 27340895
111			"-D__ARM_FEATURE_LPAE=1",
112		},
113		"cortex-a53": []string{
114			"-mcpu=cortex-a53",
115			"-mfpu=neon-fp-armv8",
116			// Fake an ARM compiler flag as these processors support LPAE which clang
117			// don't advertise.
118			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
119			// better solution comes around. See Bug 27340895
120			"-D__ARM_FEATURE_LPAE=1",
121		},
122		"cortex-a55": []string{
123			"-mcpu=cortex-a55",
124			"-mfpu=neon-fp-armv8",
125			// Fake an ARM compiler flag as these processors support LPAE which clang
126			// don't advertise.
127			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
128			// better solution comes around. See Bug 27340895
129			"-D__ARM_FEATURE_LPAE=1",
130		},
131		"cortex-a75": []string{
132			"-mcpu=cortex-a55",
133			"-mfpu=neon-fp-armv8",
134			// Fake an ARM compiler flag as these processors support LPAE which clang
135			// don't advertise.
136			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
137			// better solution comes around. See Bug 27340895
138			"-D__ARM_FEATURE_LPAE=1",
139		},
140		"cortex-a76": []string{
141			"-mcpu=cortex-a55",
142			"-mfpu=neon-fp-armv8",
143			// Fake an ARM compiler flag as these processors support LPAE which clang
144			// don't advertise.
145			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
146			// better solution comes around. See Bug 27340895
147			"-D__ARM_FEATURE_LPAE=1",
148		},
149		"krait": []string{
150			"-mcpu=krait",
151			"-mfpu=neon-vfpv4",
152			// Fake an ARM compiler flag as these processors support LPAE which clang
153			// don't advertise.
154			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
155			// better solution comes around. See Bug 27340895
156			"-D__ARM_FEATURE_LPAE=1",
157		},
158		"kryo": []string{
159			// Use cortex-a53 because the GNU assembler doesn't recognize -mcpu=kryo
160			// even though clang does.
161			"-mcpu=cortex-a53",
162			"-mfpu=neon-fp-armv8",
163			// Fake an ARM compiler flag as these processors support LPAE which clang
164			// don't advertise.
165			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
166			// better solution comes around. See Bug 27340895
167			"-D__ARM_FEATURE_LPAE=1",
168		},
169		"kryo385": []string{
170			// Use cortex-a53 because kryo385 is not supported in clang.
171			"-mcpu=cortex-a53",
172			// Fake an ARM compiler flag as these processors support LPAE which clang
173			// don't advertise.
174			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
175			// better solution comes around. See Bug 27340895
176			"-D__ARM_FEATURE_LPAE=1",
177		},
178	}
179)
180
181const (
182	name        = "arm"
183	ndkTriple   = "arm-linux-androideabi"
184	clangTriple = "armv7a-linux-androideabi"
185)
186
187func init() {
188	pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " "))
189	pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " "))
190
191	pctx.StaticVariable("ArmFixCortexA8LdFlags", strings.Join(armFixCortexA8LdFlags, " "))
192	pctx.StaticVariable("ArmNoFixCortexA8LdFlags", strings.Join(armNoFixCortexA8LdFlags, " "))
193
194	// Clang cflags
195	pctx.StaticVariable("ArmToolchainCflags", strings.Join(armToolchainCflags, " "))
196	pctx.StaticVariable("ArmCflags", strings.Join(armCflags, " "))
197	pctx.StaticVariable("ArmCppflags", strings.Join(armCppflags, " "))
198
199	// Clang ARM vs. Thumb instruction set cflags
200	pctx.StaticVariable("ArmArmCflags", strings.Join(armArmCflags, " "))
201	pctx.StaticVariable("ArmThumbCflags", strings.Join(armThumbCflags, " "))
202
203	// Clang arch variant cflags
204	pctx.StaticVariable("ArmArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
205	pctx.StaticVariable("ArmArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
206	pctx.StaticVariable("ArmArmv8ACflags", strings.Join(armArchVariantCflags["armv8-a"], " "))
207	pctx.StaticVariable("ArmArmv82ACflags", strings.Join(armArchVariantCflags["armv8-2a"], " "))
208
209	// Clang cpu variant cflags
210	pctx.StaticVariable("ArmGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
211	pctx.StaticVariable("ArmCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
212	pctx.StaticVariable("ArmCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
213	pctx.StaticVariable("ArmCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
214	pctx.StaticVariable("ArmCortexA32Cflags", strings.Join(armCpuVariantCflags["cortex-a32"], " "))
215	pctx.StaticVariable("ArmCortexA53Cflags", strings.Join(armCpuVariantCflags["cortex-a53"], " "))
216	pctx.StaticVariable("ArmCortexA55Cflags", strings.Join(armCpuVariantCflags["cortex-a55"], " "))
217	pctx.StaticVariable("ArmKraitCflags", strings.Join(armCpuVariantCflags["krait"], " "))
218	pctx.StaticVariable("ArmKryoCflags", strings.Join(armCpuVariantCflags["kryo"], " "))
219}
220
221var (
222	armArchVariantCflagsVar = map[string]string{
223		"armv7-a":      "${config.ArmArmv7ACflags}",
224		"armv7-a-neon": "${config.ArmArmv7ANeonCflags}",
225		"armv8-a":      "${config.ArmArmv8ACflags}",
226		"armv8-2a":     "${config.ArmArmv82ACflags}",
227	}
228
229	armCpuVariantCflagsVar = map[string]string{
230		"":               "${config.ArmGenericCflags}",
231		"cortex-a7":      "${config.ArmCortexA7Cflags}",
232		"cortex-a8":      "${config.ArmCortexA8Cflags}",
233		"cortex-a9":      "${config.ArmGenericCflags}",
234		"cortex-a15":     "${config.ArmCortexA15Cflags}",
235		"cortex-a32":     "${config.ArmCortexA32Cflags}",
236		"cortex-a53":     "${config.ArmCortexA53Cflags}",
237		"cortex-a53.a57": "${config.ArmCortexA53Cflags}",
238		"cortex-a55":     "${config.ArmCortexA55Cflags}",
239		"cortex-a72":     "${config.ArmCortexA53Cflags}",
240		"cortex-a73":     "${config.ArmCortexA53Cflags}",
241		"cortex-a75":     "${config.ArmCortexA55Cflags}",
242		"cortex-a76":     "${config.ArmCortexA55Cflags}",
243		"krait":          "${config.ArmKraitCflags}",
244		"kryo":           "${config.ArmKryoCflags}",
245		"kryo385":        "${config.ArmCortexA53Cflags}",
246		"exynos-m1":      "${config.ArmCortexA53Cflags}",
247		"exynos-m2":      "${config.ArmCortexA53Cflags}",
248	}
249)
250
251type toolchainArm struct {
252	toolchainBionic
253	toolchain32Bit
254	ldflags         string
255	lldflags        string
256	toolchainCflags string
257}
258
259func (t *toolchainArm) Name() string {
260	return name
261}
262
263func (t *toolchainArm) IncludeFlags() string {
264	return ""
265}
266
267func (t *toolchainArm) ClangTriple() string {
268	// http://b/72619014 work around llvm LTO bug.
269	return clangTriple
270}
271
272func (t *toolchainArm) ndkTriple() string {
273	// Use current NDK include path, while ClangTriple is changed.
274	return ndkTriple
275}
276
277func (t *toolchainArm) ToolchainCflags() string {
278	return t.toolchainCflags
279}
280
281func (t *toolchainArm) Cflags() string {
282	return "${config.ArmCflags}"
283}
284
285func (t *toolchainArm) Cppflags() string {
286	return "${config.ArmCppflags}"
287}
288
289func (t *toolchainArm) Ldflags() string {
290	return t.ldflags
291}
292
293func (t *toolchainArm) Lldflags() string {
294	return t.lldflags // TODO: handle V8 cases
295}
296
297func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
298	switch isa {
299	case "arm":
300		return "${config.ArmArmCflags}", nil
301	case "thumb", "":
302		return "${config.ArmThumbCflags}", nil
303	default:
304		return t.toolchainBase.InstructionSetFlags(isa)
305	}
306}
307
308func (toolchainArm) LibclangRuntimeLibraryArch() string {
309	return name
310}
311
312func armToolchainFactory(arch android.Arch) Toolchain {
313	var fixCortexA8 string
314	toolchainCflags := make([]string, 2, 3)
315
316	toolchainCflags[0] = "${config.ArmToolchainCflags}"
317	toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
318
319	toolchainCflags = append(toolchainCflags,
320		variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant))
321
322	switch arch.ArchVariant {
323	case "armv7-a-neon":
324		switch arch.CpuVariant {
325		case "cortex-a8", "":
326			// Generic ARM might be a Cortex A8 -- better safe than sorry
327			fixCortexA8 = "${config.ArmFixCortexA8LdFlags}"
328		default:
329			fixCortexA8 = "${config.ArmNoFixCortexA8LdFlags}"
330		}
331	case "armv7-a":
332		fixCortexA8 = "${config.ArmFixCortexA8LdFlags}"
333	case "armv8-a", "armv8-2a":
334		// Nothing extra for armv8-a/armv8-2a
335	default:
336		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
337	}
338
339	return &toolchainArm{
340		ldflags: strings.Join([]string{
341			"${config.ArmLdflags}",
342			fixCortexA8,
343		}, " "),
344		lldflags:        "${config.ArmLldflags}",
345		toolchainCflags: strings.Join(toolchainCflags, " "),
346	}
347}
348
349func init() {
350	registerToolchainFactory(android.Android, android.Arm, armToolchainFactory)
351}
352