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