Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / toolchain / pic_constant_lib.c
1 /*
2  * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include "native_client/tests/toolchain/pic_constant_lib.h"
8
9 /*
10  * This is a regression test for:
11  *     https://code.google.com/p/nativeclient/issues/detail?id=3549
12  * The compiler bug affected -fPIC compilations only.
13  */
14
15 static const char *h(const char *s, size_t n) {
16   return n != 0 ? g(s, n) : s;
17 }
18
19 static const char *f(const char *s) {
20   return h(s, g(s, 0) - s);
21 }
22
23 const char *i(void) {
24   return f("string constant");
25 }
26
27
28 /*
29  * This is a regression test for:
30  *     https://code.google.com/p/nativeclient/issues/detail?id=3598
31  * x86_64-nacl-gcc with optimization and -fPIC had a bug wherein it would
32  * attempt to generate an LEA instruction pattern using the full base
33  * register + index register + displacement addressing mode in compiling
34  * the trivial "sprint_nybble" function below, but then get an internal
35  * compiler error (and crash) because a PIC reference to a static variable
36  * is not usable as a displacement in an LEA instruction.
37  */
38
39 static const char nybble[16][5]={
40   "0000", "0001", "0010", "0011",
41   "0100", "0101", "0110", "0111",
42   "1000", "1001", "1010", "1011",
43   "1100", "1101", "1110", "1111"
44 };
45
46 /*
47  * The semantics for -fPIC require that a global function (with
48  * default visibility) be called via the PLT, so making this global
49  * truly ensures that main's call will not be inlined and so will be
50  * compiled as the general-case version that elicits the code
51  * pattern necessary to tickle the compiler bug.  Conversely, with
52  * static and __attribute__((noinline)), while gcc-4.4 does what we
53  * want, gcc-4.8 doesn't inline per se, but replaces the standalone
54  * general-case function with a standalone (obeying noinline!)
55  * fully constant-propagated-and-folded variant that doesn't even do
56  * the table lookup at all!
57  */
58 void sprint_nybble(int i, char s[4]) {
59   const char *c = nybble[i & 0x0f];
60   s[0] = c[0];
61   s[1] = c[1];
62   s[2] = c[2];
63   s[3] = c[3];
64 }