OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 12 matching lines...) Expand all Loading... |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
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 "src/v8.h" | 28 #include "src/v8.h" |
29 | 29 |
30 #include "src/disassembler.h" | 30 #include "src/disassembler.h" |
31 #include "src/factory.h" | 31 #include "src/factory.h" |
32 #include "src/macro-assembler.h" | 32 #include "src/macro-assembler.h" |
33 #include "src/mips/macro-assembler-mips.h" | 33 #include "src/mips64/macro-assembler-mips64.h" |
34 #include "src/mips/simulator-mips.h" | 34 #include "src/mips64/simulator-mips64.h" |
35 | 35 |
36 #include "test/cctest/cctest.h" | 36 #include "test/cctest/cctest.h" |
37 | 37 |
38 using namespace v8::internal; | 38 using namespace v8::internal; |
39 | 39 |
40 | 40 |
41 // Define these function prototypes to match JSEntryFunction in execution.cc. | 41 // Define these function prototypes to match JSEntryFunction in execution.cc. |
42 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); | 42 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
43 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); | 43 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
44 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); | 44 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
(...skipping 12 matching lines...) Expand all Loading... |
57 // Addition. | 57 // Addition. |
58 __ addu(v0, a0, a1); | 58 __ addu(v0, a0, a1); |
59 __ jr(ra); | 59 __ jr(ra); |
60 __ nop(); | 60 __ nop(); |
61 | 61 |
62 CodeDesc desc; | 62 CodeDesc desc; |
63 assm.GetCode(&desc); | 63 assm.GetCode(&desc); |
64 Handle<Code> code = isolate->factory()->NewCode( | 64 Handle<Code> code = isolate->factory()->NewCode( |
65 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 65 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
66 F2 f = FUNCTION_CAST<F2>(code->entry()); | 66 F2 f = FUNCTION_CAST<F2>(code->entry()); |
67 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); | 67 int64_t res = |
68 ::printf("f() = %d\n", res); | 68 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); |
69 CHECK_EQ(0xabc, res); | 69 ::printf("f() = %ld\n", res); |
| 70 CHECK_EQ(0xabcL, res); |
70 } | 71 } |
71 | 72 |
72 | 73 |
73 TEST(MIPS1) { | 74 TEST(MIPS1) { |
74 CcTest::InitializeVM(); | 75 CcTest::InitializeVM(); |
75 Isolate* isolate = CcTest::i_isolate(); | 76 Isolate* isolate = CcTest::i_isolate(); |
76 HandleScope scope(isolate); | 77 HandleScope scope(isolate); |
77 | 78 |
78 MacroAssembler assm(isolate, NULL, 0); | 79 MacroAssembler assm(isolate, NULL, 0); |
79 Label L, C; | 80 Label L, C; |
80 | 81 |
81 __ mov(a1, a0); | 82 __ mov(a1, a0); |
82 __ li(v0, 0); | 83 __ li(v0, 0); |
83 __ b(&C); | 84 __ b(&C); |
84 __ nop(); | 85 __ nop(); |
85 | 86 |
86 __ bind(&L); | 87 __ bind(&L); |
87 __ addu(v0, v0, a1); | 88 __ addu(v0, v0, a1); |
88 __ addiu(a1, a1, -1); | 89 __ addiu(a1, a1, -1); |
89 | 90 |
90 __ bind(&C); | 91 __ bind(&C); |
91 __ xori(v1, a1, 0); | 92 __ xori(v1, a1, 0); |
92 __ Branch(&L, ne, v1, Operand(0)); | 93 __ Branch(&L, ne, v1, Operand((int64_t)0)); |
93 __ nop(); | 94 __ nop(); |
94 | 95 |
95 __ jr(ra); | 96 __ jr(ra); |
96 __ nop(); | 97 __ nop(); |
97 | 98 |
98 CodeDesc desc; | 99 CodeDesc desc; |
99 assm.GetCode(&desc); | 100 assm.GetCode(&desc); |
100 Handle<Code> code = isolate->factory()->NewCode( | 101 Handle<Code> code = isolate->factory()->NewCode( |
101 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 102 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
102 F1 f = FUNCTION_CAST<F1>(code->entry()); | 103 F1 f = FUNCTION_CAST<F1>(code->entry()); |
103 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); | 104 int64_t res = |
104 ::printf("f() = %d\n", res); | 105 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); |
105 CHECK_EQ(1275, res); | 106 ::printf("f() = %ld\n", res); |
| 107 CHECK_EQ(1275L, res); |
106 } | 108 } |
107 | 109 |
108 | 110 |
109 TEST(MIPS2) { | 111 TEST(MIPS2) { |
110 CcTest::InitializeVM(); | 112 CcTest::InitializeVM(); |
111 Isolate* isolate = CcTest::i_isolate(); | 113 Isolate* isolate = CcTest::i_isolate(); |
112 HandleScope scope(isolate); | 114 HandleScope scope(isolate); |
113 | 115 |
114 MacroAssembler assm(isolate, NULL, 0); | 116 MacroAssembler assm(isolate, NULL, 0); |
115 | 117 |
116 Label exit, error; | 118 Label exit, error; |
117 | 119 |
118 // ----- Test all instructions. | 120 // ----- Test all instructions. |
119 | 121 |
120 // Test lui, ori, and addiu, used in the li pseudo-instruction. | 122 // Test lui, ori, and addiu, used in the li pseudo-instruction. |
121 // This way we can then safely load registers with chosen values. | 123 // This way we can then safely load registers with chosen values. |
122 | 124 |
123 __ ori(t0, zero_reg, 0); | 125 __ ori(a4, zero_reg, 0); |
124 __ lui(t0, 0x1234); | 126 __ lui(a4, 0x1234); |
125 __ ori(t0, t0, 0); | 127 __ ori(a4, a4, 0); |
126 __ ori(t0, t0, 0x0f0f); | 128 __ ori(a4, a4, 0x0f0f); |
127 __ ori(t0, t0, 0xf0f0); | 129 __ ori(a4, a4, 0xf0f0); |
128 __ addiu(t1, t0, 1); | 130 __ addiu(a5, a4, 1); |
129 __ addiu(t2, t1, -0x10); | 131 __ addiu(a6, a5, -0x10); |
130 | 132 |
131 // Load values in temporary registers. | 133 // Load values in temporary registers. |
132 __ li(t0, 0x00000004); | 134 __ li(a4, 0x00000004); |
133 __ li(t1, 0x00001234); | 135 __ li(a5, 0x00001234); |
134 __ li(t2, 0x12345678); | 136 __ li(a6, 0x12345678); |
135 __ li(t3, 0x7fffffff); | 137 __ li(a7, 0x7fffffff); |
136 __ li(t4, 0xfffffffc); | 138 __ li(t0, 0xfffffffc); |
137 __ li(t5, 0xffffedcc); | 139 __ li(t1, 0xffffedcc); |
138 __ li(t6, 0xedcba988); | 140 __ li(t2, 0xedcba988); |
139 __ li(t7, 0x80000000); | 141 __ li(t3, 0x80000000); |
140 | 142 |
141 // SPECIAL class. | 143 // SPECIAL class. |
142 __ srl(v0, t2, 8); // 0x00123456 | 144 __ srl(v0, a6, 8); // 0x00123456 |
143 __ sll(v0, v0, 11); // 0x91a2b000 | 145 __ sll(v0, v0, 11); // 0x91a2b000 |
144 __ sra(v0, v0, 3); // 0xf2345600 | 146 __ sra(v0, v0, 3); // 0xf2345600 |
145 __ srav(v0, v0, t0); // 0xff234560 | 147 __ srav(v0, v0, a4); // 0xff234560 |
146 __ sllv(v0, v0, t0); // 0xf2345600 | 148 __ sllv(v0, v0, a4); // 0xf2345600 |
147 __ srlv(v0, v0, t0); // 0x0f234560 | 149 __ srlv(v0, v0, a4); // 0x0f234560 |
148 __ Branch(&error, ne, v0, Operand(0x0f234560)); | 150 __ Branch(&error, ne, v0, Operand(0x0f234560)); |
149 __ nop(); | 151 __ nop(); |
150 | 152 |
151 __ addu(v0, t0, t1); // 0x00001238 | 153 __ addu(v0, a4, a5); // 0x00001238 |
152 __ subu(v0, v0, t0); // 0x00001234 | 154 __ subu(v0, v0, a4); // 0x00001234 |
153 __ Branch(&error, ne, v0, Operand(0x00001234)); | 155 __ Branch(&error, ne, v0, Operand(0x00001234)); |
154 __ nop(); | 156 __ nop(); |
155 __ addu(v1, t3, t0); | 157 __ addu(v1, a7, a4); // 32bit addu result is sign-extended into 64bit reg. |
156 __ Branch(&error, ne, v1, Operand(0x80000003)); | 158 __ Branch(&error, ne, v1, Operand(0xffffffff80000003)); |
157 __ nop(); | 159 __ nop(); |
158 __ subu(v1, t7, t0); // 0x7ffffffc | 160 __ subu(v1, t3, a4); // 0x7ffffffc |
159 __ Branch(&error, ne, v1, Operand(0x7ffffffc)); | 161 __ Branch(&error, ne, v1, Operand(0x7ffffffc)); |
160 __ nop(); | 162 __ nop(); |
161 | 163 |
162 __ and_(v0, t1, t2); // 0x00001230 | 164 __ and_(v0, a5, a6); // 0x0000000000001230 |
163 __ or_(v0, v0, t1); // 0x00001234 | 165 __ or_(v0, v0, a5); // 0x0000000000001234 |
164 __ xor_(v0, v0, t2); // 0x1234444c | 166 __ xor_(v0, v0, a6); // 0x000000001234444c |
165 __ nor(v0, v0, t2); // 0xedcba987 | 167 __ nor(v0, v0, a6); // 0xffffffffedcba987 |
166 __ Branch(&error, ne, v0, Operand(0xedcba983)); | 168 __ Branch(&error, ne, v0, Operand(0xffffffffedcba983)); |
167 __ nop(); | 169 __ nop(); |
168 | 170 |
169 __ slt(v0, t7, t3); | 171 // Shift both 32bit number to left, to preserve meaning of next comparison. |
| 172 __ dsll32(a7, a7, 0); |
| 173 __ dsll32(t3, t3, 0); |
| 174 |
| 175 __ slt(v0, t3, a7); |
170 __ Branch(&error, ne, v0, Operand(0x1)); | 176 __ Branch(&error, ne, v0, Operand(0x1)); |
171 __ nop(); | 177 __ nop(); |
172 __ sltu(v0, t7, t3); | 178 __ sltu(v0, t3, a7); |
173 __ Branch(&error, ne, v0, Operand(0x0)); | 179 __ Branch(&error, ne, v0, Operand(zero_reg)); |
174 __ nop(); | 180 __ nop(); |
| 181 |
| 182 // Restore original values in registers. |
| 183 __ dsrl32(a7, a7, 0); |
| 184 __ dsrl32(t3, t3, 0); |
175 // End of SPECIAL class. | 185 // End of SPECIAL class. |
176 | 186 |
177 __ addiu(v0, zero_reg, 0x7421); // 0x00007421 | 187 __ addiu(v0, zero_reg, 0x7421); // 0x00007421 |
178 __ addiu(v0, v0, -0x1); // 0x00007420 | 188 __ addiu(v0, v0, -0x1); // 0x00007420 |
179 __ addiu(v0, v0, -0x20); // 0x00007400 | 189 __ addiu(v0, v0, -0x20); // 0x00007400 |
180 __ Branch(&error, ne, v0, Operand(0x00007400)); | 190 __ Branch(&error, ne, v0, Operand(0x00007400)); |
181 __ nop(); | 191 __ nop(); |
182 __ addiu(v1, t3, 0x1); // 0x80000000 | 192 __ addiu(v1, a7, 0x1); // 0x80000000 - result is sign-extended. |
183 __ Branch(&error, ne, v1, Operand(0x80000000)); | 193 __ Branch(&error, ne, v1, Operand(0xffffffff80000000)); |
184 __ nop(); | 194 __ nop(); |
185 | 195 |
186 __ slti(v0, t1, 0x00002000); // 0x1 | 196 __ slti(v0, a5, 0x00002000); // 0x1 |
187 __ slti(v0, v0, 0xffff8000); // 0x0 | 197 __ slti(v0, v0, 0xffff8000); // 0x0 |
188 __ Branch(&error, ne, v0, Operand(0x0)); | 198 __ Branch(&error, ne, v0, Operand(zero_reg)); |
189 __ nop(); | 199 __ nop(); |
190 __ sltiu(v0, t1, 0x00002000); // 0x1 | 200 __ sltiu(v0, a5, 0x00002000); // 0x1 |
191 __ sltiu(v0, v0, 0x00008000); // 0x1 | 201 __ sltiu(v0, v0, 0x00008000); // 0x1 |
192 __ Branch(&error, ne, v0, Operand(0x1)); | 202 __ Branch(&error, ne, v0, Operand(0x1)); |
193 __ nop(); | 203 __ nop(); |
194 | 204 |
195 __ andi(v0, t1, 0xf0f0); // 0x00001030 | 205 __ andi(v0, a5, 0xf0f0); // 0x00001030 |
196 __ ori(v0, v0, 0x8a00); // 0x00009a30 | 206 __ ori(v0, v0, 0x8a00); // 0x00009a30 |
197 __ xori(v0, v0, 0x83cc); // 0x000019fc | 207 __ xori(v0, v0, 0x83cc); // 0x000019fc |
198 __ Branch(&error, ne, v0, Operand(0x000019fc)); | 208 __ Branch(&error, ne, v0, Operand(0x000019fc)); |
199 __ nop(); | 209 __ nop(); |
200 __ lui(v1, 0x8123); // 0x81230000 | 210 __ lui(v1, 0x8123); // Result is sign-extended into 64bit register. |
201 __ Branch(&error, ne, v1, Operand(0x81230000)); | 211 __ Branch(&error, ne, v1, Operand(0xffffffff81230000)); |
202 __ nop(); | 212 __ nop(); |
203 | 213 |
204 // Bit twiddling instructions & conditional moves. | 214 // Bit twiddling instructions & conditional moves. |
205 // Uses t0-t7 as set above. | 215 // Uses a4-t3 as set above. |
206 __ Clz(v0, t0); // 29 | 216 __ Clz(v0, a4); // 29 |
207 __ Clz(v1, t1); // 19 | 217 __ Clz(v1, a5); // 19 |
208 __ addu(v0, v0, v1); // 48 | 218 __ addu(v0, v0, v1); // 48 |
209 __ Clz(v1, t2); // 3 | 219 __ Clz(v1, a6); // 3 |
210 __ addu(v0, v0, v1); // 51 | 220 __ addu(v0, v0, v1); // 51 |
211 __ Clz(v1, t7); // 0 | 221 __ Clz(v1, t3); // 0 |
212 __ addu(v0, v0, v1); // 51 | 222 __ addu(v0, v0, v1); // 51 |
213 __ Branch(&error, ne, v0, Operand(51)); | 223 __ Branch(&error, ne, v0, Operand(51)); |
214 __ Movn(a0, t3, t0); // Move a0<-t3 (t0 is NOT 0). | 224 __ Movn(a0, a7, a4); // Move a0<-a7 (a4 is NOT 0). |
215 __ Ins(a0, t1, 12, 8); // 0x7ff34fff | 225 __ Ins(a0, a5, 12, 8); // 0x7ff34fff |
216 __ Branch(&error, ne, a0, Operand(0x7ff34fff)); | 226 __ Branch(&error, ne, a0, Operand(0x7ff34fff)); |
217 __ Movz(a0, t6, t7); // a0 not updated (t7 is NOT 0). | 227 __ Movz(a0, t2, t3); // a0 not updated (t3 is NOT 0). |
218 __ Ext(a1, a0, 8, 12); // 0x34f | 228 __ Ext(a1, a0, 8, 12); // 0x34f |
219 __ Branch(&error, ne, a1, Operand(0x34f)); | 229 __ Branch(&error, ne, a1, Operand(0x34f)); |
220 __ Movz(a0, t6, v1); // a0<-t6, v0 is 0, from 8 instr back. | 230 __ Movz(a0, t2, v1); // a0<-t2, v0 is 0, from 8 instr back. |
221 __ Branch(&error, ne, a0, Operand(t6)); | 231 __ Branch(&error, ne, a0, Operand(t2)); |
222 | 232 |
223 // Everything was correctly executed. Load the expected result. | 233 // Everything was correctly executed. Load the expected result. |
224 __ li(v0, 0x31415926); | 234 __ li(v0, 0x31415926); |
225 __ b(&exit); | 235 __ b(&exit); |
226 __ nop(); | 236 __ nop(); |
227 | 237 |
228 __ bind(&error); | 238 __ bind(&error); |
229 // Got an error. Return a wrong result. | 239 // Got an error. Return a wrong result. |
230 __ li(v0, 666); | 240 __ li(v0, 666); |
231 | 241 |
232 __ bind(&exit); | 242 __ bind(&exit); |
233 __ jr(ra); | 243 __ jr(ra); |
234 __ nop(); | 244 __ nop(); |
235 | 245 |
236 CodeDesc desc; | 246 CodeDesc desc; |
237 assm.GetCode(&desc); | 247 assm.GetCode(&desc); |
238 Handle<Code> code = isolate->factory()->NewCode( | 248 Handle<Code> code = isolate->factory()->NewCode( |
239 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 249 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
240 F2 f = FUNCTION_CAST<F2>(code->entry()); | 250 F2 f = FUNCTION_CAST<F2>(code->entry()); |
241 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); | 251 int64_t res = |
242 ::printf("f() = %d\n", res); | 252 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); |
243 CHECK_EQ(0x31415926, res); | 253 ::printf("f() = %ld\n", res); |
| 254 |
| 255 CHECK_EQ(0x31415926L, res); |
244 } | 256 } |
245 | 257 |
246 | 258 |
247 TEST(MIPS3) { | 259 TEST(MIPS3) { |
248 // Test floating point instructions. | 260 // Test floating point instructions. |
249 CcTest::InitializeVM(); | 261 CcTest::InitializeVM(); |
250 Isolate* isolate = CcTest::i_isolate(); | 262 Isolate* isolate = CcTest::i_isolate(); |
251 HandleScope scope(isolate); | 263 HandleScope scope(isolate); |
252 | 264 |
253 typedef struct { | 265 typedef struct { |
(...skipping 19 matching lines...) Expand all Loading... |
273 __ add_d(f8, f4, f6); | 285 __ add_d(f8, f4, f6); |
274 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b. | 286 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b. |
275 | 287 |
276 __ mov_d(f10, f8); // c | 288 __ mov_d(f10, f8); // c |
277 __ neg_d(f12, f6); // -b | 289 __ neg_d(f12, f6); // -b |
278 __ sub_d(f10, f10, f12); | 290 __ sub_d(f10, f10, f12); |
279 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b). | 291 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b). |
280 | 292 |
281 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a. | 293 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a. |
282 | 294 |
283 __ li(t0, 120); | 295 __ li(a4, 120); |
284 __ mtc1(t0, f14); | 296 __ mtc1(a4, f14); |
285 __ cvt_d_w(f14, f14); // f14 = 120.0. | 297 __ cvt_d_w(f14, f14); // f14 = 120.0. |
286 __ mul_d(f10, f10, f14); | 298 __ mul_d(f10, f10, f14); |
287 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16. | 299 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16. |
288 | 300 |
289 __ div_d(f12, f10, f4); | 301 __ div_d(f12, f10, f4); |
290 __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44. | 302 __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44. |
291 | 303 |
292 __ sqrt_d(f14, f12); | 304 __ sqrt_d(f14, f12); |
293 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) ); | 305 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) ); |
294 // g = sqrt(f) = 10.97451593465515908537 | 306 // g = sqrt(f) = 10.97451593465515908537 |
295 | 307 |
296 if (kArchVariant == kMips32r2) { | 308 if (kArchVariant == kMips64r2) { |
297 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) ); | 309 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) ); |
298 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) ); | 310 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) ); |
299 __ madd_d(f14, f6, f4, f6); | 311 __ madd_d(f14, f6, f4, f6); |
300 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) ); | 312 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) ); |
301 } | 313 } |
302 | 314 |
303 __ jr(ra); | 315 __ jr(ra); |
304 __ nop(); | 316 __ nop(); |
305 | 317 |
306 CodeDesc desc; | 318 CodeDesc desc; |
(...skipping 11 matching lines...) Expand all Loading... |
318 t.i = 2.75; | 330 t.i = 2.75; |
319 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); | 331 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
320 USE(dummy); | 332 USE(dummy); |
321 CHECK_EQ(1.5e14, t.a); | 333 CHECK_EQ(1.5e14, t.a); |
322 CHECK_EQ(1.5e14, t.b); | 334 CHECK_EQ(1.5e14, t.b); |
323 CHECK_EQ(1.50275e14, t.c); | 335 CHECK_EQ(1.50275e14, t.c); |
324 CHECK_EQ(1.50550e14, t.d); | 336 CHECK_EQ(1.50550e14, t.d); |
325 CHECK_EQ(1.8066e16, t.e); | 337 CHECK_EQ(1.8066e16, t.e); |
326 CHECK_EQ(120.44, t.f); | 338 CHECK_EQ(120.44, t.f); |
327 CHECK_EQ(10.97451593465515908537, t.g); | 339 CHECK_EQ(10.97451593465515908537, t.g); |
328 if (kArchVariant == kMips32r2) { | 340 if (kArchVariant == kMips64r2) { |
329 CHECK_EQ(6.875, t.h); | 341 CHECK_EQ(6.875, t.h); |
330 } | 342 } |
331 } | 343 } |
332 | 344 |
333 | 345 |
334 TEST(MIPS4) { | 346 TEST(MIPS4) { |
335 // Test moves between floating point and integer registers. | 347 // Test moves between floating point and integer registers. |
336 CcTest::InitializeVM(); | 348 CcTest::InitializeVM(); |
337 Isolate* isolate = CcTest::i_isolate(); | 349 Isolate* isolate = CcTest::i_isolate(); |
338 HandleScope scope(isolate); | 350 HandleScope scope(isolate); |
339 | 351 |
340 typedef struct { | 352 typedef struct { |
341 double a; | 353 double a; |
342 double b; | 354 double b; |
343 double c; | 355 double c; |
344 } T; | 356 } T; |
345 T t; | 357 T t; |
346 | 358 |
347 Assembler assm(isolate, NULL, 0); | 359 Assembler assm(isolate, NULL, 0); |
348 Label L, C; | 360 Label L, C; |
349 | 361 |
350 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); | 362 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); |
351 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); | 363 __ ldc1(f5, MemOperand(a0, OFFSET_OF(T, b)) ); |
352 | 364 |
353 // Swap f4 and f6, by using four integer registers, t0-t3. | 365 // Swap f4 and f5, by using 3 integer registers, a4-a6, |
354 __ mfc1(t0, f4); | 366 // both two 32-bit chunks, and one 64-bit chunk. |
355 __ mfc1(t1, f5); | 367 // mXhc1 is mips32/64-r2 only, not r1, |
356 __ mfc1(t2, f6); | 368 // but we will not support r1 in practice. |
357 __ mfc1(t3, f7); | 369 __ mfc1(a4, f4); |
| 370 __ mfhc1(a5, f4); |
| 371 __ dmfc1(a6, f5); |
358 | 372 |
359 __ mtc1(t0, f6); | 373 __ mtc1(a4, f5); |
360 __ mtc1(t1, f7); | 374 __ mthc1(a5, f5); |
361 __ mtc1(t2, f4); | 375 __ dmtc1(a6, f4); |
362 __ mtc1(t3, f5); | |
363 | 376 |
364 // Store the swapped f4 and f5 back to memory. | 377 // Store the swapped f4 and f5 back to memory. |
365 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); | 378 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); |
366 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) ); | 379 __ sdc1(f5, MemOperand(a0, OFFSET_OF(T, c)) ); |
367 | 380 |
368 __ jr(ra); | 381 __ jr(ra); |
369 __ nop(); | 382 __ nop(); |
370 | 383 |
371 CodeDesc desc; | 384 CodeDesc desc; |
372 assm.GetCode(&desc); | 385 assm.GetCode(&desc); |
373 Handle<Code> code = isolate->factory()->NewCode( | 386 Handle<Code> code = isolate->factory()->NewCode( |
374 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 387 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
375 F3 f = FUNCTION_CAST<F3>(code->entry()); | 388 F3 f = FUNCTION_CAST<F3>(code->entry()); |
376 t.a = 1.5e22; | 389 t.a = 1.5e22; |
(...skipping 21 matching lines...) Expand all Loading... |
398 int j; | 411 int j; |
399 } T; | 412 } T; |
400 T t; | 413 T t; |
401 | 414 |
402 Assembler assm(isolate, NULL, 0); | 415 Assembler assm(isolate, NULL, 0); |
403 Label L, C; | 416 Label L, C; |
404 | 417 |
405 // Load all structure elements to registers. | 418 // Load all structure elements to registers. |
406 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); | 419 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); |
407 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); | 420 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); |
408 __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) ); | 421 __ lw(a4, MemOperand(a0, OFFSET_OF(T, i)) ); |
409 __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) ); | 422 __ lw(a5, MemOperand(a0, OFFSET_OF(T, j)) ); |
410 | 423 |
411 // Convert double in f4 to int in element i. | 424 // Convert double in f4 to int in element i. |
412 __ cvt_w_d(f8, f4); | 425 __ cvt_w_d(f8, f4); |
413 __ mfc1(t2, f8); | 426 __ mfc1(a6, f8); |
414 __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) ); | 427 __ sw(a6, MemOperand(a0, OFFSET_OF(T, i)) ); |
415 | 428 |
416 // Convert double in f6 to int in element j. | 429 // Convert double in f6 to int in element j. |
417 __ cvt_w_d(f10, f6); | 430 __ cvt_w_d(f10, f6); |
418 __ mfc1(t3, f10); | 431 __ mfc1(a7, f10); |
419 __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) ); | 432 __ sw(a7, MemOperand(a0, OFFSET_OF(T, j)) ); |
420 | 433 |
421 // Convert int in original i (t0) to double in a. | 434 // Convert int in original i (a4) to double in a. |
422 __ mtc1(t0, f12); | 435 __ mtc1(a4, f12); |
423 __ cvt_d_w(f0, f12); | 436 __ cvt_d_w(f0, f12); |
424 __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) ); | 437 __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) ); |
425 | 438 |
426 // Convert int in original j (t1) to double in b. | 439 // Convert int in original j (a5) to double in b. |
427 __ mtc1(t1, f14); | 440 __ mtc1(a5, f14); |
428 __ cvt_d_w(f2, f14); | 441 __ cvt_d_w(f2, f14); |
429 __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) ); | 442 __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) ); |
430 | 443 |
431 __ jr(ra); | 444 __ jr(ra); |
432 __ nop(); | 445 __ nop(); |
433 | 446 |
434 CodeDesc desc; | 447 CodeDesc desc; |
435 assm.GetCode(&desc); | 448 assm.GetCode(&desc); |
436 Handle<Code> code = isolate->factory()->NewCode( | 449 Handle<Code> code = isolate->factory()->NewCode( |
437 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 450 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
(...skipping 27 matching lines...) Expand all Loading... |
465 int32_t r4; | 478 int32_t r4; |
466 int32_t r5; | 479 int32_t r5; |
467 int32_t r6; | 480 int32_t r6; |
468 } T; | 481 } T; |
469 T t; | 482 T t; |
470 | 483 |
471 Assembler assm(isolate, NULL, 0); | 484 Assembler assm(isolate, NULL, 0); |
472 Label L, C; | 485 Label L, C; |
473 | 486 |
474 // Basic word load/store. | 487 // Basic word load/store. |
475 __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) ); | 488 __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) ); |
476 __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) ); | 489 __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) ); |
477 | 490 |
478 // lh with positive data. | 491 // lh with positive data. |
479 __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) ); | 492 __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) ); |
480 __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) ); | 493 __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) ); |
481 | 494 |
482 // lh with negative data. | 495 // lh with negative data. |
483 __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) ); | 496 __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) ); |
484 __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) ); | 497 __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) ); |
485 | 498 |
486 // lhu with negative data. | 499 // lhu with negative data. |
487 __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) ); | 500 __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) ); |
488 __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) ); | 501 __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) ); |
489 | 502 |
490 // lb with negative data. | 503 // lb with negative data. |
491 __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) ); | 504 __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) ); |
492 __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) ); | 505 __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) ); |
493 | 506 |
494 // sh writes only 1/2 of word. | 507 // sh writes only 1/2 of word. |
495 __ lui(t5, 0x3333); | 508 __ lui(t1, 0x3333); |
496 __ ori(t5, t5, 0x3333); | 509 __ ori(t1, t1, 0x3333); |
497 __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) ); | 510 __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) ); |
498 __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) ); | 511 __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) ); |
499 __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) ); | 512 __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) ); |
500 | 513 |
501 __ jr(ra); | 514 __ jr(ra); |
502 __ nop(); | 515 __ nop(); |
503 | 516 |
504 CodeDesc desc; | 517 CodeDesc desc; |
505 assm.GetCode(&desc); | 518 assm.GetCode(&desc); |
506 Handle<Code> code = isolate->factory()->NewCode( | 519 Handle<Code> code = isolate->factory()->NewCode( |
507 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 520 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
508 F3 f = FUNCTION_CAST<F3>(code->entry()); | 521 F3 f = FUNCTION_CAST<F3>(code->entry()); |
509 t.ui = 0x11223344; | 522 t.ui = 0x11223344; |
510 t.si = 0x99aabbcc; | 523 t.si = 0x99aabbcc; |
511 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); | 524 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
512 USE(dummy); | 525 USE(dummy); |
513 | 526 |
514 CHECK_EQ(0x11223344, t.r1); | 527 CHECK_EQ(0x11223344, t.r1); |
515 #if __BYTE_ORDER == __LITTLE_ENDIAN | |
516 CHECK_EQ(0x3344, t.r2); | 528 CHECK_EQ(0x3344, t.r2); |
517 CHECK_EQ(0xffffbbcc, t.r3); | 529 CHECK_EQ(0xffffbbcc, t.r3); |
518 CHECK_EQ(0x0000bbcc, t.r4); | 530 CHECK_EQ(0x0000bbcc, t.r4); |
519 CHECK_EQ(0xffffffcc, t.r5); | 531 CHECK_EQ(0xffffffcc, t.r5); |
520 CHECK_EQ(0x3333bbcc, t.r6); | 532 CHECK_EQ(0x3333bbcc, t.r6); |
521 #elif __BYTE_ORDER == __BIG_ENDIAN | |
522 CHECK_EQ(0x1122, t.r2); | |
523 CHECK_EQ(0xffff99aa, t.r3); | |
524 CHECK_EQ(0x000099aa, t.r4); | |
525 CHECK_EQ(0xffffff99, t.r5); | |
526 CHECK_EQ(0x99aa3333, t.r6); | |
527 #else | |
528 #error Unknown endianness | |
529 #endif | |
530 } | 533 } |
531 | 534 |
532 | 535 |
533 TEST(MIPS7) { | 536 TEST(MIPS7) { |
534 // Test floating point compare and branch instructions. | 537 // Test floating point compare and branch instructions. |
535 CcTest::InitializeVM(); | 538 CcTest::InitializeVM(); |
536 Isolate* isolate = CcTest::i_isolate(); | 539 Isolate* isolate = CcTest::i_isolate(); |
537 HandleScope scope(isolate); | 540 HandleScope scope(isolate); |
538 | 541 |
539 typedef struct { | 542 typedef struct { |
(...skipping 27 matching lines...) Expand all Loading... |
567 __ bc1t(&less_than); | 570 __ bc1t(&less_than); |
568 } else { | 571 } else { |
569 __ c(OLT, D, f6, f4, 2); | 572 __ c(OLT, D, f6, f4, 2); |
570 __ bc1t(&less_than, 2); | 573 __ bc1t(&less_than, 2); |
571 } | 574 } |
572 __ nop(); | 575 __ nop(); |
573 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) ); | 576 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) ); |
574 __ Branch(&outa_here); | 577 __ Branch(&outa_here); |
575 | 578 |
576 __ bind(&less_than); | 579 __ bind(&less_than); |
577 __ Addu(t0, zero_reg, Operand(1)); | 580 __ Addu(a4, zero_reg, Operand(1)); |
578 __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true. | 581 __ sw(a4, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true. |
579 | 582 |
580 | 583 |
581 // This test-case should have additional tests. | 584 // This test-case should have additional tests. |
582 | 585 |
583 __ bind(&outa_here); | 586 __ bind(&outa_here); |
584 | 587 |
585 __ jr(ra); | 588 __ jr(ra); |
586 __ nop(); | 589 __ nop(); |
587 | 590 |
588 CodeDesc desc; | 591 CodeDesc desc; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 int32_t result_rotrv_16; | 629 int32_t result_rotrv_16; |
627 int32_t result_rotrv_20; | 630 int32_t result_rotrv_20; |
628 int32_t result_rotrv_24; | 631 int32_t result_rotrv_24; |
629 int32_t result_rotrv_28; | 632 int32_t result_rotrv_28; |
630 } T; | 633 } T; |
631 T t; | 634 T t; |
632 | 635 |
633 MacroAssembler assm(isolate, NULL, 0); | 636 MacroAssembler assm(isolate, NULL, 0); |
634 | 637 |
635 // Basic word load. | 638 // Basic word load. |
636 __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) ); | 639 __ lw(a4, MemOperand(a0, OFFSET_OF(T, input)) ); |
637 | 640 |
638 // ROTR instruction (called through the Ror macro). | 641 // ROTR instruction (called through the Ror macro). |
639 __ Ror(t1, t0, 0x0004); | 642 __ Ror(a5, a4, 0x0004); |
640 __ Ror(t2, t0, 0x0008); | 643 __ Ror(a6, a4, 0x0008); |
641 __ Ror(t3, t0, 0x000c); | 644 __ Ror(a7, a4, 0x000c); |
642 __ Ror(t4, t0, 0x0010); | 645 __ Ror(t0, a4, 0x0010); |
643 __ Ror(t5, t0, 0x0014); | 646 __ Ror(t1, a4, 0x0014); |
644 __ Ror(t6, t0, 0x0018); | 647 __ Ror(t2, a4, 0x0018); |
645 __ Ror(t7, t0, 0x001c); | 648 __ Ror(t3, a4, 0x001c); |
646 | 649 |
647 // Basic word store. | 650 // Basic word store. |
648 __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) ); | 651 __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) ); |
649 __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) ); | 652 __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) ); |
650 __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) ); | 653 __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) ); |
651 __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) ); | 654 __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) ); |
652 __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) ); | 655 __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) ); |
653 __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) ); | 656 __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) ); |
654 __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) ); | 657 __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) ); |
655 | 658 |
656 // ROTRV instruction (called through the Ror macro). | 659 // ROTRV instruction (called through the Ror macro). |
657 __ li(t7, 0x0004); | 660 __ li(t3, 0x0004); |
658 __ Ror(t1, t0, t7); | 661 __ Ror(a5, a4, t3); |
659 __ li(t7, 0x0008); | 662 __ li(t3, 0x0008); |
660 __ Ror(t2, t0, t7); | 663 __ Ror(a6, a4, t3); |
661 __ li(t7, 0x000C); | 664 __ li(t3, 0x000C); |
662 __ Ror(t3, t0, t7); | 665 __ Ror(a7, a4, t3); |
663 __ li(t7, 0x0010); | 666 __ li(t3, 0x0010); |
664 __ Ror(t4, t0, t7); | 667 __ Ror(t0, a4, t3); |
665 __ li(t7, 0x0014); | 668 __ li(t3, 0x0014); |
666 __ Ror(t5, t0, t7); | 669 __ Ror(t1, a4, t3); |
667 __ li(t7, 0x0018); | 670 __ li(t3, 0x0018); |
668 __ Ror(t6, t0, t7); | 671 __ Ror(t2, a4, t3); |
669 __ li(t7, 0x001C); | 672 __ li(t3, 0x001C); |
670 __ Ror(t7, t0, t7); | 673 __ Ror(t3, a4, t3); |
671 | 674 |
672 // Basic word store. | 675 // Basic word store. |
673 __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) ); | 676 __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) ); |
674 __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) ); | 677 __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) ); |
675 __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) ); | 678 __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) ); |
676 __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) ); | 679 __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) ); |
677 __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) ); | 680 __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) ); |
678 __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) ); | 681 __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) ); |
679 __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) ); | 682 __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) ); |
680 | 683 |
681 __ jr(ra); | 684 __ jr(ra); |
682 __ nop(); | 685 __ nop(); |
683 | 686 |
684 CodeDesc desc; | 687 CodeDesc desc; |
685 assm.GetCode(&desc); | 688 assm.GetCode(&desc); |
686 Handle<Code> code = isolate->factory()->NewCode( | 689 Handle<Code> code = isolate->factory()->NewCode( |
687 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 690 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
688 F3 f = FUNCTION_CAST<F3>(code->entry()); | 691 F3 f = FUNCTION_CAST<F3>(code->entry()); |
689 t.input = 0x12345678; | 692 t.input = 0x12345678; |
(...skipping 19 matching lines...) Expand all Loading... |
709 | 712 |
710 TEST(MIPS9) { | 713 TEST(MIPS9) { |
711 // Test BRANCH improvements. | 714 // Test BRANCH improvements. |
712 CcTest::InitializeVM(); | 715 CcTest::InitializeVM(); |
713 Isolate* isolate = CcTest::i_isolate(); | 716 Isolate* isolate = CcTest::i_isolate(); |
714 HandleScope scope(isolate); | 717 HandleScope scope(isolate); |
715 | 718 |
716 MacroAssembler assm(isolate, NULL, 0); | 719 MacroAssembler assm(isolate, NULL, 0); |
717 Label exit, exit2, exit3; | 720 Label exit, exit2, exit3; |
718 | 721 |
719 __ Branch(&exit, ge, a0, Operand(0x00000000)); | 722 __ Branch(&exit, ge, a0, Operand(zero_reg)); |
720 __ Branch(&exit2, ge, a0, Operand(0x00001FFF)); | 723 __ Branch(&exit2, ge, a0, Operand(0x00001FFF)); |
721 __ Branch(&exit3, ge, a0, Operand(0x0001FFFF)); | 724 __ Branch(&exit3, ge, a0, Operand(0x0001FFFF)); |
722 | 725 |
723 __ bind(&exit); | 726 __ bind(&exit); |
724 __ bind(&exit2); | 727 __ bind(&exit2); |
725 __ bind(&exit3); | 728 __ bind(&exit3); |
726 __ jr(ra); | 729 __ jr(ra); |
727 __ nop(); | 730 __ nop(); |
728 | 731 |
729 CodeDesc desc; | 732 CodeDesc desc; |
730 assm.GetCode(&desc); | 733 assm.GetCode(&desc); |
731 isolate->factory()->NewCode( | 734 isolate->factory()->NewCode( |
732 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 735 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
733 } | 736 } |
734 | 737 |
735 | 738 |
736 TEST(MIPS10) { | 739 TEST(MIPS10) { |
737 // Test conversions between doubles and long integers. | 740 // Test conversions between doubles and long integers. |
738 // Test hos the long ints map to FP regs pairs. | 741 // Test hos the long ints map to FP regs pairs. |
739 CcTest::InitializeVM(); | 742 CcTest::InitializeVM(); |
740 Isolate* isolate = CcTest::i_isolate(); | 743 Isolate* isolate = CcTest::i_isolate(); |
741 HandleScope scope(isolate); | 744 HandleScope scope(isolate); |
742 | 745 |
743 typedef struct { | 746 typedef struct { |
744 double a; | 747 double a; |
| 748 double a_converted; |
745 double b; | 749 double b; |
746 int32_t dbl_mant; | 750 int32_t dbl_mant; |
747 int32_t dbl_exp; | 751 int32_t dbl_exp; |
748 int32_t word; | 752 int32_t long_hi; |
749 int32_t b_word; | 753 int32_t long_lo; |
| 754 int64_t long_as_int64; |
| 755 int32_t b_long_hi; |
| 756 int32_t b_long_lo; |
| 757 int64_t b_long_as_int64; |
750 } T; | 758 } T; |
751 T t; | 759 T t; |
752 | 760 |
753 Assembler assm(isolate, NULL, 0); | 761 Assembler assm(isolate, NULL, 0); |
754 Label L, C; | 762 Label L, C; |
755 | 763 |
756 if (kArchVariant == kMips32r2) { | 764 if (kArchVariant == kMips64r2) { |
| 765 // Rewritten for FR=1 FPU mode: |
| 766 // - 32 FP regs of 64-bits each, no odd/even pairs. |
| 767 // - Note that cvt_l_d/cvt_d_l ARE legal in FR=1 mode. |
757 // Load all structure elements to registers. | 768 // Load all structure elements to registers. |
758 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a))); | 769 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a))); |
759 | 770 |
760 // Save the raw bits of the double. | 771 // Save the raw bits of the double. |
761 __ mfc1(t0, f0); | 772 __ mfc1(a4, f0); |
762 __ mfc1(t1, f1); | 773 __ mfhc1(a5, f0); |
763 __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant))); | 774 __ sw(a4, MemOperand(a0, OFFSET_OF(T, dbl_mant))); |
764 __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp))); | 775 __ sw(a5, MemOperand(a0, OFFSET_OF(T, dbl_exp))); |
765 | 776 |
766 // Convert double in f0 to long, save hi/lo parts. | 777 // Convert double in f0 to long, save hi/lo parts. |
767 __ cvt_w_d(f0, f0); | 778 __ cvt_l_d(f0, f0); |
768 __ mfc1(t0, f0); // f0 has a 32-bits word. | 779 __ mfc1(a4, f0); // f0 LS 32 bits of long. |
769 __ sw(t0, MemOperand(a0, OFFSET_OF(T, word))); | 780 __ mfhc1(a5, f0); // f0 MS 32 bits of long. |
| 781 __ sw(a4, MemOperand(a0, OFFSET_OF(T, long_lo))); |
| 782 __ sw(a5, MemOperand(a0, OFFSET_OF(T, long_hi))); |
| 783 |
| 784 // Combine the high/low ints, convert back to double. |
| 785 __ dsll32(a6, a5, 0); // Move a5 to high bits of a6. |
| 786 __ or_(a6, a6, a4); |
| 787 __ dmtc1(a6, f1); |
| 788 __ cvt_d_l(f1, f1); |
| 789 __ sdc1(f1, MemOperand(a0, OFFSET_OF(T, a_converted))); |
| 790 |
770 | 791 |
771 // Convert the b long integers to double b. | 792 // Convert the b long integers to double b. |
772 __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_word))); | 793 __ lw(a4, MemOperand(a0, OFFSET_OF(T, b_long_lo))); |
773 __ mtc1(t0, f8); // f8 has a 32-bits word. | 794 __ lw(a5, MemOperand(a0, OFFSET_OF(T, b_long_hi))); |
774 __ cvt_d_w(f10, f8); | 795 __ mtc1(a4, f8); // f8 LS 32-bits. |
| 796 __ mthc1(a5, f8); // f8 MS 32-bits. |
| 797 __ cvt_d_l(f10, f8); |
775 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b))); | 798 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b))); |
776 | 799 |
| 800 // Convert double b back to long-int. |
| 801 __ ldc1(f31, MemOperand(a0, OFFSET_OF(T, b))); |
| 802 __ cvt_l_d(f31, f31); |
| 803 __ dmfc1(a7, f31); |
| 804 __ sd(a7, MemOperand(a0, OFFSET_OF(T, b_long_as_int64))); |
| 805 |
| 806 |
777 __ jr(ra); | 807 __ jr(ra); |
778 __ nop(); | 808 __ nop(); |
779 | 809 |
780 CodeDesc desc; | 810 CodeDesc desc; |
781 assm.GetCode(&desc); | 811 assm.GetCode(&desc); |
782 Handle<Code> code = isolate->factory()->NewCode( | 812 Handle<Code> code = isolate->factory()->NewCode( |
783 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 813 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
784 F3 f = FUNCTION_CAST<F3>(code->entry()); | 814 F3 f = FUNCTION_CAST<F3>(code->entry()); |
785 t.a = 2.147483646e+09; // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double. | 815 t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double. |
786 t.b_word = 0x0ff00ff0; // 0x0FF00FF0 -> 0x as double. | 816 t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double. |
| 817 t.b_long_lo = 0x00ff00ff; |
787 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); | 818 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
788 USE(dummy); | 819 USE(dummy); |
789 | 820 |
790 CHECK_EQ(0x41DFFFFF, t.dbl_exp); | 821 CHECK_EQ(0x41DFFFFF, t.dbl_exp); |
791 CHECK_EQ(0xFF800000, t.dbl_mant); | 822 CHECK_EQ(0xFFC00000, t.dbl_mant); |
792 CHECK_EQ(0X7FFFFFFE, t.word); | 823 CHECK_EQ(0, t.long_hi); |
793 // 0x0FF00FF0 -> 2.6739096+e08 | 824 CHECK_EQ(0x7fffffff, t.long_lo); |
794 CHECK_EQ(2.6739096e08, t.b); | 825 CHECK_EQ(2.147483647e9, t.a_converted); |
| 826 |
| 827 // 0xFF00FF00FF -> 1.095233372415e12. |
| 828 CHECK_EQ(1.095233372415e12, t.b); |
| 829 CHECK_EQ(0xFF00FF00FF, t.b_long_as_int64); |
795 } | 830 } |
796 } | 831 } |
797 | 832 |
798 | 833 |
799 TEST(MIPS11) { | 834 TEST(MIPS11) { |
800 // Test LWL, LWR, SWL and SWR instructions. | 835 // Test LWL, LWR, SWL and SWR instructions. |
801 CcTest::InitializeVM(); | 836 CcTest::InitializeVM(); |
802 Isolate* isolate = CcTest::i_isolate(); | 837 Isolate* isolate = CcTest::i_isolate(); |
803 HandleScope scope(isolate); | 838 HandleScope scope(isolate); |
804 | 839 |
(...skipping 15 matching lines...) Expand all Loading... |
820 int32_t swr_0; | 855 int32_t swr_0; |
821 int32_t swr_1; | 856 int32_t swr_1; |
822 int32_t swr_2; | 857 int32_t swr_2; |
823 int32_t swr_3; | 858 int32_t swr_3; |
824 } T; | 859 } T; |
825 T t; | 860 T t; |
826 | 861 |
827 Assembler assm(isolate, NULL, 0); | 862 Assembler assm(isolate, NULL, 0); |
828 | 863 |
829 // Test all combinations of LWL and vAddr. | 864 // Test all combinations of LWL and vAddr. |
830 __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 865 __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
831 __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 866 __ lwl(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
832 __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) ); | 867 __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwl_0)) ); |
833 | 868 |
834 __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 869 __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
835 __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) ); | 870 __ lwl(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) ); |
836 __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) ); | 871 __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwl_1)) ); |
837 | 872 |
838 __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 873 __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
839 __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) ); | 874 __ lwl(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) ); |
840 __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) ); | 875 __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwl_2)) ); |
841 | 876 |
842 __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 877 __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
843 __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) ); | 878 __ lwl(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) ); |
844 __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) ); | 879 __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwl_3)) ); |
845 | 880 |
846 // Test all combinations of LWR and vAddr. | 881 // Test all combinations of LWR and vAddr. |
847 __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 882 __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
848 __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 883 __ lwr(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
849 __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) ); | 884 __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwr_0)) ); |
850 | 885 |
851 __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 886 __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
852 __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) ); | 887 __ lwr(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) ); |
853 __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) ); | 888 __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwr_1)) ); |
854 | 889 |
855 __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 890 __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
856 __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) ); | 891 __ lwr(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) ); |
857 __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) ); | 892 __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwr_2)) ); |
858 | 893 |
859 __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 894 __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
860 __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) ); | 895 __ lwr(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) ); |
861 __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) ); | 896 __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwr_3)) ); |
862 | 897 |
863 // Test all combinations of SWL and vAddr. | 898 // Test all combinations of SWL and vAddr. |
864 __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 899 __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
865 __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) ); | 900 __ sw(a4, MemOperand(a0, OFFSET_OF(T, swl_0)) ); |
866 __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 901 __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
867 __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) ); | 902 __ swl(a4, MemOperand(a0, OFFSET_OF(T, swl_0)) ); |
868 | 903 |
869 __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 904 __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
870 __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) ); | 905 __ sw(a5, MemOperand(a0, OFFSET_OF(T, swl_1)) ); |
871 __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 906 __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
872 __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) ); | 907 __ swl(a5, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) ); |
873 | 908 |
874 __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 909 __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
875 __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) ); | 910 __ sw(a6, MemOperand(a0, OFFSET_OF(T, swl_2)) ); |
876 __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 911 __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
877 __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) ); | 912 __ swl(a6, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) ); |
878 | 913 |
879 __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 914 __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
880 __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) ); | 915 __ sw(a7, MemOperand(a0, OFFSET_OF(T, swl_3)) ); |
881 __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 916 __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
882 __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) ); | 917 __ swl(a7, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) ); |
883 | 918 |
884 // Test all combinations of SWR and vAddr. | 919 // Test all combinations of SWR and vAddr. |
885 __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 920 __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
886 __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) ); | 921 __ sw(a4, MemOperand(a0, OFFSET_OF(T, swr_0)) ); |
887 __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 922 __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
888 __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) ); | 923 __ swr(a4, MemOperand(a0, OFFSET_OF(T, swr_0)) ); |
889 | 924 |
890 __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 925 __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
891 __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) ); | 926 __ sw(a5, MemOperand(a0, OFFSET_OF(T, swr_1)) ); |
892 __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 927 __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
893 __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) ); | 928 __ swr(a5, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) ); |
894 | 929 |
895 __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 930 __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
896 __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) ); | 931 __ sw(a6, MemOperand(a0, OFFSET_OF(T, swr_2)) ); |
897 __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 932 __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
898 __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) ); | 933 __ swr(a6, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) ); |
899 | 934 |
900 __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) ); | 935 __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)) ); |
901 __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) ); | 936 __ sw(a7, MemOperand(a0, OFFSET_OF(T, swr_3)) ); |
902 __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) ); | 937 __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)) ); |
903 __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) ); | 938 __ swr(a7, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) ); |
904 | 939 |
905 __ jr(ra); | 940 __ jr(ra); |
906 __ nop(); | 941 __ nop(); |
907 | 942 |
908 CodeDesc desc; | 943 CodeDesc desc; |
909 assm.GetCode(&desc); | 944 assm.GetCode(&desc); |
910 Handle<Code> code = isolate->factory()->NewCode( | 945 Handle<Code> code = isolate->factory()->NewCode( |
911 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 946 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
912 F3 f = FUNCTION_CAST<F3>(code->entry()); | 947 F3 f = FUNCTION_CAST<F3>(code->entry()); |
913 t.reg_init = 0xaabbccdd; | 948 t.reg_init = 0xaabbccdd; |
914 t.mem_init = 0x11223344; | 949 t.mem_init = 0x11223344; |
915 | 950 |
916 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); | 951 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
917 USE(dummy); | 952 USE(dummy); |
918 | 953 |
919 #if __BYTE_ORDER == __LITTLE_ENDIAN | |
920 CHECK_EQ(0x44bbccdd, t.lwl_0); | 954 CHECK_EQ(0x44bbccdd, t.lwl_0); |
921 CHECK_EQ(0x3344ccdd, t.lwl_1); | 955 CHECK_EQ(0x3344ccdd, t.lwl_1); |
922 CHECK_EQ(0x223344dd, t.lwl_2); | 956 CHECK_EQ(0x223344dd, t.lwl_2); |
923 CHECK_EQ(0x11223344, t.lwl_3); | 957 CHECK_EQ(0x11223344, t.lwl_3); |
924 | 958 |
925 CHECK_EQ(0x11223344, t.lwr_0); | 959 CHECK_EQ(0x11223344, t.lwr_0); |
926 CHECK_EQ(0xaa112233, t.lwr_1); | 960 CHECK_EQ(0xaa112233, t.lwr_1); |
927 CHECK_EQ(0xaabb1122, t.lwr_2); | 961 CHECK_EQ(0xaabb1122, t.lwr_2); |
928 CHECK_EQ(0xaabbcc11, t.lwr_3); | 962 CHECK_EQ(0xaabbcc11, t.lwr_3); |
929 | 963 |
930 CHECK_EQ(0x112233aa, t.swl_0); | 964 CHECK_EQ(0x112233aa, t.swl_0); |
931 CHECK_EQ(0x1122aabb, t.swl_1); | 965 CHECK_EQ(0x1122aabb, t.swl_1); |
932 CHECK_EQ(0x11aabbcc, t.swl_2); | 966 CHECK_EQ(0x11aabbcc, t.swl_2); |
933 CHECK_EQ(0xaabbccdd, t.swl_3); | 967 CHECK_EQ(0xaabbccdd, t.swl_3); |
934 | 968 |
935 CHECK_EQ(0xaabbccdd, t.swr_0); | 969 CHECK_EQ(0xaabbccdd, t.swr_0); |
936 CHECK_EQ(0xbbccdd44, t.swr_1); | 970 CHECK_EQ(0xbbccdd44, t.swr_1); |
937 CHECK_EQ(0xccdd3344, t.swr_2); | 971 CHECK_EQ(0xccdd3344, t.swr_2); |
938 CHECK_EQ(0xdd223344, t.swr_3); | 972 CHECK_EQ(0xdd223344, t.swr_3); |
939 #elif __BYTE_ORDER == __BIG_ENDIAN | |
940 CHECK_EQ(0x11223344, t.lwl_0); | |
941 CHECK_EQ(0x223344dd, t.lwl_1); | |
942 CHECK_EQ(0x3344ccdd, t.lwl_2); | |
943 CHECK_EQ(0x44bbccdd, t.lwl_3); | |
944 | |
945 CHECK_EQ(0xaabbcc11, t.lwr_0); | |
946 CHECK_EQ(0xaabb1122, t.lwr_1); | |
947 CHECK_EQ(0xaa112233, t.lwr_2); | |
948 CHECK_EQ(0x11223344, t.lwr_3); | |
949 | |
950 CHECK_EQ(0xaabbccdd, t.swl_0); | |
951 CHECK_EQ(0x11aabbcc, t.swl_1); | |
952 CHECK_EQ(0x1122aabb, t.swl_2); | |
953 CHECK_EQ(0x112233aa, t.swl_3); | |
954 | |
955 CHECK_EQ(0xdd223344, t.swr_0); | |
956 CHECK_EQ(0xccdd3344, t.swr_1); | |
957 CHECK_EQ(0xbbccdd44, t.swr_2); | |
958 CHECK_EQ(0xaabbccdd, t.swr_3); | |
959 #else | |
960 #error Unknown endianness | |
961 #endif | |
962 } | 973 } |
963 | 974 |
964 | 975 |
965 TEST(MIPS12) { | 976 TEST(MIPS12) { |
966 CcTest::InitializeVM(); | 977 CcTest::InitializeVM(); |
967 Isolate* isolate = CcTest::i_isolate(); | 978 Isolate* isolate = CcTest::i_isolate(); |
968 HandleScope scope(isolate); | 979 HandleScope scope(isolate); |
969 | 980 |
970 typedef struct { | 981 typedef struct { |
971 int32_t x; | 982 int32_t x; |
972 int32_t y; | 983 int32_t y; |
973 int32_t y1; | 984 int32_t y1; |
974 int32_t y2; | 985 int32_t y2; |
975 int32_t y3; | 986 int32_t y3; |
976 int32_t y4; | 987 int32_t y4; |
977 } T; | 988 } T; |
978 T t; | 989 T t; |
979 | 990 |
980 MacroAssembler assm(isolate, NULL, 0); | 991 MacroAssembler assm(isolate, NULL, 0); |
981 | 992 |
982 __ mov(t6, fp); // Save frame pointer. | 993 __ mov(t2, fp); // Save frame pointer. |
983 __ mov(fp, a0); // Access struct T by fp. | 994 __ mov(fp, a0); // Access struct T by fp. |
984 __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) ); | 995 __ lw(a4, MemOperand(a0, OFFSET_OF(T, y)) ); |
985 __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) ); | 996 __ lw(a7, MemOperand(a0, OFFSET_OF(T, y4)) ); |
986 | 997 |
987 __ addu(t1, t0, t3); | 998 __ addu(a5, a4, a7); |
988 __ subu(t4, t0, t3); | 999 __ subu(t0, a4, a7); |
989 __ nop(); | 1000 __ nop(); |
990 __ push(t0); // These instructions disappear after opt. | 1001 __ push(a4); // These instructions disappear after opt. |
991 __ Pop(); | 1002 __ Pop(); |
992 __ addu(t0, t0, t0); | 1003 __ addu(a4, a4, a4); |
993 __ nop(); | 1004 __ nop(); |
994 __ Pop(); // These instructions disappear after opt. | 1005 __ Pop(); // These instructions disappear after opt. |
995 __ push(t3); | 1006 __ push(a7); |
996 __ nop(); | 1007 __ nop(); |
997 __ push(t3); // These instructions disappear after opt. | 1008 __ push(a7); // These instructions disappear after opt. |
998 __ pop(t3); | 1009 __ pop(a7); |
999 __ nop(); | 1010 __ nop(); |
1000 __ push(t3); | 1011 __ push(a7); |
1001 __ pop(t4); | 1012 __ pop(t0); |
1002 __ nop(); | 1013 __ nop(); |
1003 __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) ); | 1014 __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)) ); |
1004 __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) ); | 1015 __ lw(a4, MemOperand(fp, OFFSET_OF(T, y)) ); |
1005 __ nop(); | 1016 __ nop(); |
1006 __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) ); | 1017 __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)) ); |
1007 __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) ); | 1018 __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)) ); |
1008 __ nop(); | 1019 __ nop(); |
1009 __ push(t1); | 1020 __ push(a5); |
1010 __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) ); | 1021 __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)) ); |
1011 __ pop(t1); | 1022 __ pop(a5); |
1012 __ nop(); | 1023 __ nop(); |
1013 __ push(t1); | 1024 __ push(a5); |
1014 __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) ); | 1025 __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) ); |
1015 __ pop(t1); | 1026 __ pop(a5); |
1016 __ nop(); | 1027 __ nop(); |
1017 __ push(t1); | 1028 __ push(a5); |
1018 __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) ); | 1029 __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) ); |
1019 __ pop(t2); | 1030 __ pop(a6); |
1020 __ nop(); | 1031 __ nop(); |
1021 __ push(t2); | 1032 __ push(a6); |
1022 __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) ); | 1033 __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) ); |
1023 __ pop(t1); | 1034 __ pop(a5); |
1024 __ nop(); | 1035 __ nop(); |
1025 __ push(t1); | 1036 __ push(a5); |
1026 __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) ); | 1037 __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)) ); |
1027 __ pop(t3); | 1038 __ pop(a7); |
1028 __ nop(); | 1039 __ nop(); |
1029 | 1040 |
1030 __ mov(fp, t6); | 1041 __ mov(fp, t2); |
1031 __ jr(ra); | 1042 __ jr(ra); |
1032 __ nop(); | 1043 __ nop(); |
1033 | 1044 |
1034 CodeDesc desc; | 1045 CodeDesc desc; |
1035 assm.GetCode(&desc); | 1046 assm.GetCode(&desc); |
1036 Handle<Code> code = isolate->factory()->NewCode( | 1047 Handle<Code> code = isolate->factory()->NewCode( |
1037 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1048 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
1038 F3 f = FUNCTION_CAST<F3>(code->entry()); | 1049 F3 f = FUNCTION_CAST<F3>(code->entry()); |
1039 t.x = 1; | 1050 t.x = 1; |
1040 t.y = 2; | 1051 t.y = 2; |
(...skipping 20 matching lines...) Expand all Loading... |
1061 double cvt_small_out; | 1072 double cvt_small_out; |
1062 uint32_t trunc_big_out; | 1073 uint32_t trunc_big_out; |
1063 uint32_t trunc_small_out; | 1074 uint32_t trunc_small_out; |
1064 uint32_t cvt_big_in; | 1075 uint32_t cvt_big_in; |
1065 uint32_t cvt_small_in; | 1076 uint32_t cvt_small_in; |
1066 } T; | 1077 } T; |
1067 T t; | 1078 T t; |
1068 | 1079 |
1069 MacroAssembler assm(isolate, NULL, 0); | 1080 MacroAssembler assm(isolate, NULL, 0); |
1070 | 1081 |
1071 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in))); | 1082 __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_small_in))); |
1072 __ Cvt_d_uw(f10, t0, f22); | 1083 __ Cvt_d_uw(f10, a4, f22); |
1073 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out))); | 1084 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out))); |
1074 | 1085 |
1075 __ Trunc_uw_d(f10, f10, f22); | 1086 __ Trunc_uw_d(f10, f10, f22); |
1076 __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out))); | 1087 __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out))); |
1077 | 1088 |
1078 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in))); | 1089 __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_big_in))); |
1079 __ Cvt_d_uw(f8, t0, f22); | 1090 __ Cvt_d_uw(f8, a4, f22); |
1080 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out))); | 1091 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out))); |
1081 | 1092 |
1082 __ Trunc_uw_d(f8, f8, f22); | 1093 __ Trunc_uw_d(f8, f8, f22); |
1083 __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out))); | 1094 __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out))); |
1084 | 1095 |
1085 __ jr(ra); | 1096 __ jr(ra); |
1086 __ nop(); | 1097 __ nop(); |
1087 | 1098 |
1088 CodeDesc desc; | 1099 CodeDesc desc; |
1089 assm.GetCode(&desc); | 1100 assm.GetCode(&desc); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 | 1231 |
1221 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); | 1232 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
1222 USE(dummy); | 1233 USE(dummy); |
1223 | 1234 |
1224 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask)) | 1235 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask)) |
1225 #define CHECK_ROUND_RESULT(type) \ | 1236 #define CHECK_ROUND_RESULT(type) \ |
1226 CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \ | 1237 CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \ |
1227 CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \ | 1238 CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \ |
1228 CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \ | 1239 CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \ |
1229 CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \ | 1240 CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \ |
1230 CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result); | 1241 CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result); |
1231 | 1242 |
1232 CHECK_ROUND_RESULT(round); | 1243 CHECK_ROUND_RESULT(round); |
1233 CHECK_ROUND_RESULT(floor); | 1244 CHECK_ROUND_RESULT(floor); |
1234 CHECK_ROUND_RESULT(ceil); | 1245 CHECK_ROUND_RESULT(ceil); |
1235 CHECK_ROUND_RESULT(cvt); | 1246 CHECK_ROUND_RESULT(cvt); |
1236 } | 1247 } |
1237 | 1248 |
1238 | 1249 |
1239 TEST(MIPS15) { | 1250 TEST(MIPS15) { |
1240 // Test chaining of label usages within instructions (issue 1644). | 1251 // Test chaining of label usages within instructions (issue 1644). |
1241 CcTest::InitializeVM(); | 1252 CcTest::InitializeVM(); |
1242 Isolate* isolate = CcTest::i_isolate(); | 1253 Isolate* isolate = CcTest::i_isolate(); |
1243 HandleScope scope(isolate); | 1254 HandleScope scope(isolate); |
1244 Assembler assm(isolate, NULL, 0); | 1255 Assembler assm(isolate, NULL, 0); |
1245 | 1256 |
1246 Label target; | 1257 Label target; |
1247 __ beq(v0, v1, &target); | 1258 __ beq(v0, v1, &target); |
1248 __ nop(); | 1259 __ nop(); |
1249 __ bne(v0, v1, &target); | 1260 __ bne(v0, v1, &target); |
1250 __ nop(); | 1261 __ nop(); |
1251 __ bind(&target); | 1262 __ bind(&target); |
1252 __ nop(); | 1263 __ nop(); |
1253 } | 1264 } |
1254 | 1265 |
| 1266 |
| 1267 // ----- mips64 tests ----------------------------------------------- |
| 1268 |
| 1269 TEST(MIPS16) { |
| 1270 // Test 64-bit memory loads and stores. |
| 1271 CcTest::InitializeVM(); |
| 1272 Isolate* isolate = CcTest::i_isolate(); |
| 1273 HandleScope scope(isolate); |
| 1274 |
| 1275 typedef struct { |
| 1276 int64_t r1; |
| 1277 int64_t r2; |
| 1278 int64_t r3; |
| 1279 int64_t r4; |
| 1280 int64_t r5; |
| 1281 int64_t r6; |
| 1282 uint32_t ui; |
| 1283 int32_t si; |
| 1284 } T; |
| 1285 T t; |
| 1286 |
| 1287 Assembler assm(isolate, NULL, 0); |
| 1288 Label L, C; |
| 1289 |
| 1290 // Basic 32-bit word load/store, with un-signed data. |
| 1291 __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) ); |
| 1292 __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) ); |
| 1293 |
| 1294 // Check that the data got zero-extended into 64-bit a4. |
| 1295 __ sd(a4, MemOperand(a0, OFFSET_OF(T, r2)) ); |
| 1296 |
| 1297 // Basic 32-bit word load/store, with SIGNED data. |
| 1298 __ lw(a5, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1299 __ sw(a5, MemOperand(a0, OFFSET_OF(T, r3)) ); |
| 1300 |
| 1301 // Check that the data got sign-extended into 64-bit a4. |
| 1302 __ sd(a5, MemOperand(a0, OFFSET_OF(T, r4)) ); |
| 1303 |
| 1304 // 32-bit UNSIGNED word load/store, with SIGNED data. |
| 1305 __ lwu(a6, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1306 __ sw(a6, MemOperand(a0, OFFSET_OF(T, r5)) ); |
| 1307 |
| 1308 // Check that the data got zero-extended into 64-bit a4. |
| 1309 __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6)) ); |
| 1310 |
| 1311 // lh with positive data. |
| 1312 __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) ); |
| 1313 __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) ); |
| 1314 |
| 1315 // lh with negative data. |
| 1316 __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1317 __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) ); |
| 1318 |
| 1319 // lhu with negative data. |
| 1320 __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1321 __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) ); |
| 1322 |
| 1323 // lb with negative data. |
| 1324 __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1325 __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) ); |
| 1326 |
| 1327 // // sh writes only 1/2 of word. |
| 1328 __ lui(t1, 0x3333); |
| 1329 __ ori(t1, t1, 0x3333); |
| 1330 __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) ); |
| 1331 __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) ); |
| 1332 __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) ); |
| 1333 |
| 1334 __ jr(ra); |
| 1335 __ nop(); |
| 1336 |
| 1337 CodeDesc desc; |
| 1338 assm.GetCode(&desc); |
| 1339 Handle<Code> code = isolate->factory()->NewCode( |
| 1340 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 1341 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 1342 t.ui = 0x44332211; |
| 1343 t.si = 0x99aabbcc; |
| 1344 t.r1 = 0x1111111111111111; |
| 1345 t.r2 = 0x2222222222222222; |
| 1346 t.r3 = 0x3333333333333333; |
| 1347 t.r4 = 0x4444444444444444; |
| 1348 t.r5 = 0x5555555555555555; |
| 1349 t.r6 = 0x6666666666666666; |
| 1350 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); |
| 1351 USE(dummy); |
| 1352 |
| 1353 // Unsigned data, 32 & 64. |
| 1354 CHECK_EQ(0x1111111144332211L, t.r1); |
| 1355 CHECK_EQ(0x0000000000002211L, t.r2); |
| 1356 |
| 1357 // Signed data, 32 & 64. |
| 1358 CHECK_EQ(0x33333333ffffbbccL, t.r3); |
| 1359 CHECK_EQ(0xffffffff0000bbccL, t.r4); |
| 1360 |
| 1361 // Signed data, 32 & 64. |
| 1362 CHECK_EQ(0x55555555ffffffccL, t.r5); |
| 1363 CHECK_EQ(0x000000003333bbccL, t.r6); |
| 1364 } |
| 1365 |
1255 #undef __ | 1366 #undef __ |
OLD | NEW |