1// Copyright 2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Test paths in the code generator where values in specific registers
29// get moved around.
30function identity(x) {
31  return x;
32}
33
34function lookup(w, a) {
35  // This function tests a code path in the generation of a keyed load IC
36  // where the key and the value are both in the same register.
37  a = a;
38  w[a] = a;
39}
40
41function cover_codegen_paths() {
42  var x = 1;
43
44  // This test depends on the fixed order of register allocation.  We try to
45  // get values in specific registers (ia32, x64):
46  var a;   // Register eax, rax.
47  var b;   // Register ebx, rbx.
48  var c;   // Register ecx, rcx.
49  var d;   // Register edx, rdx.
50  var di;  // Register edi, rdi.
51
52  while (x == 1) {
53    // The call will spill registers and leave x in {eax,rax}.
54    x = identity(1);
55    // The add will spill x and reuse {eax,rax} for the result.
56    a = x + 1;
57    // A fresh register {ebx,rbx} will be allocated for x, then reused for
58    // the result.
59    b = x + 1;
60    // Et cetera.
61    c = x + 1;
62    d = x + 1;
63    di = x + 1;
64    // Locals are in the corresponding registers here.
65    assertEquals(8, c << a);
66
67    x = identity(1);
68    a = x + 1;
69    b = x + 1;
70    c = x + 1;
71    d = x + 1;
72    di = x + 1;
73    assertEquals(8, a << c);
74
75    x = identity(1);
76    a = x + 1;
77    b = x + 1;
78    c = x + 1;
79    d = x + 1;
80    di = x + 1;
81    c = 0; // Free register ecx.
82    assertEquals(8, a << d);
83
84    x = identity(1);
85    a = x + 1;
86    b = x + 1;
87    c = x + 1;
88    d = x + 1;
89    di = x + 1;
90    b = 0; // Free register ebx.
91    assertEquals(8, a << d);
92
93    // Test the non-commutative subtraction operation with a smi on the
94    // left, all available registers on the right, and a non-smi result.
95    x = identity(-1073741824);  // Least (31-bit) smi.
96    a = x + 1;  // Still a smi, the greatest smi negated.
97    b = x + 1;
98    c = x + 1;
99    d = x + 1;
100    di = x + 1;
101    // Subtraction should overflow the 31-bit smi range.  The result
102    // (1073741824) is outside the 31-bit smi range so it doesn't hit the
103    // "unsafe smi" code that spills a register.
104    assertEquals(1073741824, 1 - a);
105
106    x = identity(-1073741824);
107    a = x + 1;
108    b = x + 1;
109    c = x + 1;
110    d = x + 1;
111    di = x + 1;
112    assertEquals(1073741824, 1 - b);
113
114    x = identity(-1073741824);
115    a = x + 1;
116    b = x + 1;
117    c = x + 1;
118    d = x + 1;
119    di = x + 1;
120    assertEquals(1073741824, 1 - c);
121
122    x = identity(-1073741824);
123    a = x + 1;
124    b = x + 1;
125    c = x + 1;
126    d = x + 1;
127    di = x + 1;
128    assertEquals(1073741824, 1 - d);
129
130    x = identity(-1073741824);
131    a = x + 1;
132    b = x + 1;
133    c = x + 1;
134    d = x + 1;
135    di = x + 1;
136    assertEquals(1073741824, 1 - di);
137
138    x = 3;
139    var w = { };
140    lookup(w, x);
141    lookup(w, x);
142    lookup(w, x);
143
144    x = 3;  // Terminate while loop.
145  }
146}
147
148cover_codegen_paths();
149