1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions 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 "src/v8.h"
31 
32 #include "src/debug/debug.h"
33 #include "src/disasm.h"
34 #include "src/disassembler.h"
35 #include "src/ic/ic.h"
36 #include "src/macro-assembler.h"
37 #include "src/x87/frames-x87.h"
38 #include "test/cctest/cctest.h"
39 
40 using namespace v8::internal;
41 
42 
43 #define __ assm.
44 
45 
DummyStaticFunction(Object * result)46 static void DummyStaticFunction(Object* result) {
47 }
48 
49 
TEST(DisasmIa320)50 TEST(DisasmIa320) {
51   CcTest::InitializeVM();
52   Isolate* isolate = CcTest::i_isolate();
53   HandleScope scope(isolate);
54   v8::internal::byte buffer[2048];
55   Assembler assm(isolate, buffer, sizeof buffer);
56   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
57 
58   // Short immediate instructions
59   __ adc(eax, 12345678);
60   __ add(eax, Immediate(12345678));
61   __ or_(eax, 12345678);
62   __ sub(eax, Immediate(12345678));
63   __ xor_(eax, 12345678);
64   __ and_(eax, 12345678);
65   Handle<FixedArray> foo = isolate->factory()->NewFixedArray(10, TENURED);
66   __ cmp(eax, foo);
67 
68   // ---- This one caused crash
69   __ mov(ebx,  Operand(esp, ecx, times_2, 0));  // [esp+ecx*4]
70 
71   // ---- All instructions that I can think of
72   __ add(edx, ebx);
73   __ add(edx, Operand(12, RelocInfo::NONE32));
74   __ add(edx, Operand(ebx, 0));
75   __ add(edx, Operand(ebx, 16));
76   __ add(edx, Operand(ebx, 1999));
77   __ add(edx, Operand(ebx, -4));
78   __ add(edx, Operand(ebx, -1999));
79   __ add(edx, Operand(esp, 0));
80   __ add(edx, Operand(esp, 16));
81   __ add(edx, Operand(esp, 1999));
82   __ add(edx, Operand(esp, -4));
83   __ add(edx, Operand(esp, -1999));
84   __ nop();
85   __ add(esi, Operand(ecx, times_4, 0));
86   __ add(esi, Operand(ecx, times_4, 24));
87   __ add(esi, Operand(ecx, times_4, -4));
88   __ add(esi, Operand(ecx, times_4, -1999));
89   __ nop();
90   __ add(edi, Operand(ebp, ecx, times_4, 0));
91   __ add(edi, Operand(ebp, ecx, times_4, 12));
92   __ add(edi, Operand(ebp, ecx, times_4, -8));
93   __ add(edi, Operand(ebp, ecx, times_4, -3999));
94   __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
95 
96   __ nop();
97   __ add(ebx, Immediate(12));
98   __ nop();
99   __ adc(ecx, 12);
100   __ adc(ecx, 1000);
101   __ nop();
102   __ and_(edx, 3);
103   __ and_(edx, Operand(esp, 4));
104   __ cmp(edx, 3);
105   __ cmp(edx, Operand(esp, 4));
106   __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
107   Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED);
108   __ cmp(ebx, foo2);
109   __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
110   __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
111   __ or_(edx, 3);
112   __ xor_(edx, 3);
113   __ nop();
114   __ cpuid();
115   __ movsx_b(edx, ecx);
116   __ movsx_w(edx, ecx);
117   __ movzx_b(edx, ecx);
118   __ movzx_w(edx, ecx);
119 
120   __ nop();
121   __ imul(edx, ecx);
122   __ shld(edx, ecx);
123   __ shrd(edx, ecx);
124   __ bts(edx, ecx);
125   __ bts(Operand(ebx, ecx, times_4, 0), ecx);
126   __ nop();
127   __ pushad();
128   __ popad();
129   __ pushfd();
130   __ popfd();
131   __ push(Immediate(12));
132   __ push(Immediate(23456));
133   __ push(ecx);
134   __ push(esi);
135   __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
136   __ push(Operand(ebx, ecx, times_4, 0));
137   __ push(Operand(ebx, ecx, times_4, 0));
138   __ push(Operand(ebx, ecx, times_4, 10000));
139   __ pop(edx);
140   __ pop(eax);
141   __ pop(Operand(ebx, ecx, times_4, 0));
142   __ nop();
143 
144   __ add(edx, Operand(esp, 16));
145   __ add(edx, ecx);
146   __ mov_b(edx, ecx);
147   __ mov_b(ecx, 6);
148   __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
149   __ mov_b(Operand(esp, 16), edx);
150   __ mov_w(edx, Operand(esp, 16));
151   __ mov_w(Operand(esp, 16), edx);
152   __ nop();
153   __ movsx_w(edx, Operand(esp, 12));
154   __ movsx_b(edx, Operand(esp, 12));
155   __ movzx_w(edx, Operand(esp, 12));
156   __ movzx_b(edx, Operand(esp, 12));
157   __ nop();
158   __ mov(edx, 1234567);
159   __ mov(edx, Operand(esp, 12));
160   __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
161   __ mov(Operand(ebx, ecx, times_4, 10000), edx);
162   __ nop();
163   __ dec_b(edx);
164   __ dec_b(Operand(eax, 10));
165   __ dec_b(Operand(ebx, ecx, times_4, 10000));
166   __ dec(edx);
167   __ cdq();
168 
169   __ nop();
170   __ idiv(edx);
171   __ idiv(Operand(edx, ecx, times_1, 1));
172   __ idiv(Operand(esp, 12));
173   __ div(edx);
174   __ div(Operand(edx, ecx, times_1, 1));
175   __ div(Operand(esp, 12));
176   __ mul(edx);
177   __ neg(edx);
178   __ not_(edx);
179   __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
180 
181   __ imul(edx, Operand(ebx, ecx, times_4, 10000));
182   __ imul(edx, ecx, 12);
183   __ imul(edx, Operand(edx, eax, times_2, 42), 8);
184   __ imul(edx, ecx, 1000);
185   __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
186 
187   __ inc(edx);
188   __ inc(Operand(ebx, ecx, times_4, 10000));
189   __ push(Operand(ebx, ecx, times_4, 10000));
190   __ pop(Operand(ebx, ecx, times_4, 10000));
191   __ call(Operand(ebx, ecx, times_4, 10000));
192   __ jmp(Operand(ebx, ecx, times_4, 10000));
193 
194   __ lea(edx, Operand(ebx, ecx, times_4, 10000));
195   __ or_(edx, 12345);
196   __ or_(edx, Operand(ebx, ecx, times_4, 10000));
197 
198   __ nop();
199 
200   __ rcl(edx, 1);
201   __ rcl(edx, 7);
202   __ rcr(edx, 1);
203   __ rcr(edx, 7);
204   __ ror(edx, 1);
205   __ ror(edx, 6);
206   __ ror_cl(edx);
207   __ ror(Operand(ebx, ecx, times_4, 10000), 1);
208   __ ror(Operand(ebx, ecx, times_4, 10000), 6);
209   __ ror_cl(Operand(ebx, ecx, times_4, 10000));
210   __ sar(edx, 1);
211   __ sar(edx, 6);
212   __ sar_cl(edx);
213   __ sar(Operand(ebx, ecx, times_4, 10000), 1);
214   __ sar(Operand(ebx, ecx, times_4, 10000), 6);
215   __ sar_cl(Operand(ebx, ecx, times_4, 10000));
216   __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
217   __ shld(edx, Operand(ebx, ecx, times_4, 10000));
218   __ shl(edx, 1);
219   __ shl(edx, 6);
220   __ shl_cl(edx);
221   __ shl(Operand(ebx, ecx, times_4, 10000), 1);
222   __ shl(Operand(ebx, ecx, times_4, 10000), 6);
223   __ shl_cl(Operand(ebx, ecx, times_4, 10000));
224   __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
225   __ shr(edx, 1);
226   __ shr(edx, 7);
227   __ shr_cl(edx);
228   __ shr(Operand(ebx, ecx, times_4, 10000), 1);
229   __ shr(Operand(ebx, ecx, times_4, 10000), 6);
230   __ shr_cl(Operand(ebx, ecx, times_4, 10000));
231 
232 
233   // Immediates
234 
235   __ adc(edx, 12345);
236 
237   __ add(ebx, Immediate(12));
238   __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
239 
240   __ and_(ebx, 12345);
241 
242   __ cmp(ebx, 12345);
243   __ cmp(ebx, Immediate(12));
244   __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
245   __ cmpb(eax, 100);
246 
247   __ or_(ebx, 12345);
248 
249   __ sub(ebx, Immediate(12));
250   __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
251 
252   __ xor_(ebx, 12345);
253 
254   __ imul(edx, ecx, 12);
255   __ imul(edx, ecx, 1000);
256 
257   __ cld();
258   __ rep_movs();
259   __ rep_stos();
260   __ stos();
261 
262   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
263   __ sub(edx, ebx);
264 
265   __ test(edx, Immediate(12345));
266   __ test(edx, Operand(ebx, ecx, times_8, 10000));
267   __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
268   __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
269   __ test_b(Operand(eax, -20), 0x9A);
270   __ nop();
271 
272   __ xor_(edx, 12345);
273   __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
274   __ bts(Operand(ebx, ecx, times_8, 10000), edx);
275   __ hlt();
276   __ int3();
277   __ ret(0);
278   __ ret(8);
279 
280   // Calls
281 
282   Label L1, L2;
283   __ bind(&L1);
284   __ nop();
285   __ call(&L1);
286   __ call(&L2);
287   __ nop();
288   __ bind(&L2);
289   __ call(Operand(ebx, ecx, times_4, 10000));
290   __ nop();
291   Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
292   __ call(ic, RelocInfo::CODE_TARGET);
293   __ nop();
294   __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
295   __ nop();
296 
297   __ jmp(&L1);
298   __ jmp(Operand(ebx, ecx, times_4, 10000));
299   ExternalReference after_break_target =
300       ExternalReference::debug_after_break_target_address(isolate);
301   __ jmp(Operand::StaticVariable(after_break_target));
302   __ jmp(ic, RelocInfo::CODE_TARGET);
303   __ nop();
304 
305 
306   Label Ljcc;
307   __ nop();
308   // long jumps
309   __ j(overflow, &Ljcc);
310   __ j(no_overflow, &Ljcc);
311   __ j(below, &Ljcc);
312   __ j(above_equal, &Ljcc);
313   __ j(equal, &Ljcc);
314   __ j(not_equal, &Ljcc);
315   __ j(below_equal, &Ljcc);
316   __ j(above, &Ljcc);
317   __ j(sign, &Ljcc);
318   __ j(not_sign, &Ljcc);
319   __ j(parity_even, &Ljcc);
320   __ j(parity_odd, &Ljcc);
321   __ j(less, &Ljcc);
322   __ j(greater_equal, &Ljcc);
323   __ j(less_equal, &Ljcc);
324   __ j(greater, &Ljcc);
325   __ nop();
326   __ bind(&Ljcc);
327   // short jumps
328   __ j(overflow, &Ljcc);
329   __ j(no_overflow, &Ljcc);
330   __ j(below, &Ljcc);
331   __ j(above_equal, &Ljcc);
332   __ j(equal, &Ljcc);
333   __ j(not_equal, &Ljcc);
334   __ j(below_equal, &Ljcc);
335   __ j(above, &Ljcc);
336   __ j(sign, &Ljcc);
337   __ j(not_sign, &Ljcc);
338   __ j(parity_even, &Ljcc);
339   __ j(parity_odd, &Ljcc);
340   __ j(less, &Ljcc);
341   __ j(greater_equal, &Ljcc);
342   __ j(less_equal, &Ljcc);
343   __ j(greater, &Ljcc);
344 
345   // 0xD9 instructions
346   __ nop();
347 
348   __ fld(1);
349   __ fld1();
350   __ fldz();
351   __ fldpi();
352   __ fabs();
353   __ fchs();
354   __ fprem();
355   __ fprem1();
356   __ fincstp();
357   __ ftst();
358   __ fxam();
359   __ fxch(3);
360   __ fld_s(Operand(ebx, ecx, times_4, 10000));
361   __ fstp_s(Operand(ebx, ecx, times_4, 10000));
362   __ ffree(3);
363   __ fld_d(Operand(ebx, ecx, times_4, 10000));
364   __ fstp_d(Operand(ebx, ecx, times_4, 10000));
365   __ nop();
366 
367   __ fild_s(Operand(ebx, ecx, times_4, 10000));
368   __ fistp_s(Operand(ebx, ecx, times_4, 10000));
369   __ fild_d(Operand(ebx, ecx, times_4, 10000));
370   __ fistp_d(Operand(ebx, ecx, times_4, 10000));
371   __ fnstsw_ax();
372   __ nop();
373   __ fadd(3);
374   __ fsub(3);
375   __ fmul(3);
376   __ fdiv(3);
377 
378   __ faddp(3);
379   __ fsubp(3);
380   __ fmulp(3);
381   __ fdivp(3);
382   __ fcompp();
383   __ fwait();
384   __ frndint();
385   __ fninit();
386   __ nop();
387 
388   __ fldcw(Operand(ebx, ecx, times_4, 10000));
389   __ fnstcw(Operand(ebx, ecx, times_4, 10000));
390   __ fadd_d(Operand(ebx, ecx, times_4, 10000));
391   __ fnsave(Operand(ebx, ecx, times_4, 10000));
392   __ frstor(Operand(ebx, ecx, times_4, 10000));
393 
394   // xchg.
395   {
396     __ xchg(eax, eax);
397     __ xchg(eax, ebx);
398     __ xchg(ebx, ebx);
399     __ xchg(ebx, Operand(esp, 12));
400   }
401 
402   // Nop instructions
403   for (int i = 0; i < 16; i++) {
404     __ Nop(i);
405   }
406 
407   __ ret(0);
408 
409   CodeDesc desc;
410   assm.GetCode(&desc);
411   Handle<Code> code = isolate->factory()->NewCode(
412       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
413   USE(code);
414 #ifdef OBJECT_PRINT
415   OFStream os(stdout);
416   code->Print(os);
417   byte* begin = code->instruction_start();
418   byte* end = begin + code->instruction_size();
419   disasm::Disassembler::Disassemble(stdout, begin, end);
420 #endif
421 }
422 
423 #undef __
424