18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "disassembler.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/simulator-arm.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/assembler-arm-inl.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cctest.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal;
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Define these function prototypes to match JSEntryFunction in execution.cc.
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochtypedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochtypedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Persistent<v8::Context> env;
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeVM() {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (env.IsEmpty()) {
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    env = v8::Context::New();
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm.
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(0) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeVM();
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::HandleScope scope;
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ add(r0, r0, Operand(r1));
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(pc, Operand(lr));
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodeDesc desc;
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assm.GetCode(&desc);
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      desc,
715913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Code::ComputeFlags(Code::STUB),
7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK(code->IsCode());
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::cast(code)->Print();
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ::printf("f() = %d\n", res);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(7, res);
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(1) {
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeVM();
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::HandleScope scope;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label L, C;
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r1, Operand(r0));
929ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  __ mov(r0, Operand(0, RelocInfo::NONE));
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ b(&C);
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ bind(&L);
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ add(r0, r0, Operand(r1));
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ sub(r1, r1, Operand(1));
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ bind(&C);
1009ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  __ teq(r1, Operand(0, RelocInfo::NONE));
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ b(ne, &L);
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(pc, Operand(lr));
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodeDesc desc;
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assm.GetCode(&desc);
10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
1075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      desc,
1085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Code::ComputeFlags(Code::STUB),
10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK(code->IsCode());
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::cast(code)->Print();
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ::printf("f() = %d\n", res);
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(5050, res);
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(2) {
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeVM();
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::HandleScope scope;
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label L, C;
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r1, Operand(r0));
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r0, Operand(1));
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ b(&C);
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ bind(&L);
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mul(r0, r1, r0);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ sub(r1, r1, Operand(1));
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ bind(&C);
1379ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  __ teq(r1, Operand(0, RelocInfo::NONE));
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ b(ne, &L);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(pc, Operand(lr));
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // some relocated stuff here, not executed
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ RecordComment("dead code, just testing relocations");
14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ mov(r0, Operand(FACTORY->true_value()));
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ RecordComment("dead code, just testing immediate operands");
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r0, Operand(-1));
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r0, Operand(0xFF000000));
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r0, Operand(0xF0F0F0F0));
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r0, Operand(0xFFF0FFFF));
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodeDesc desc;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assm.GetCode(&desc);
15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
1535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      desc,
1545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Code::ComputeFlags(Code::STUB),
15544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK(code->IsCode());
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::cast(code)->Print();
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ::printf("f() = %d\n", res);
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(3628800, res);
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(3) {
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeVM();
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::HandleScope scope;
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  typedef struct {
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int i;
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    char c;
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int16_t s;
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } T;
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  T t;
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label L, C;
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(ip, Operand(sp));
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ sub(fp, ip, Operand(4));
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r4, Operand(r0));
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r2, Operand(r0, ASR, 1));
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ add(r0, r2, Operand(r0));
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r2, Operand(r2, LSL, 2));
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ add(r0, r2, Operand(r0));
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ mov(r2, Operand(r2, ASR, 3));
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodeDesc desc;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assm.GetCode(&desc);
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
2015913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      desc,
2025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Code::ComputeFlags(Code::STUB),
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK(code->IsCode());
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::cast(code)->Print();
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  t.i = 100000;
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  t.c = 10;
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  t.s = 1000;
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ::printf("f() = %d\n", res);
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(101010, res);
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(100000/2, t.i);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(10*4, t.c);
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(1000/8, t.s);
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(4) {
222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Test the VFP floating point instructions.
223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  InitializeVM();
224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  v8::HandleScope scope;
225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  typedef struct {
227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    double a;
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    double b;
229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    double c;
23080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    double d;
23180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    double e;
23280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    double f;
2331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    double g;
2341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    double h;
23580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    int i;
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double m;
23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double n;
23880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    float x;
23980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    float y;
240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } T;
241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  T t;
242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Create a function that accepts &t, and loads, manipulates, and stores
24480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // the doubles and floats.
2458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label L, C;
247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
2498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(VFP3)) {
250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CpuFeatures::Scope scope(VFP3);
251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ mov(ip, Operand(sp));
253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ sub(fp, ip, Operand(4));
255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ mov(r4, Operand(r0));
257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vldr(d6, r4, OFFSET_OF(T, a));
258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vldr(d7, r4, OFFSET_OF(T, b));
259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vadd(d5, d6, d7);
260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vstr(d5, r4, OFFSET_OF(T, c));
261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vmov(r2, r3, d5);
263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vmov(d4, r2, r3);
264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ vstr(d4, r4, OFFSET_OF(T, b));
265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
26680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Load t.x and t.y, switch values, and store back to the struct.
26780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vldr(s0, r4, OFFSET_OF(T, x));
26880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vldr(s31, r4, OFFSET_OF(T, y));
26980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(s16, s0);
27080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(s0, s31);
27180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(s31, s16);
27280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(s0, r4, OFFSET_OF(T, x));
27380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(s31, r4, OFFSET_OF(T, y));
27480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
27580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Move a literal into a register that can be encoded in the instruction.
27680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(d4, 1.0);
27780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(d4, r4, OFFSET_OF(T, e));
27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
27980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Move a literal into a register that requires 64 bits to encode.
28080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // 0x3ff0000010000000 = 1.000000059604644775390625
28180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(d4, 1.000000059604644775390625);
28280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(d4, r4, OFFSET_OF(T, d));
28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Convert from floating point to integer.
28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(d4, 2.0);
28680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vcvt_s32_f64(s31, d4);
28780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(s31, r4, OFFSET_OF(T, i));
28880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
28980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Convert from integer to floating point.
29080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ mov(lr, Operand(42));
29180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vmov(s31, lr);
29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vcvt_f64_s32(d4, s31);
29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ vstr(d4, r4, OFFSET_OF(T, f));
2941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Test vabs.
2961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vldr(d1, r4, OFFSET_OF(T, g));
2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vabs(d0, d1);
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vstr(d0, r4, OFFSET_OF(T, g));
2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vldr(d2, r4, OFFSET_OF(T, h));
3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vabs(d0, d2);
3011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vstr(d0, r4, OFFSET_OF(T, h));
3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Test vneg.
30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vldr(d1, r4, OFFSET_OF(T, m));
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vneg(d0, d1);
30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vstr(d0, r4, OFFSET_OF(T, m));
30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vldr(d1, r4, OFFSET_OF(T, n));
30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vneg(d0, d1);
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ vstr(d0, r4, OFFSET_OF(T, n));
31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeDesc desc;
314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assm.GetCode(&desc);
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
3165913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        desc,
3175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        Code::ComputeFlags(Code::STUB),
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK(code->IsCode());
320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef DEBUG
321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Code::cast(code)->Print();
322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif
323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    t.a = 1.5;
325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    t.b = 2.75;
326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    t.c = 17.17;
32780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.d = 0.0;
32880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.e = 0.0;
32980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.f = 0.0;
3301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    t.g = -2718.2818;
3311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    t.h = 31415926.5;
33280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.i = 0;
33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.m = -2718.2818;
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.n = 123.456;
33580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.x = 4.5;
33680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    t.y = 9.0;
337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    USE(dummy);
33980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(4.5, t.y);
34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(9.0, t.x);
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(-123.456, t.n);
34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(2718.2818, t.m);
34380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(2, t.i);
3441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CHECK_EQ(2718.2818, t.g);
3451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CHECK_EQ(31415926.5, t.h);
34680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(42.0, t.f);
34780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(1.0, t.e);
34880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK_EQ(1.000000059604644775390625, t.d);
349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_EQ(4.25, t.c);
350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_EQ(4.25, t.b);
351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_EQ(1.5, t.a);
352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
3557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(5) {
3577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Test the ARMv7 bitfield instructions.
3587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  InitializeVM();
3597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  v8::HandleScope scope;
3607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
3627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(ARMv7)) {
3647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CpuFeatures::Scope scope(ARMv7);
3657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    // On entry, r0 = 0xAAAAAAAA = 0b10..10101010.
3667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ ubfx(r0, r0, 1, 12);  // 0b00..010101010101 = 0x555
3677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ sbfx(r0, r0, 0, 5);   // 0b11..111111110101 = -11
3687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ bfc(r0, 1, 3);        // 0b11..111111110001 = -15
3697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ mov(r1, Operand(7));
3707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ bfi(r0, r1, 3, 3);    // 0b11..111111111001 = -7
3717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    __ mov(pc, Operand(lr));
3727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CodeDesc desc;
3747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    assm.GetCode(&desc);
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
3765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        desc,
3775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        Code::ComputeFlags(Code::STUB),
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
3797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CHECK(code->IsCode());
3807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef DEBUG
3817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    Code::cast(code)->Print();
3827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif
3837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
3847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    int res = reinterpret_cast<int>(
3857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0));
3867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    ::printf("f() = %d\n", res);
3877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CHECK_EQ(-7, res);
3887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
3897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
3907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
39150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
39250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian MonsenTEST(6) {
39350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // Test saturating instructions.
39450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  InitializeVM();
39550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  v8::HandleScope scope;
39650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
3978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
39850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
3998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(ARMv7)) {
40050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    CpuFeatures::Scope scope(ARMv7);
40150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ usat(r1, 8, Operand(r0));           // Sat 0xFFFF to 0-255 = 0xFF.
40250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ usat(r2, 12, Operand(r0, ASR, 9));  // Sat (0xFFFF>>9) to 0-4095 = 0x7F.
40350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ usat(r3, 1, Operand(r0, LSL, 16));  // Sat (0xFFFF<<16) to 0-1 = 0x0.
40450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ add(r0, r1, Operand(r2));
40550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ add(r0, r0, Operand(r3));
40650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    __ mov(pc, Operand(lr));
40750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
40850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    CodeDesc desc;
40950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    assm.GetCode(&desc);
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
4115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        desc,
4125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        Code::ComputeFlags(Code::STUB),
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
41450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    CHECK(code->IsCode());
41550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen#ifdef DEBUG
41650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    Code::cast(code)->Print();
41750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen#endif
41850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
41950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    int res = reinterpret_cast<int>(
42050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen                CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0));
42150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    ::printf("f() = %d\n", res);
42250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    CHECK_EQ(382, res);
42350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  }
42450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen}
42550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
42690bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockenum VCVTTypes {
4281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  s32_f64,
4291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  u32_f64
4301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
4311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void TestRoundingMode(VCVTTypes types,
4331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             VFPRoundingMode mode,
4341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             double value,
4351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             int expected,
4361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             bool expected_exception = false) {
43790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner  InitializeVM();
43890bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner  v8::HandleScope scope;
43990bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
44190bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(VFP3)) {
4431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CpuFeatures::Scope scope(VFP3);
44490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Label wrong_exception;
4461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vmrs(r1);
4481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Set custom FPSCR.
4491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask));
4501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ orr(r2, r2, Operand(mode));
4511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vmsr(r2);
4521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Load value, convert, and move back result to r0 if everything went well.
4541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vmov(d1, value);
4551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    switch (types) {
4561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      case s32_f64:
4571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        __ vcvt_s32_f64(s0, d1, kFPSCRRounding);
4581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        break;
4591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      case u32_f64:
4611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        __ vcvt_u32_f64(s0, d1, kFPSCRRounding);
4621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        break;
4631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      default:
4651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        UNREACHABLE();
4661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        break;
4671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
4681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Check for vfp exceptions
4691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vmrs(r2);
4701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ tst(r2, Operand(kVFPExceptionMask));
4711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Check that we behaved as expected.
4721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(&wrong_exception,
4731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block         expected_exception ? eq : ne);
4741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // There was no exception. Retrieve the result and return.
4751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ vmov(r0, s0);
4761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ mov(pc, Operand(lr));
47790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // The exception behaviour is not what we expected.
4791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Load a special value and return.
4801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ bind(&wrong_exception);
4811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ mov(r0, Operand(11223344));
4821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ mov(pc, Operand(lr));
48390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
4841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CodeDesc desc;
4851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    assm.GetCode(&desc);
48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
4871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        desc,
4881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        Code::ComputeFlags(Code::STUB),
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
4901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CHECK(code->IsCode());
49190bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner#ifdef DEBUG
4921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Code::cast(code)->Print();
49390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner#endif
4941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
4951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    int res = reinterpret_cast<int>(
4961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
4971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ::printf("res = %d\n", res);
4981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CHECK_EQ(expected, res);
4991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
50090bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner}
50190bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
50290bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
50390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell BrennerTEST(7) {
50490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner  // Test vfp rounding modes.
50590bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
5061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // s32_f64 (double to integer).
5071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN,  0, 0);
5091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN,  0.5, 0);
5101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, -0.5, 0);
5111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN,  1.5, 2);
5121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, -1.5, -2);
5131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN,  123.7, 124);
5141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, -123.7, -124);
5151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN,  123456.2,  123456);
5161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, -123456.2, -123456);
5171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
5181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMaxInt + 0.49), kMaxInt);
5191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMaxInt + 1.0), kMaxInt, true);
5201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMaxInt + 0.5), kMaxInt, true);
5211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, static_cast<double>(kMinInt), kMinInt);
5221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMinInt - 0.5), kMinInt);
5231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMinInt - 1.0), kMinInt, true);
5241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RN, (kMinInt - 0.51), kMinInt, true);
5251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM,  0, 0);
5271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM,  0.5, 0);
5281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, -0.5, -1);
5291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM,  123.7, 123);
5301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, -123.7, -124);
5311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM,  123456.2,  123456);
5321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, -123456.2, -123457);
5331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
5341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, (kMaxInt + 0.5), kMaxInt);
5351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, (kMaxInt + 1.0), kMaxInt, true);
5361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, static_cast<double>(kMinInt), kMinInt);
5371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, (kMinInt - 0.5), kMinInt, true);
5381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RM, (kMinInt + 0.5), kMinInt);
5391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ,  0, 0);
5411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ,  0.5, 0);
5421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, -0.5, 0);
5431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ,  123.7,  123);
5441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, -123.7, -123);
5451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ,  123456.2,  123456);
5461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, -123456.2, -123456);
5471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
5491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, (kMaxInt + 1.0), kMaxInt, true);
5501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, static_cast<double>(kMinInt), kMinInt);
5511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, (kMinInt - 0.5), kMinInt);
5521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(s32_f64, RZ, (kMinInt - 1.0), kMinInt, true);
5531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // u32_f64 (double to integer).
5561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Negative values.
5581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, -0.5, 0);
5591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, -123456.7, 0, true);
5601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, static_cast<double>(kMinInt), 0, true);
5611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, kMinInt - 1.0, 0, true);
5621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, -0.5, 0, true);
5641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, -123456.7, 0, true);
5651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, static_cast<double>(kMinInt), 0, true);
5661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, kMinInt - 1.0, 0, true);
5671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, -0.5, 0);
5691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, -123456.7, 0, true);
5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, static_cast<double>(kMinInt), 0, true);
5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, kMinInt - 1.0, 0, true);
5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Positive values.
5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // kMaxInt is the maximum *signed* integer: 0x7fffffff.
5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const uint32_t kMaxUInt = 0xffffffffu;
5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ,  0, 0);
5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ,  0.5, 0);
5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ,  123.7,  123);
5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ,  123456.2,  123456);
5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
5821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, (kMaxInt + 1.0),
5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                static_cast<uint32_t>(kMaxInt) + 1);
5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, (kMaxUInt + 0.5), kMaxUInt);
5851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RZ, (kMaxUInt + 1.0), kMaxUInt, true);
5861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM,  0, 0);
5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM,  0.5, 0);
5891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM,  123.7, 123);
5901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM,  123456.2,  123456);
5911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
5921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, (kMaxInt + 0.5), kMaxInt);
5931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, (kMaxInt + 1.0),
5941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                static_cast<uint32_t>(kMaxInt) + 1);
5951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, (kMaxUInt + 0.5), kMaxUInt);
5961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RM, (kMaxUInt + 1.0), kMaxUInt, true);
5971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN,  0, 0);
5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN,  0.5, 0);
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN,  1.5, 2);
6011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN,  123.7, 124);
6021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN,  123456.2,  123456);
6031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
6041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt);
6051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5),
6061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                static_cast<uint32_t>(kMaxInt) + 1);
6071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt);
6081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true);
6091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true);
61090bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner}
61190bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
6128b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(8) {
6138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Test VFP multi load/store with ia_w.
6148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  InitializeVM();
6158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  v8::HandleScope scope;
6168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
6188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double a;
6198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double b;
6208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double c;
6218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double d;
6228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double e;
6238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double f;
6248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double g;
6258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double h;
6268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } D;
6278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  D d;
6288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float a;
6318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float b;
6328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float c;
6338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float d;
6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float e;
6358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float f;
6368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float g;
6378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float h;
6388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } F;
6398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  F f;
6408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Create a function that uses vldm/vstm to move some double and
6428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // single precision values around in memory.
6438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
6448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(VFP3)) {
6468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CpuFeatures::Scope scope(VFP3);
6478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ mov(ip, Operand(sp));
6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
6508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ sub(fp, ip, Operand(4));
6518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, a)));
6538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia_w, r4, d0, d3);
6548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia_w, r4, d4, d7);
6558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, a)));
6578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia_w, r4, d6, d7);
6588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia_w, r4, d0, d5);
6598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, a)));
6618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia_w, r4, s0, s3);
6628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia_w, r4, s4, s7);
6638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, a)));
6658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia_w, r4, s6, s7);
6668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia_w, r4, s0, s5);
6678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
6698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CodeDesc desc;
6718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    assm.GetCode(&desc);
6728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* code = HEAP->CreateCode(
6738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        desc,
6748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Code::ComputeFlags(Code::STUB),
6758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
6768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK(code->IsCode());
6778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG
6788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Code::cast(code)->Print();
6798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif
6808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
6818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.a = 1.1;
6828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.b = 2.2;
6838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.c = 3.3;
6848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.d = 4.4;
6858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.e = 5.5;
6868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.f = 6.6;
6878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.g = 7.7;
6888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.h = 8.8;
6898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.a = 1.0;
6918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.b = 2.0;
6928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.c = 3.0;
6938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.d = 4.0;
6948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.e = 5.0;
6958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.f = 6.0;
6968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.g = 7.0;
6978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.h = 8.0;
6988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
6998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
7008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    USE(dummy);
7018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.7, d.a);
7038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.8, d.b);
7048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.1, d.c);
7058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.2, d.d);
7068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.3, d.e);
7078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.4, d.f);
7088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.5, d.g);
7098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.6, d.h);
7108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.0, f.a);
7128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.0, f.b);
7138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.0, f.c);
7148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.0, f.d);
7158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.0, f.e);
7168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.0, f.f);
7178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.0, f.g);
7188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.0, f.h);
7198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
7208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
7218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7238b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(9) {
7248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Test VFP multi load/store with ia.
7258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  InitializeVM();
7268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  v8::HandleScope scope;
7278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double a;
7308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double b;
7318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double c;
7328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double d;
7338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double e;
7348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double f;
7358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double g;
7368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double h;
7378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } D;
7388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  D d;
7398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
7418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float a;
7428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float b;
7438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float c;
7448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float d;
7458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float e;
7468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float f;
7478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float g;
7488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float h;
7498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } F;
7508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  F f;
7518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Create a function that uses vldm/vstm to move some double and
7538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // single precision values around in memory.
7548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
7558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(VFP3)) {
7578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CpuFeatures::Scope scope(VFP3);
7588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ mov(ip, Operand(sp));
7608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
7618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ sub(fp, ip, Operand(4));
7628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, a)));
7648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia, r4, d0, d3);
7658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r4, Operand(4 * 8));
7668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia, r4, d4, d7);
7678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, a)));
7698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia, r4, d6, d7);
7708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r4, Operand(2 * 8));
7718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia, r4, d0, d5);
7728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, a)));
7748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia, r4, s0, s3);
7758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r4, Operand(4 * 4));
7768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(ia, r4, s4, s7);
7778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, a)));
7798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia, r4, s6, s7);
7808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r4, Operand(2 * 4));
7818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(ia, r4, s0, s5);
7828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
7848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CodeDesc desc;
7868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    assm.GetCode(&desc);
7878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* code = HEAP->CreateCode(
7888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        desc,
7898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Code::ComputeFlags(Code::STUB),
7908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
7918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK(code->IsCode());
7928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG
7938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Code::cast(code)->Print();
7948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif
7958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
7968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.a = 1.1;
7978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.b = 2.2;
7988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.c = 3.3;
7998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.d = 4.4;
8008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.e = 5.5;
8018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.f = 6.6;
8028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.g = 7.7;
8038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.h = 8.8;
8048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.a = 1.0;
8068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.b = 2.0;
8078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.c = 3.0;
8088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.d = 4.0;
8098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.e = 5.0;
8108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.f = 6.0;
8118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.g = 7.0;
8128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.h = 8.0;
8138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
8158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    USE(dummy);
8168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.7, d.a);
8188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.8, d.b);
8198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.1, d.c);
8208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.2, d.d);
8218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.3, d.e);
8228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.4, d.f);
8238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.5, d.g);
8248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.6, d.h);
8258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.0, f.a);
8278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.0, f.b);
8288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.0, f.c);
8298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.0, f.d);
8308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.0, f.e);
8318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.0, f.f);
8328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.0, f.g);
8338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.0, f.h);
8348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
8358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
8368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8388b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(10) {
8398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Test VFP multi load/store with db_w.
8408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  InitializeVM();
8418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  v8::HandleScope scope;
8428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
8448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double a;
8458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double b;
8468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double c;
8478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double d;
8488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double e;
8498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double f;
8508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double g;
8518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    double h;
8528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } D;
8538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  D d;
8548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  typedef struct {
8568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float a;
8578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float b;
8588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float c;
8598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float d;
8608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float e;
8618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float f;
8628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float g;
8638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    float h;
8648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } F;
8658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  F f;
8668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Create a function that uses vldm/vstm to move some double and
8688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // single precision values around in memory.
8698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
8708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (CpuFeatures::IsSupported(VFP3)) {
8728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CpuFeatures::Scope scope(VFP3);
8738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ mov(ip, Operand(sp));
8758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
8768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ sub(fp, ip, Operand(4));
8778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
8798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(db_w, r4, d4, d7);
8808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(db_w, r4, d0, d3);
8818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
8838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(db_w, r4, d0, d5);
8848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(db_w, r4, d6, d7);
8858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
8878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(db_w, r4, s4, s7);
8888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vldm(db_w, r4, s0, s3);
8898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
8918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(db_w, r4, s0, s5);
8928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ vstm(db_w, r4, s6, s7);
8938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
8958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CodeDesc desc;
8978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    assm.GetCode(&desc);
8988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* code = HEAP->CreateCode(
8998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        desc,
9008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Code::ComputeFlags(Code::STUB),
9018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
9028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK(code->IsCode());
9038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG
9048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Code::cast(code)->Print();
9058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif
9068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
9078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.a = 1.1;
9088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.b = 2.2;
9098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.c = 3.3;
9108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.d = 4.4;
9118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.e = 5.5;
9128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.f = 6.6;
9138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.g = 7.7;
9148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    d.h = 8.8;
9158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.a = 1.0;
9178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.b = 2.0;
9188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.c = 3.0;
9198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.d = 4.0;
9208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.e = 5.0;
9218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.f = 6.0;
9228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.g = 7.0;
9238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    f.h = 8.0;
9248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
9268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    USE(dummy);
9278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.7, d.a);
9298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.8, d.b);
9308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.1, d.c);
9318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.2, d.d);
9328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.3, d.e);
9338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.4, d.f);
9348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.5, d.g);
9358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.6, d.h);
9368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(7.0, f.a);
9388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(8.0, f.b);
9398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(1.0, f.c);
9408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(2.0, f.d);
9418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(3.0, f.e);
9428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(4.0, f.f);
9438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(5.0, f.g);
9448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    CHECK_EQ(6.0, f.h);
9458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
9468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
9478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(11) {
950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Test instructions using the carry flag.
951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  InitializeVM();
952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::HandleScope scope;
953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  typedef struct {
955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int32_t a;
956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int32_t b;
957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int32_t c;
958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int32_t d;
959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } I;
960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  I i;
961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
962257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i.a = 0xabcd0001;
963257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i.b = 0xabcd0000;
964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Test HeapObject untagging.
968257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r1, Operand(r1, ASR, 1), SetCC);
970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ adc(r1, r1, Operand(r1), LeaveCC, cs);
971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
972257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r2, Operand(r2, ASR, 1), SetCC);
975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ adc(r2, r2, Operand(r2), LeaveCC, cs);
976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Test corner cases.
979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r1, Operand(0xffffffff));
980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r2, Operand(0));
981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r3, Operand(r1, ASR, 1), SetCC);  // Set the carry.
982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ adc(r3, r1, Operand(r2));
983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r1, Operand(0xffffffff));
986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r2, Operand(0));
987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(r3, Operand(r2, ASR, 1), SetCC);  // Unset the carry.
988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ adc(r3, r1, Operand(r2));
989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ mov(pc, Operand(lr));
992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CodeDesc desc;
994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  assm.GetCode(&desc);
995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* code = HEAP->CreateCode(
996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      desc,
997257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Code::ComputeFlags(Code::STUB),
998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK(code->IsCode());
1000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG
1001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Code::cast(code)->Print();
1002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
1003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
1004257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0);
1005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  USE(dummy);
1006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK_EQ(0xabcd0001, i.a);
1008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK_EQ(static_cast<int32_t>(0xabcd0000) >> 1, i.b);
1009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK_EQ(0x00000000, i.c);
1010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK_EQ(0xffffffff, i.d);
1011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
101369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
101469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(12) {
101569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Test chaining of label usages within instructions (issue 1644).
101669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  InitializeVM();
101769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::HandleScope scope;
101869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
101969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
102069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Label target;
102169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ b(eq, &target);
102269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ b(ne, &target);
102369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bind(&target);
102469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ nop();
102569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
102669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __
1028