1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 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 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/assembler-arm-inl.h" 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/simulator-arm.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/disassembler.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Define these function prototypes to match JSEntryFunction in execution.cc. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F2)(int x, int y, int p2, int p3, int p4); 438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochtypedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4); 448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochtypedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(0) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r0, Operand(r1)); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F2 f = FUNCTION_CAST<F2>(code->entry()); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0)); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, res); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(1) { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r1, Operand(r0)); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r0, Operand::Zero()); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(&C); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r0, Operand(r1)); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(r1, r1, Operand(1)); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ teq(r1, Operand::Zero()); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(ne, &L); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0)); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5050, res); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(2) { 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r1, Operand(r0)); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(1)); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(&C); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mul(r0, r1, r0); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(r1, r1, Operand(1)); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ teq(r1, Operand::Zero()); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(ne, &L); 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // some relocated stuff here, not executed 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ RecordComment("dead code, just testing relocations"); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r0, Operand(isolate->factory()->true_value())); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ RecordComment("dead code, just testing immediate operands"); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(-1)); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xFF000000)); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xF0F0F0F0)); 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xFFF0FFFF)); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0)); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3628800, res); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(3) { 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef struct { 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int i; 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char c; 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int16_t s; 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } T; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block T t; 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(ip, Operand(sp)); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(fp, ip, Operand(4)); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r4, Operand(r0)); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i))); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r0, ASR, 1)); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ str(r2, MemOperand(r4, OFFSET_OF(T, i))); 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c))); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r2, Operand(r0)); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r2, LSL, 2)); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ strb(r2, MemOperand(r4, OFFSET_OF(T, c))); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s))); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r2, Operand(r0)); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r2, ASR, 3)); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ strh(r2, MemOperand(r4, OFFSET_OF(T, s))); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.i = 100000; 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.c = 10; 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.s = 1000; 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0)); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(101010, res); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(100000/2, t.i); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(10*4, t.c); 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1000/8, t.s); 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(4) { 209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Test the VFP floating point instructions. 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke typedef struct { 215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke double a; 216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke double b; 217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke double c; 21880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen double d; 21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen double e; 22080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen double f; 2211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block double g; 2221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block double h; 22380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int i; 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double j; 22544f0eee88ff00398ff7f715fab053374d808c90dSteve Block double m; 22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block double n; 22780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen float x; 22880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen float y; 229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } T; 230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke T t; 231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Create a function that accepts &t, and loads, manipulates, and stores 23380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the doubles and floats. 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label L, C; 236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 2388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (CpuFeatures::IsSupported(VFP3)) { 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, VFP3); 240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ mov(ip, Operand(sp)); 242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ sub(fp, ip, Operand(4)); 244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ mov(r4, Operand(r0)); 246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vldr(d6, r4, OFFSET_OF(T, a)); 247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vldr(d7, r4, OFFSET_OF(T, b)); 248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vadd(d5, d6, d7); 249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vstr(d5, r4, OFFSET_OF(T, c)); 250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmla(d5, d6, d7); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmls(d5, d5, d6); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vmov(r2, r3, d5); 255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vmov(d4, r2, r3); 256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ vstr(d4, r4, OFFSET_OF(T, b)); 257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 25880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Load t.x and t.y, switch values, and store back to the struct. 25980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vldr(s0, r4, OFFSET_OF(T, x)); 26080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vldr(s31, r4, OFFSET_OF(T, y)); 26180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(s16, s0); 26280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(s0, s31); 26380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(s31, s16); 26480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(s0, r4, OFFSET_OF(T, x)); 26580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(s31, r4, OFFSET_OF(T, y)); 26680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Move a literal into a register that can be encoded in the instruction. 26880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(d4, 1.0); 26980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(d4, r4, OFFSET_OF(T, e)); 27080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Move a literal into a register that requires 64 bits to encode. 27280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // 0x3ff0000010000000 = 1.000000059604644775390625 27380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(d4, 1.000000059604644775390625); 27480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(d4, r4, OFFSET_OF(T, d)); 27580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Convert from floating point to integer. 27780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(d4, 2.0); 27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vcvt_s32_f64(s31, d4); 27980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(s31, r4, OFFSET_OF(T, i)); 28080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Convert from integer to floating point. 28280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ mov(lr, Operand(42)); 28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vmov(s31, lr); 28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vcvt_f64_s32(d4, s31); 28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ vstr(d4, r4, OFFSET_OF(T, f)); 2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert from fixed point to floating point. 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(lr, Operand(2468)); 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(s8, lr); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vcvt_f64_s32(d4, 2); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d4, r4, OFFSET_OF(T, j)); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Test vabs. 2941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vldr(d1, r4, OFFSET_OF(T, g)); 2951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vabs(d0, d1); 2961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vstr(d0, r4, OFFSET_OF(T, g)); 2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vldr(d2, r4, OFFSET_OF(T, h)); 2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vabs(d0, d2); 2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vstr(d0, r4, OFFSET_OF(T, h)); 3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Test vneg. 30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vldr(d1, r4, OFFSET_OF(T, m)); 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vneg(d0, d1); 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vstr(d0, r4, OFFSET_OF(T, m)); 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vldr(d1, r4, OFFSET_OF(T, n)); 30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vneg(d0, d1); 30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ vstr(d0, r4, OFFSET_OF(T, n)); 30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeDesc desc; 312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke assm.GetCode(&desc); 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef DEBUG 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke t.a = 1.5; 321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke t.b = 2.75; 322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke t.c = 17.17; 32380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.d = 0.0; 32480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.e = 0.0; 32580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.f = 0.0; 3261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block t.g = -2718.2818; 3271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block t.h = 31415926.5; 32880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.i = 0; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.j = 0; 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block t.m = -2718.2818; 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block t.n = 123.456; 33280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.x = 4.5; 33380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen t.y = 9.0; 334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke USE(dummy); 33680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(4.5, t.y); 33780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(9.0, t.x); 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(-123.456, t.n); 33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(2718.2818, t.m); 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, t.i); 3411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CHECK_EQ(2718.2818, t.g); 3421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CHECK_EQ(31415926.5, t.h); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(617.0, t.j); 34480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(42.0, t.f); 34580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1.0, t.e); 34680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1.000000059604644775390625, t.d); 347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(4.25, t.c); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(-4.1875, t.b); 349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(1.5, t.a); 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 3537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(5) { 3557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Test the ARMv7 bitfield instructions. 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 3597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 3617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (CpuFeatures::IsSupported(ARMv7)) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, ARMv7); 3647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On entry, r0 = 0xAAAAAAAA = 0b10..10101010. 3657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ ubfx(r0, r0, 1, 12); // 0b00..010101010101 = 0x555 3667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ sbfx(r0, r0, 0, 5); // 0b11..111111110101 = -11 3677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ bfc(r0, 1, 3); // 0b11..111111110001 = -15 3687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ mov(r1, Operand(7)); 3697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ bfi(r0, r1, 3, 3); // 0b11..111111111001 = -7 3707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ mov(pc, Operand(lr)); 3717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeDesc desc; 3737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch assm.GetCode(&desc); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 3767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef DEBUG 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 3797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 3817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int res = reinterpret_cast<int>( 3827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0)); 3837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ::printf("f() = %d\n", res); 3847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(-7, res); 3857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 3867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 3877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 38850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 38950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian MonsenTEST(6) { 39050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen // Test saturating instructions. 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 39450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 39650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 3978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (CpuFeatures::IsSupported(ARMv7)) { 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, ARMv7); 39950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ usat(r1, 8, Operand(r0)); // Sat 0xFFFF to 0-255 = 0xFF. 40050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ usat(r2, 12, Operand(r0, ASR, 9)); // Sat (0xFFFF>>9) to 0-4095 = 0x7F. 40150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ usat(r3, 1, Operand(r0, LSL, 16)); // Sat (0xFFFF<<16) to 0-1 = 0x0. 40250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ add(r0, r1, Operand(r2)); 40350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ add(r0, r0, Operand(r3)); 40450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen __ mov(pc, Operand(lr)); 40550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 40650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen CodeDesc desc; 40750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen assm.GetCode(&desc); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 41050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen#ifdef DEBUG 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 41350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen#endif 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 41550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen int res = reinterpret_cast<int>( 41650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0)); 41750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen ::printf("f() = %d\n", res); 41850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen CHECK_EQ(382, res); 41950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen } 42050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen} 42150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 42290bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 4231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockenum VCVTTypes { 4241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block s32_f64, 4251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block u32_f64 4261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 4271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void TestRoundingMode(VCVTTypes types, 4291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block VFPRoundingMode mode, 4301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block double value, 4311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int expected, 4321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool expected_exception = false) { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 43590bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 43790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 4388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (CpuFeatures::IsSupported(VFP3)) { 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, VFP3); 44090bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 4411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Label wrong_exception; 4421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vmrs(r1); 4441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Set custom FPSCR. 4451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask)); 4461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ orr(r2, r2, Operand(mode)); 4471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vmsr(r2); 4481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Load value, convert, and move back result to r0 if everything went well. 4501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vmov(d1, value); 4511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block switch (types) { 4521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case s32_f64: 4531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vcvt_s32_f64(s0, d1, kFPSCRRounding); 4541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block break; 4551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block case u32_f64: 4571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vcvt_u32_f64(s0, d1, kFPSCRRounding); 4581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block break; 4591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block default: 4611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block UNREACHABLE(); 4621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block break; 4631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Check for vfp exceptions 4651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vmrs(r2); 4661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ tst(r2, Operand(kVFPExceptionMask)); 4671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Check that we behaved as expected. 4681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ b(&wrong_exception, 4691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block expected_exception ? eq : ne); 4701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // There was no exception. Retrieve the result and return. 4711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ vmov(r0, s0); 4721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ mov(pc, Operand(lr)); 47390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 4741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The exception behaviour is not what we expected. 4751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Load a special value and return. 4761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ bind(&wrong_exception); 4771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ mov(r0, Operand(11223344)); 4781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ mov(pc, Operand(lr)); 47990bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 4801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CodeDesc desc; 4811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block assm.GetCode(&desc); 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 48490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner#ifdef DEBUG 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 48790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner#endif 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 4891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int res = reinterpret_cast<int>( 4901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); 4911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ::printf("res = %d\n", res); 4921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CHECK_EQ(expected, res); 4931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 49490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner} 49590bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 49690bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 49790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell BrennerTEST(7) { 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 49990bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner // Test vfp rounding modes. 50090bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 5011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // s32_f64 (double to integer). 5021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, 0, 0); 5041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, 0.5, 0); 5051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, -0.5, 0); 5061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, 1.5, 2); 5071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, -1.5, -2); 5081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, 123.7, 124); 5091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, -123.7, -124); 5101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, 123456.2, 123456); 5111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, -123456.2, -123456); 5121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, static_cast<double>(kMaxInt), kMaxInt); 5131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMaxInt + 0.49), kMaxInt); 5141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMaxInt + 1.0), kMaxInt, true); 5151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMaxInt + 0.5), kMaxInt, true); 5161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, static_cast<double>(kMinInt), kMinInt); 5171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMinInt - 0.5), kMinInt); 5181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMinInt - 1.0), kMinInt, true); 5191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RN, (kMinInt - 0.51), kMinInt, true); 5201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, 0, 0); 5221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, 0.5, 0); 5231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, -0.5, -1); 5241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, 123.7, 123); 5251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, -123.7, -124); 5261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, 123456.2, 123456); 5271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, -123456.2, -123457); 5281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, static_cast<double>(kMaxInt), kMaxInt); 5291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, (kMaxInt + 0.5), kMaxInt); 5301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, (kMaxInt + 1.0), kMaxInt, true); 5311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, static_cast<double>(kMinInt), kMinInt); 5321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, (kMinInt - 0.5), kMinInt, true); 5331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RM, (kMinInt + 0.5), kMinInt); 5341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, 0, 0); 5361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, 0.5, 0); 5371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, -0.5, 0); 5381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, 123.7, 123); 5391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, -123.7, -123); 5401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, 123456.2, 123456); 5411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, -123456.2, -123456); 5421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt); 5431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, (kMaxInt + 0.5), kMaxInt); 5441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, (kMaxInt + 1.0), kMaxInt, true); 5451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, static_cast<double>(kMinInt), kMinInt); 5461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, (kMinInt - 0.5), kMinInt); 5471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(s32_f64, RZ, (kMinInt - 1.0), kMinInt, true); 5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // u32_f64 (double to integer). 5511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Negative values. 5531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, -0.5, 0); 5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, -123456.7, 0, true); 5551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, static_cast<double>(kMinInt), 0, true); 5561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, kMinInt - 1.0, 0, true); 5571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, -0.5, 0, true); 5591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, -123456.7, 0, true); 5601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, static_cast<double>(kMinInt), 0, true); 5611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, kMinInt - 1.0, 0, true); 5621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, -0.5, 0); 5641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, -123456.7, 0, true); 5651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, static_cast<double>(kMinInt), 0, true); 5661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, kMinInt - 1.0, 0, true); 5671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Positive values. 5691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // kMaxInt is the maximum *signed* integer: 0x7fffffff. 5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const uint32_t kMaxUInt = 0xffffffffu; 5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, 0, 0); 5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, 0.5, 0); 5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, 123.7, 123); 5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, 123456.2, 123456); 5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt); 5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, (kMaxInt + 0.5), kMaxInt); 5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, (kMaxInt + 1.0), 5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static_cast<uint32_t>(kMaxInt) + 1); 5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, (kMaxUInt + 0.5), kMaxUInt); 5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RZ, (kMaxUInt + 1.0), kMaxUInt, true); 5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, 0, 0); 5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, 0.5, 0); 5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, 123.7, 123); 5851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, 123456.2, 123456); 5861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, static_cast<double>(kMaxInt), kMaxInt); 5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, (kMaxInt + 0.5), kMaxInt); 5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, (kMaxInt + 1.0), 5891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static_cast<uint32_t>(kMaxInt) + 1); 5901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, (kMaxUInt + 0.5), kMaxUInt); 5911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RM, (kMaxUInt + 1.0), kMaxUInt, true); 5921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, 0, 0); 5941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, 0.5, 0); 5951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, 1.5, 2); 5961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, 123.7, 124); 5971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, 123456.2, 123456); 5981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt); 5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt); 6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5), 6011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static_cast<uint32_t>(kMaxInt) + 1); 6021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt); 6031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true); 6041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true); 60590bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner} 60690bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6088b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(8) { 6098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Test VFP multi load/store with ia_w. 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 6138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 6158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double a; 6168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double b; 6178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double c; 6188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double d; 6198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double e; 6208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double f; 6218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double g; 6228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double h; 6238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } D; 6248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch D d; 6258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 6278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float a; 6288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float b; 6298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float c; 6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float d; 6318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float e; 6328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float f; 6338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float g; 6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float h; 6358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } F; 6368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch F f; 6378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Create a function that uses vldm/vstm to move some double and 6398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // single precision values around in memory. 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 6418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(sp)); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sub(fp, ip, Operand(4)); 6458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, a))); 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia_w, r4, d0, d3); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia_w, r4, d4, d7); 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, a))); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, d6, d7); 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, d0, d5); 6538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, a))); 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia_w, r4, s0, s3); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia_w, r4, s4, s7); 6578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, a))); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, s6, s7); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, s0, s5); 6618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 6638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 6688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 6718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F4 fn = FUNCTION_CAST<F4>(code->entry()); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.a = 1.1; 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.b = 2.2; 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.c = 3.3; 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.d = 4.4; 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.e = 5.5; 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.f = 6.6; 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.g = 7.7; 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.h = 8.8; 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.a = 1.0; 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.b = 2.0; 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.c = 3.0; 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.d = 4.0; 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.e = 5.0; 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.f = 6.0; 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.g = 7.0; 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.h = 8.0; 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 6938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.7, d.a); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.8, d.b); 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.1, d.c); 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.2, d.d); 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.3, d.e); 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.4, d.f); 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.5, d.g); 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.6, d.h); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.0, f.a); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.0, f.b); 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.0, f.c); 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.0, f.d); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.0, f.e); 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.0, f.f); 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.0, f.g); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.0, f.h); 7118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 7128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7148b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(9) { 7158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Test VFP multi load/store with ia. 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 7198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 7218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double a; 7228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double b; 7238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double c; 7248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double d; 7258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double e; 7268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double f; 7278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double g; 7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double h; 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } D; 7308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch D d; 7318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 7338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float a; 7348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float b; 7358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float c; 7368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float d; 7378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float e; 7388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float f; 7398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float g; 7408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float h; 7418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } F; 7428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch F f; 7438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Create a function that uses vldm/vstm to move some double and 7458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // single precision values around in memory. 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 7478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(sp)); 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sub(fp, ip, Operand(4)); 7518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, a))); 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia, r4, d0, d3); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r4, Operand(4 * 8)); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia, r4, d4, d7); 7568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, a))); 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia, r4, d6, d7); 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r4, Operand(2 * 8)); 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia, r4, d0, d5); 7618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, a))); 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia, r4, s0, s3); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r4, Operand(4 * 4)); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia, r4, s4, s7); 7668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, a))); 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia, r4, s6, s7); 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r4, Operand(2 * 4)); 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia, r4, s0, s5); 7718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 7738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 7788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 7818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F4 fn = FUNCTION_CAST<F4>(code->entry()); 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.a = 1.1; 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.b = 2.2; 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.c = 3.3; 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.d = 4.4; 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.e = 5.5; 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.f = 6.6; 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.g = 7.7; 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.h = 8.8; 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.a = 1.0; 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.b = 2.0; 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.c = 3.0; 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.d = 4.0; 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.e = 5.0; 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.f = 6.0; 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.g = 7.0; 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.h = 8.0; 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 8038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.7, d.a); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.8, d.b); 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.1, d.c); 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.2, d.d); 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.3, d.e); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.4, d.f); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.5, d.g); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.6, d.h); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.0, f.a); 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.0, f.b); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.0, f.c); 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.0, f.d); 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.0, f.e); 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.0, f.f); 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.0, f.g); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.0, f.h); 8218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 8228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8248b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(10) { 8258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Test VFP multi load/store with db_w. 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 8298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 8318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double a; 8328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double b; 8338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double c; 8348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double d; 8358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double e; 8368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double f; 8378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double g; 8388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch double h; 8398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } D; 8408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch D d; 8418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch typedef struct { 8438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float a; 8448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float b; 8458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float c; 8468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float d; 8478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float e; 8488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float f; 8498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float g; 8508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch float h; 8518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } F; 8528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch F f; 8538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Create a function that uses vldm/vstm to move some double and 8558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // single precision values around in memory. 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 8578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(sp)); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sub(fp, ip, Operand(4)); 8618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8)); 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(db_w, r4, d4, d7); 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(db_w, r4, d0, d3); 8658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8)); 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(db_w, r4, d0, d5); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(db_w, r4, d6, d7); 8698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4)); 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(db_w, r4, s4, s7); 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(db_w, r4, s0, s3); 8738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4)); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(db_w, r4, s0, s5); 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(db_w, r4, s6, s7); 8778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 8798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 8848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 8878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F4 fn = FUNCTION_CAST<F4>(code->entry()); 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.a = 1.1; 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.b = 2.2; 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.c = 3.3; 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.d = 4.4; 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.e = 5.5; 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.f = 6.6; 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.g = 7.7; 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d.h = 8.8; 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.a = 1.0; 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.b = 2.0; 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.c = 3.0; 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.d = 4.0; 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.e = 5.0; 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.f = 6.0; 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.g = 7.0; 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.h = 8.0; 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 9098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.7, d.a); 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.8, d.b); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.1, d.c); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.2, d.d); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.3, d.e); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.4, d.f); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.5, d.g); 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.6, d.h); 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7.0, f.a); 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8.0, f.b); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.0, f.c); 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.0, f.d); 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.0, f.e); 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4.0, f.f); 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5.0, f.g); 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(6.0, f.h); 9278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 9288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(11) { 931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test instructions using the carry flag. 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch typedef struct { 937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t a; 938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t b; 939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t c; 940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t d; 941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } I; 942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch I i; 943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i.a = 0xabcd0001; 945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i.b = 0xabcd0000; 946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test HeapObject untagging. 950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a))); 951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r1, Operand(r1, ASR, 1), SetCC); 952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ adc(r1, r1, Operand(r1), LeaveCC, cs); 953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ str(r1, MemOperand(r0, OFFSET_OF(I, a))); 954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b))); 956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r2, Operand(r2, ASR, 1), SetCC); 957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ adc(r2, r2, Operand(r2), LeaveCC, cs); 958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ str(r2, MemOperand(r0, OFFSET_OF(I, b))); 959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test corner cases. 961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r1, Operand(0xffffffff)); 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r2, Operand::Zero()); 963257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry. 964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ adc(r3, r1, Operand(r2)); 965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ str(r3, MemOperand(r0, OFFSET_OF(I, c))); 966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r1, Operand(0xffffffff)); 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r2, Operand::Zero()); 969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry. 970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ adc(r3, r1, Operand(r2)); 971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ str(r3, MemOperand(r0, OFFSET_OF(I, d))); 972257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ mov(pc, Operand(lr)); 974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CodeDesc desc; 976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assm.GetCode(&desc); 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0); 985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch USE(dummy); 986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(0xabcd0001, i.a); 988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(static_cast<int32_t>(0xabcd0000) >> 1, i.b); 989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(0x00000000, i.c); 990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(0xffffffff, i.d); 991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 99369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 99469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(12) { 99569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Test chaining of label usages within instructions (issue 1644). 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 99969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 100169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Label target; 100269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ b(eq, &target); 100369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ b(ne, &target); 100469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(&target); 100569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ nop(); 100669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 100769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(13) { 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test VFP instructions using registers d16-d31. 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CpuFeatures::IsSupported(VFP32DREGS)) { 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef struct { 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double a; 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double b; 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double c; 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double x; 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double y; 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double z; 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double i; 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double j; 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double k; 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t low; 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t high; 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } T; 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T t; 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a function that accepts &t, and loads, manipulates, and stores 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the doubles and floats. 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label L, C; 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CpuFeatures::IsSupported(VFP3)) { 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, VFP3); 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | lr.bit()); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load a, b, c into d16, d17, d18. 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r4, Operand(r0)); 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldr(d16, r4, OFFSET_OF(T, a)); 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldr(d17, r4, OFFSET_OF(T, b)); 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldr(d18, r4, OFFSET_OF(T, c)); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vneg(d25, d16); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vadd(d25, d25, d17); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vsub(d25, d25, d18); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmul(d25, d25, d25); 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vdiv(d25, d25, d18); 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d16, d25); 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vsqrt(d17, d25); 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vneg(d17, d17); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vabs(d17, d17); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmla(d18, d16, d17); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store d16, d17, d18 into a, b, c. 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r4, Operand(r0)); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d16, r4, OFFSET_OF(T, a)); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d17, r4, OFFSET_OF(T, b)); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d18, r4, OFFSET_OF(T, c)); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load x, y, z into d29-d31. 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, x))); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldm(ia_w, r4, d29, d31); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap d29 and d30 via r registers. 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(r1, r2, d29); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d29, d30); 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d30, r1, r2); 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert to and from integer. 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vcvt_s32_f64(s1, d31); 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vcvt_f64_u32(d31, s1); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store d29-d31 into x, y, z. 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, x))); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, d29, d31); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move constants into d20, d21, d22 and store into i, j, k. 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d20, 14.7610017472335499); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d21, 16.0); 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r1, Operand(372106121)); 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r2, Operand(1079146608)); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d22, VmovIndexLo, r1); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(d22, VmovIndexHi, r2); 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, i))); 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstm(ia_w, r4, d20, d22); 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move d22 into low and high. 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(r4, VmovIndexLo, d22); 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r4, MemOperand(r0, OFFSET_OF(T, low))); 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmov(r4, VmovIndexHi, d22); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r4, MemOperand(r0, OFFSET_OF(T, high))); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | pc.bit()); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.a = 1.5; 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.b = 2.75; 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.c = 17.17; 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.x = 1.5; 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.y = 2.75; 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.z = 17.17; 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(14.7610017472335499, t.a); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3.84200491244266251, t.b); 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(73.8818412254460241, t.c); 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2.75, t.x); 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1.5, t.y); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(17.0, t.z); 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(14.7610017472335499, t.i); 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(16.0, t.j); 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(73.8818412254460241, t.k); 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(372106121, t.low); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1079146608, t.high); 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(14) { 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test the VFP Canonicalized Nan mode. 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef struct { 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double left; 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double right; 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double add_result; 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double sub_result; 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double mul_result; 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double div_result; 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } T; 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T t; 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a function that makes the four basic operations. 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure FPSCR state (as JSEntryStub does). 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label fpscr_done; 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmrs(r1); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ tst(r1, Operand(kVFPDefaultNaNModeControlBit)); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ b(ne, &fpscr_done); 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ orr(r1, r1, Operand(kVFPDefaultNaNModeControlBit)); 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmsr(r1); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&fpscr_done); 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldr(d0, r0, OFFSET_OF(T, left)); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vldr(d1, r0, OFFSET_OF(T, right)); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vadd(d2, d0, d1); 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d2, r0, OFFSET_OF(T, add_result)); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vsub(d2, d0, d1); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d2, r0, OFFSET_OF(T, sub_result)); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmul(d2, d0, d1); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d2, r0, OFFSET_OF(T, mul_result)); 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vdiv(d2, d0, d1); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vstr(d2, r0, OFFSET_OF(T, div_result)); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(pc, Operand(lr)); 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.left = bit_cast<double>(kHoleNanInt64); 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.right = 1; 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.add_result = 0; 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.sub_result = 0; 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.mul_result = 0; 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.div_result = 0; 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint32_t kArmNanUpper32 = 0x7ff80000; 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint32_t kArmNanLower32 = 0x00000000; 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uint64_t kArmNanInt64 = 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (static_cast<uint64_t>(kArmNanUpper32) << 32) | kArmNanLower32; 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kArmNanInt64 != kHoleNanInt64); 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // With VFP2 the sign of the canonicalized Nan is undefined. So 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we remove the sign bit for the upper tests. 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanUpper32, 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (bit_cast<int64_t>(t.add_result) >> 32) & 0x7fffffff); 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.add_result) & 0xffffffffu); 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanUpper32, 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (bit_cast<int64_t>(t.sub_result) >> 32) & 0x7fffffff); 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.sub_result) & 0xffffffffu); 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanUpper32, 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (bit_cast<int64_t>(t.mul_result) >> 32) & 0x7fffffff); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.mul_result) & 0xffffffffu); 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanUpper32, 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (bit_cast<int64_t>(t.div_result) >> 32) & 0x7fffffff); 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.div_result) & 0xffffffffu); 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(15) { 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test the Neon instructions. 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef struct { 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src0; 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src1; 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src2; 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src3; 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src4; 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src5; 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src6; 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src7; 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst0; 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst1; 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst2; 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst3; 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst4; 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst5; 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst6; 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst7; 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t srcA0; 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t srcA1; 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA0; 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA1; 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA2; 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA3; 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA4; 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA5; 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA6; 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dstA7; 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } T; 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T t; 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a function that accepts &t, and loads, manipulates, and stores 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the doubles and floats. 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CpuFeatures::IsSupported(NEON)) { 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, NEON); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | lr.bit()); 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move 32 bytes with neon. 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, src0))); 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4)); 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, dst0))); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vst1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4)); 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Expand 8 bytes into 8 words(16 bits). 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, srcA0))); 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vld1(Neon8, NeonListOperand(d0), NeonMemOperand(r4)); 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmovl(NeonU8, q0, d0); 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, dstA0))); 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4)); 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The same expansion, but with different source and destination registers. 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, srcA0))); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vld1(Neon8, NeonListOperand(d1), NeonMemOperand(r4)); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vmovl(NeonU8, q1, d1); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r4, r0, Operand(OFFSET_OF(T, dstA4))); 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4)); 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | pc.bit()); 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src0 = 0x01020304; 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src1 = 0x11121314; 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src2 = 0x21222324; 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src3 = 0x31323334; 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src4 = 0x41424344; 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src5 = 0x51525354; 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src6 = 0x61626364; 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src7 = 0x71727374; 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst0 = 0; 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst1 = 0; 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst2 = 0; 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst3 = 0; 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst4 = 0; 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst5 = 0; 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst6 = 0; 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst7 = 0; 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.srcA0 = 0x41424344; 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.srcA1 = 0x81828384; 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA0 = 0; 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA1 = 0; 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA2 = 0; 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA3 = 0; 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA4 = 0; 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA5 = 0; 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA6 = 0; 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dstA7 = 0; 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x01020304, t.dst0); 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x11121314, t.dst1); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x21222324, t.dst2); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x31323334, t.dst3); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x41424344, t.dst4); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x51525354, t.dst5); 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x61626364, t.dst6); 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x71727374, t.dst7); 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00430044, t.dstA0); 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00410042, t.dstA1); 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00830084, t.dstA2); 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00810082, t.dstA3); 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00430044, t.dstA4); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00410042, t.dstA5); 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00830084, t.dstA6); 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00810082, t.dstA7); 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(16) { 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test the pkh, uxtb, uxtab and uxtb16 instructions. 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef struct { 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src0; 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src1; 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t src2; 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst0; 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst1; 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst2; 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst3; 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dst4; 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } T; 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T t; 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a function that accepts &t, and loads, manipulates, and stores 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the doubles and floats. 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | lr.bit()); 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r4, Operand(r0)); 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src0))); 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r1, MemOperand(r4, OFFSET_OF(T, src1))); 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pkhbt(r2, r0, Operand(r1, LSL, 8)); 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r4, OFFSET_OF(T, dst0))); 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pkhtb(r2, r0, Operand(r1, ASR, 8)); 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1))); 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ uxtb16(r2, Operand(r0, ROR, 8)); 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2))); 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ uxtb(r2, Operand(r0, ROR, 8)); 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3))); 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2))); 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ uxtab(r2, r0, Operand(r1, ROR, 8)); 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4))); 1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | pc.bit()); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src0 = 0x01020304; 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src1 = 0x11121314; 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.src2 = 0x11121300; 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst0 = 0; 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst1 = 0; 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst2 = 0; 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst3 = 0; 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dst4 = 0; 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x12130304, t.dst0); 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x01021213, t.dst1); 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00010003, t.dst2); 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x00000003, t.dst3); 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x11121313, t.dst4); 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(17) { 1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test generating labels at high addresses. 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Should not assert. 1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate a code segment that will be longer than 2^24 bytes. 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < 1 << 23 ; ++i) { // 2^23 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ nop(); 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label target; 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ b(eq, &target); 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&target); 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ nop(); 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TEST_SDIV(expected_, dividend_, divisor_) \ 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.dividend = dividend_; \ 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.divisor = divisor_; \ 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t.result = 0; \ 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \ 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(expected_, t.result); 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(18) { 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test the sdiv. 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef struct { 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t dividend; 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t divisor; 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t result; 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } T; 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T t; 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CpuFeatures::IsSupported(SUDIV)) { 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuFeatureScope scope(&assm, SUDIV); 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r3, Operand(r0)); 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend))); 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor))); 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sdiv(r2, r0, r1); 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r2, MemOperand(r3, OFFSET_OF(T, result))); 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bx(lr); 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F3 f = FUNCTION_CAST<F3>(code->entry()); 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* dummy; 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(1073741824, kMinInt, -2); 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(kMinInt, kMinInt, -1); 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(5, 10, 2); 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(3, 10, 3); 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(-5, 10, -2); 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(-3, 10, -3); 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(-5, -10, 2); 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(-3, -10, 3); 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(5, -10, -2); 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TEST_SDIV(3, -10, -3); 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(dummy); 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TEST_SDIV 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(code_relative_offset) { 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test extracting the offset of a label from the beginning of the code 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a register. 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize a code object that will contain the code. 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> code_object(isolate->heap()->undefined_value(), isolate); 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label start, target_away, target_faraway; 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit()); 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // r3 is used as the address zero, the test will crash when we load it. 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r3, Operand::Zero()); 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // r5 will be a pointer to the start of the code. 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r5, Operand(code_object)); 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov_label_offset(r4, &start); 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov_label_offset(r1, &target_faraway); 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r1, MemOperand(sp, kPointerSize, NegPreIndex)); 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov_label_offset(r1, &target_away); 1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump straight to 'target_away' the first time and use the relative 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position the second time. This covers the case when extracting the 1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position of a label which is linked. 1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r2, Operand::Zero()); 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&start); 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cmp(r2, Operand::Zero()); 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ b(eq, &target_away); 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(pc, r5, r1); 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit invalid instructions to push the label between 2^8 and 2^16 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions away. The test will crash if they are reached. 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < (1 << 10); i++) { 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r3, MemOperand(r3)); 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&target_away); 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This will be hit twice: r0 = r0 + 5 + 5. 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r0, r0, Operand(5)); 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r1, MemOperand(sp, kPointerSize, PostIndex), ne); 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(pc, r5, r4, LeaveCC, ne); 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r2, Operand(1)); 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ b(&start); 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit invalid instructions to push the label between 2^16 and 2^24 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions away. The test will crash if they are reached. 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < (1 << 21); i++) { 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r3, MemOperand(r3)); 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&target_faraway); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // r0 = r0 + 5 + 5 + 11 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(r0, r0, Operand(11)); 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit()); 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), code_object); 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 21, 0, 0, 0, 0)); 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ::printf("f() = %d\n", res); 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(42, res); 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __ 1569