| Index: test/mjsunit/codegen-coverage.js
|
| diff --git a/test/mjsunit/codegen-coverage.js b/test/mjsunit/codegen-coverage.js
|
| index d5e7769d712cc651381afcc6905d0eba074fdcc2..42c371ba26dccdb3b24da896a6146bf836279d66 100644
|
| --- a/test/mjsunit/codegen-coverage.js
|
| +++ b/test/mjsunit/codegen-coverage.js
|
| @@ -25,64 +25,110 @@
|
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| -// Test the paths in the code generator where values in specific
|
| -// registers get moved around so that the shift operation can use
|
| -// register ECX on ia32 for the shift amount. Other codegen coverage
|
| -// tests should go here too.
|
| -
|
| -
|
| +// Flags: --nofull-compiler --nofast-compiler
|
|
|
| +// Test paths in the code generator where values in specific registers
|
| +// get moved around.
|
| function identity(x) {
|
| return x;
|
| }
|
|
|
| function cover_codegen_paths() {
|
| var x = 1;
|
| - var a; // Register EAX
|
| - var b; // Register EBX
|
| - var c; // Register ECX
|
| - var d; // Register EDX
|
| - // Register ESI is already used.
|
| - var di; // Register EDI
|
| +
|
| + // This test depends on the fixed order of register allocation. We try to
|
| + // get values in specific registers (ia32, x64):
|
| + var a; // Register eax, rax.
|
| + var b; // Register ebx, rbx.
|
| + var c; // Register ecx, rcx.
|
| + var d; // Register edx, rdx.
|
| + var di; // Register edi, rdi.
|
|
|
| while (x == 1) {
|
| + // The call will spill registers and leave x in {eax,rax}.
|
| x = identity(1);
|
| + // The add will spill x and reuse {eax,rax} for the result.
|
| a = x + 1;
|
| + // A fresh register {ebx,rbx} will be allocated for x, then reused for
|
| + // the result.
|
| + b = x + 1;
|
| + // Et cetera.
|
| c = x + 1;
|
| d = x + 1;
|
| - b = x + 1;
|
| di = x + 1;
|
| // Locals are in the corresponding registers here.
|
| - assertEquals(c << a, 8);
|
| + assertEquals(8, c << a);
|
|
|
| x = identity(1);
|
| a = x + 1;
|
| + b = x + 1;
|
| c = x + 1;
|
| d = x + 1;
|
| - b = x + 1;
|
| di = x + 1;
|
| - // Locals are in the corresponding registers here.
|
| - assertEquals(a << c, 8);
|
| + assertEquals(8, a << c);
|
|
|
| x = identity(1);
|
| a = x + 1;
|
| + b = x + 1;
|
| c = x + 1;
|
| d = x + 1;
|
| - b = x + 1;
|
| di = x + 1;
|
| - // Locals are in the corresponding registers here.
|
| c = 0; // Free register ecx.
|
| - assertEquals(a << d, 8);
|
| + assertEquals(8, a << d);
|
|
|
| x = identity(1);
|
| a = x + 1;
|
| + b = x + 1;
|
| c = x + 1;
|
| d = x + 1;
|
| - b = x + 1;
|
| di = x + 1;
|
| - // Locals are in the corresponding registers here.
|
| b = 0; // Free register ebx.
|
| - assertEquals(a << d, 8);
|
| + assertEquals(8, a << d);
|
| +
|
| + // Test the non-commutative subtraction operation with a smi on the
|
| + // left, all available registers on the right, and a non-smi result.
|
| + x = identity(-1073741824); // Least (31-bit) smi.
|
| + a = x + 1; // Still a smi, the greatest smi negated.
|
| + b = x + 1;
|
| + c = x + 1;
|
| + d = x + 1;
|
| + di = x + 1;
|
| + // Subtraction should overflow the 31-bit smi range. The result
|
| + // (1073741824) is outside the 31-bit smi range so it doesn't hit the
|
| + // "unsafe smi" code that spills a register.
|
| + assertEquals(1073741824, 1 - a);
|
| +
|
| + x = identity(-1073741824);
|
| + a = x + 1;
|
| + b = x + 1;
|
| + c = x + 1;
|
| + d = x + 1;
|
| + di = x + 1;
|
| + assertEquals(1073741824, 1 - b);
|
| +
|
| + x = identity(-1073741824);
|
| + a = x + 1;
|
| + b = x + 1;
|
| + c = x + 1;
|
| + d = x + 1;
|
| + di = x + 1;
|
| + assertEquals(1073741824, 1 - c);
|
| +
|
| + x = identity(-1073741824);
|
| + a = x + 1;
|
| + b = x + 1;
|
| + c = x + 1;
|
| + d = x + 1;
|
| + di = x + 1;
|
| + assertEquals(1073741824, 1 - d);
|
| +
|
| + x = identity(-1073741824);
|
| + a = x + 1;
|
| + b = x + 1;
|
| + c = x + 1;
|
| + d = x + 1;
|
| + di = x + 1;
|
| + assertEquals(1073741824, 1 - di);
|
|
|
| x = 3;
|
| }
|
|
|