OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 | 29 |
30 #include "src/v8.h" | 30 #include "src/v8.h" |
31 #include "test/cctest/cctest.h" | 31 #include "test/cctest/cctest.h" |
32 | 32 |
33 #include "src/macro-assembler.h" | 33 #include "src/macro-assembler.h" |
34 #include "src/mips/macro-assembler-mips.h" | 34 #include "src/mips64/macro-assembler-mips64.h" |
35 #include "src/mips/simulator-mips.h" | 35 #include "src/mips64/simulator-mips64.h" |
36 | 36 |
37 | 37 |
38 using namespace v8::internal; | 38 using namespace v8::internal; |
39 | 39 |
40 typedef void* (*F)(int x, int y, int p2, int p3, int p4); | 40 typedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4); |
41 | 41 |
42 #define __ masm-> | 42 #define __ masm-> |
43 | 43 |
44 | 44 |
45 static byte to_non_zero(int n) { | 45 static byte to_non_zero(int n) { |
46 return static_cast<unsigned>(n) % 255 + 1; | 46 return static_cast<unsigned>(n) % 255 + 1; |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 static bool all_zeroes(const byte* beg, const byte* end) { | 50 static bool all_zeroes(const byte* beg, const byte* end) { |
(...skipping 28 matching lines...) Expand all Loading... |
79 // Storage for a0 and a1. | 79 // Storage for a0 and a1. |
80 byte* a0_; | 80 byte* a0_; |
81 byte* a1_; | 81 byte* a1_; |
82 | 82 |
83 MacroAssembler assembler(isolate, NULL, 0); | 83 MacroAssembler assembler(isolate, NULL, 0); |
84 MacroAssembler* masm = &assembler; | 84 MacroAssembler* masm = &assembler; |
85 | 85 |
86 // Code to be generated: The stuff in CopyBytes followed by a store of a0 and | 86 // Code to be generated: The stuff in CopyBytes followed by a store of a0 and |
87 // a1, respectively. | 87 // a1, respectively. |
88 __ CopyBytes(a0, a1, a2, a3); | 88 __ CopyBytes(a0, a1, a2, a3); |
89 __ li(a2, Operand(reinterpret_cast<int>(&a0_))); | 89 __ li(a2, Operand(reinterpret_cast<int64_t>(&a0_))); |
90 __ li(a3, Operand(reinterpret_cast<int>(&a1_))); | 90 __ li(a3, Operand(reinterpret_cast<int64_t>(&a1_))); |
91 __ sw(a0, MemOperand(a2)); | 91 __ sd(a0, MemOperand(a2)); |
92 __ jr(ra); | 92 __ jr(ra); |
93 __ sw(a1, MemOperand(a3)); | 93 __ sd(a1, MemOperand(a3)); |
94 | 94 |
95 CodeDesc desc; | 95 CodeDesc desc; |
96 masm->GetCode(&desc); | 96 masm->GetCode(&desc); |
97 Handle<Code> code = isolate->factory()->NewCode( | 97 Handle<Code> code = isolate->factory()->NewCode( |
98 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 98 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
99 | 99 |
100 ::F f = FUNCTION_CAST< ::F>(code->entry()); | 100 ::F f = FUNCTION_CAST< ::F>(code->entry()); |
101 | 101 |
102 // Initialise source data with non-zero bytes. | 102 // Initialise source data with non-zero bytes. |
103 for (int i = 0; i < data_size; i++) { | 103 for (int i = 0; i < data_size; i++) { |
104 src_buffer[i] = to_non_zero(i); | 104 src_buffer[i] = to_non_zero(i); |
105 } | 105 } |
106 | 106 |
107 const int fuzz = 11; | 107 const int fuzz = 11; |
108 | 108 |
109 for (int size = 0; size < 600; size++) { | 109 for (int size = 0; size < 600; size++) { |
110 for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) { | 110 for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) { |
111 for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { | 111 for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { |
112 memset(dest_buffer, 0, data_size); | 112 memset(dest_buffer, 0, data_size); |
113 CHECK(dest + size < dest_buffer + data_size); | 113 CHECK(dest + size < dest_buffer + data_size); |
114 (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src), | 114 (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(src), |
115 reinterpret_cast<int>(dest), size, 0, 0); | 115 reinterpret_cast<int64_t>(dest), |
| 116 size, 0, 0); |
116 // a0 and a1 should point at the first byte after the copied data. | 117 // a0 and a1 should point at the first byte after the copied data. |
117 CHECK_EQ(src + size, a0_); | 118 CHECK_EQ(src + size, a0_); |
118 CHECK_EQ(dest + size, a1_); | 119 CHECK_EQ(dest + size, a1_); |
119 // Check that we haven't written outside the target area. | 120 // Check that we haven't written outside the target area. |
120 CHECK(all_zeroes(dest_buffer, dest)); | 121 CHECK(all_zeroes(dest_buffer, dest)); |
121 CHECK(all_zeroes(dest + size, dest_buffer + data_size)); | 122 CHECK(all_zeroes(dest + size, dest_buffer + data_size)); |
122 // Check the target area. | 123 // Check the target area. |
123 CHECK_EQ(0, memcmp(src, dest, size)); | 124 CHECK_EQ(0, memcmp(src, dest, size)); |
124 } | 125 } |
125 } | 126 } |
126 } | 127 } |
127 | 128 |
128 // Check that the source data hasn't been clobbered. | 129 // Check that the source data hasn't been clobbered. |
129 for (int i = 0; i < data_size; i++) { | 130 for (int i = 0; i < data_size; i++) { |
130 CHECK(src_buffer[i] == to_non_zero(i)); | 131 CHECK(src_buffer[i] == to_non_zero(i)); |
131 } | 132 } |
132 } | 133 } |
133 | 134 |
134 | 135 |
135 static void TestNaN(const char *code) { | 136 TEST(LoadConstants) { |
136 // NaN value is different on MIPS and x86 architectures, and TEST(NaNx) | 137 CcTest::InitializeVM(); |
137 // tests checks the case where a x86 NaN value is serialized into the | 138 Isolate* isolate = Isolate::Current(); |
138 // snapshot on the simulator during cross compilation. | 139 HandleScope handles(isolate); |
139 v8::HandleScope scope(CcTest::isolate()); | |
140 v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION); | |
141 v8::Context::Scope context_scope(context); | |
142 | 140 |
143 v8::Local<v8::Script> script = v8::Script::Compile(v8_str(code)); | 141 int64_t refConstants[64]; |
144 v8::Local<v8::Object> result = v8::Local<v8::Object>::Cast(script->Run()); | 142 int64_t result[64]; |
145 // Have to populate the handle manually, as it's not Cast-able. | 143 |
146 i::Handle<i::JSObject> o = | 144 int64_t mask = 1; |
147 v8::Utils::OpenHandle<v8::Object, i::JSObject>(result); | 145 for (int i = 0; i < 64; i++) { |
148 i::Handle<i::JSArray> array1(reinterpret_cast<i::JSArray*>(*o)); | 146 refConstants[i] = ~(mask << i); |
149 i::FixedDoubleArray* a = i::FixedDoubleArray::cast(array1->elements()); | 147 } |
150 double value = a->get_scalar(0); | 148 |
151 CHECK(std::isnan(value) && | 149 MacroAssembler assembler(isolate, NULL, 0); |
152 i::BitCast<uint64_t>(value) == | 150 MacroAssembler* masm = &assembler; |
153 i::BitCast<uint64_t>( | 151 |
154 i::FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 152 __ mov(a4, a0); |
| 153 for (int i = 0; i < 64; i++) { |
| 154 // Load constant. |
| 155 __ li(a5, Operand(refConstants[i])); |
| 156 __ sd(a5, MemOperand(a4)); |
| 157 __ Daddu(a4, a4, Operand(kPointerSize)); |
| 158 } |
| 159 |
| 160 __ jr(ra); |
| 161 __ nop(); |
| 162 |
| 163 CodeDesc desc; |
| 164 masm->GetCode(&desc); |
| 165 Handle<Code> code = isolate->factory()->NewCode( |
| 166 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 167 |
| 168 ::F f = FUNCTION_CAST< ::F>(code->entry()); |
| 169 (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(result), |
| 170 0, 0, 0, 0); |
| 171 // Check results. |
| 172 for (int i = 0; i < 64; i++) { |
| 173 CHECK(refConstants[i] == result[i]); |
| 174 } |
155 } | 175 } |
156 | 176 |
157 | 177 |
158 TEST(NaN0) { | 178 TEST(LoadAddress) { |
159 TestNaN( | 179 CcTest::InitializeVM(); |
160 "var result;" | 180 Isolate* isolate = Isolate::Current(); |
161 "for (var i = 0; i < 2; i++) {" | 181 HandleScope handles(isolate); |
162 " result = new Array(Number.NaN, Number.POSITIVE_INFINITY);" | 182 |
163 "}" | 183 MacroAssembler assembler(isolate, NULL, 0); |
164 "result;"); | 184 MacroAssembler* masm = &assembler; |
| 185 Label to_jump, skip; |
| 186 __ mov(a4, a0); |
| 187 |
| 188 __ Branch(&skip); |
| 189 __ bind(&to_jump); |
| 190 __ nop(); |
| 191 __ nop(); |
| 192 __ jr(ra); |
| 193 __ nop(); |
| 194 __ bind(&skip); |
| 195 __ li(a4, Operand(masm->jump_address(&to_jump)), ADDRESS_LOAD); |
| 196 int check_size = masm->InstructionsGeneratedSince(&skip); |
| 197 CHECK_EQ(check_size, 4); |
| 198 __ jr(a4); |
| 199 __ nop(); |
| 200 __ stop("invalid"); |
| 201 __ stop("invalid"); |
| 202 __ stop("invalid"); |
| 203 __ stop("invalid"); |
| 204 __ stop("invalid"); |
| 205 |
| 206 |
| 207 CodeDesc desc; |
| 208 masm->GetCode(&desc); |
| 209 Handle<Code> code = isolate->factory()->NewCode( |
| 210 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 211 |
| 212 ::F f = FUNCTION_CAST< ::F>(code->entry()); |
| 213 (void) CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0); |
| 214 // Check results. |
165 } | 215 } |
166 | 216 |
167 | |
168 TEST(NaN1) { | |
169 TestNaN( | |
170 "var result;" | |
171 "for (var i = 0; i < 2; i++) {" | |
172 " result = [NaN];" | |
173 "}" | |
174 "result;"); | |
175 } | |
176 | |
177 | |
178 #undef __ | 217 #undef __ |
OLD | NEW |