The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-code-stubs-arm.cc @ f230a1cf

History | View | Annotate | Download (6.14 KB)

1
// Copyright 2013 the V8 project authors. All rights reserved.
2
// Rrdistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Rrdistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Rrdistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include <stdlib.h>
29

    
30
#include "v8.h"
31

    
32
#include "cctest.h"
33
#include "code-stubs.h"
34
#include "test-code-stubs.h"
35
#include "factory.h"
36
#include "macro-assembler.h"
37
#include "platform.h"
38
#include "simulator.h"
39

    
40
using namespace v8::internal;
41

    
42
#define __ masm.
43

    
44
ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
45
                                              Register source_reg,
46
                                              Register destination_reg,
47
                                              bool inline_fastpath) {
48
  // Allocate an executable page of memory.
49
  size_t actual_size;
50
  byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
51
                                                 &actual_size,
52
                                                 true));
53
  CHECK(buffer);
54
  HandleScope handles(isolate);
55
  MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
56
  masm.set_allow_stub_calls(false);
57
  DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath);
58

    
59
  byte* start = stub.GetCode(isolate)->instruction_start();
60
  Label done;
61

    
62
  // Save callee save registers.
63
  __ Push(r7, r6, r5, r4);
64
  __ Push(lr);
65

    
66
  // For softfp, move the input value into d0.
67
  if (!masm.use_eabi_hardfloat()) {
68
    __ vmov(d0, r0, r1);
69
  }
70
  // Push the double argument.
71
  __ sub(sp, sp, Operand(kDoubleSize));
72
  __ vstr(d0, sp, 0);
73
  if (!source_reg.is(sp)) {
74
    __ mov(source_reg, sp);
75
  }
76

    
77
  // Save registers make sure they don't get clobbered.
78
  int source_reg_offset = kDoubleSize;
79
  int reg_num = 0;
80
  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
81
    Register reg = Register::from_code(reg_num);
82
    if (!reg.is(destination_reg)) {
83
      __ push(reg);
84
      source_reg_offset += kPointerSize;
85
    }
86
  }
87

    
88
  // Re-push the double argument.
89
  __ sub(sp, sp, Operand(kDoubleSize));
90
  __ vstr(d0, sp, 0);
91

    
92
  // Call through to the actual stub
93
  if (inline_fastpath) {
94
    __ vldr(d0, MemOperand(source_reg));
95
    __ TryInlineTruncateDoubleToI(destination_reg, d0, &done);
96
    if (destination_reg.is(source_reg) && !source_reg.is(sp)) {
97
      // Restore clobbered source_reg.
98
      __ add(source_reg, sp, Operand(source_reg_offset));
99
    }
100
  }
101
  __ Call(start, RelocInfo::EXTERNAL_REFERENCE);
102
  __ bind(&done);
103

    
104
  __ add(sp, sp, Operand(kDoubleSize));
105

    
106
  // Make sure no registers have been unexpectedly clobbered
107
  for (--reg_num; reg_num >= 0; --reg_num) {
108
    Register reg = Register::from_code(reg_num);
109
    if (!reg.is(destination_reg)) {
110
      __ ldr(ip, MemOperand(sp, 0));
111
      __ cmp(reg, ip);
112
      __ Assert(eq, kRegisterWasClobbered);
113
      __ add(sp, sp, Operand(kPointerSize));
114
    }
115
  }
116

    
117
  __ add(sp, sp, Operand(kDoubleSize));
118

    
119
  if (!destination_reg.is(r0))
120
    __ mov(r0, destination_reg);
121

    
122
  // Restore callee save registers.
123
  __ Pop(lr);
124
  __ Pop(r7, r6, r5, r4);
125

    
126
  __ Ret(0);
127

    
128
  CodeDesc desc;
129
  masm.GetCode(&desc);
130
  CPU::FlushICache(buffer, actual_size);
131
  return (reinterpret_cast<ConvertDToIFunc>(
132
      reinterpret_cast<intptr_t>(buffer)));
133
}
134

    
135
#undef __
136

    
137

    
138
static Isolate* GetIsolateFrom(LocalContext* context) {
139
  return reinterpret_cast<Isolate*>((*context)->GetIsolate());
140
}
141

    
142

    
143
int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
144
                                    double from) {
145
#ifdef USE_SIMULATOR
146
  return CALL_GENERATED_FP_INT(func, from, 0);
147
#else
148
  return (*func)(from);
149
#endif
150
}
151

    
152

    
153
TEST(ConvertDToI) {
154
  CcTest::InitializeVM();
155
  LocalContext context;
156
  Isolate* isolate = GetIsolateFrom(&context);
157
  HandleScope scope(isolate);
158

    
159
#if DEBUG
160
  // Verify that the tests actually work with the C version. In the release
161
  // code, the compiler optimizes it away because it's all constant, but does it
162
  // wrong, triggering an assert on gcc.
163
  RunAllTruncationTests(&ConvertDToICVersion);
164
#endif
165

    
166
  Register source_registers[] = {sp, r0, r1, r2, r3, r4, r5, r6, r7};
167
  Register dest_registers[] = {r0, r1, r2, r3, r4, r5, r6, r7};
168

    
169
  for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
170
    for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
171
      RunAllTruncationTests(
172
          RunGeneratedCodeCallWrapper,
173
          MakeConvertDToIFuncTrampoline(isolate,
174
                                        source_registers[s],
175
                                        dest_registers[d],
176
                                        false));
177
      RunAllTruncationTests(
178
          RunGeneratedCodeCallWrapper,
179
          MakeConvertDToIFuncTrampoline(isolate,
180
                                        source_registers[s],
181
                                        dest_registers[d],
182
                                        true));
183
    }
184
  }
185
}