blob: cd538635d6edef9032545b9e8ffca59a983c34b7 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// 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
Andrei Popescu402d9372010-02-26 13:31:12 +000028// Test paths in the code generator where values in specific registers
29// get moved around.
Steve Blocka7e24c12009-10-30 11:49:00 +000030function identity(x) {
31 return x;
32}
33
Steve Block6ded16b2010-05-10 14:33:55 +010034function 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
Steve Blocka7e24c12009-10-30 11:49:00 +000041function cover_codegen_paths() {
42 var x = 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000043
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.
Steve Blocka7e24c12009-10-30 11:49:00 +000051
52 while (x == 1) {
Andrei Popescu402d9372010-02-26 13:31:12 +000053 // The call will spill registers and leave x in {eax,rax}.
Steve Blocka7e24c12009-10-30 11:49:00 +000054 x = identity(1);
Andrei Popescu402d9372010-02-26 13:31:12 +000055 // The add will spill x and reuse {eax,rax} for the result.
Steve Blocka7e24c12009-10-30 11:49:00 +000056 a = x + 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000057 // A fresh register {ebx,rbx} will be allocated for x, then reused for
58 // the result.
59 b = x + 1;
60 // Et cetera.
Steve Blocka7e24c12009-10-30 11:49:00 +000061 c = x + 1;
62 d = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000063 di = x + 1;
64 // Locals are in the corresponding registers here.
Andrei Popescu402d9372010-02-26 13:31:12 +000065 assertEquals(8, c << a);
Steve Blocka7e24c12009-10-30 11:49:00 +000066
67 x = identity(1);
68 a = x + 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000069 b = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000070 c = x + 1;
71 d = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000072 di = x + 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000073 assertEquals(8, a << c);
Steve Blocka7e24c12009-10-30 11:49:00 +000074
75 x = identity(1);
76 a = x + 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000077 b = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000078 c = x + 1;
79 d = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000080 di = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000081 c = 0; // Free register ecx.
Andrei Popescu402d9372010-02-26 13:31:12 +000082 assertEquals(8, a << d);
Steve Blocka7e24c12009-10-30 11:49:00 +000083
84 x = identity(1);
85 a = x + 1;
Andrei Popescu402d9372010-02-26 13:31:12 +000086 b = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000087 c = x + 1;
88 d = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000089 di = x + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +000090 b = 0; // Free register ebx.
Andrei Popescu402d9372010-02-26 13:31:12 +000091 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);
Steve Blocka7e24c12009-10-30 11:49:00 +0000137
138 x = 3;
Steve Block6ded16b2010-05-10 14:33:55 +0100139 var w = { };
140 lookup(w, x);
141 lookup(w, x);
142 lookup(w, x);
143
144 x = 3; // Terminate while loop.
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 }
146}
147
148cover_codegen_paths();