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.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/serialize.h" 38#include "test/cctest/cctest.h" 39 40using namespace v8::internal; 41 42 43#define __ assm. 44 45 46static void DummyStaticFunction(Object* result) { 47} 48 49 50TEST(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 __ sar(edx, 1); 205 __ sar(edx, 6); 206 __ sar_cl(edx); 207 __ sar(Operand(ebx, ecx, times_4, 10000), 1); 208 __ sar(Operand(ebx, ecx, times_4, 10000), 6); 209 __ sar_cl(Operand(ebx, ecx, times_4, 10000)); 210 __ sbb(edx, Operand(ebx, ecx, times_4, 10000)); 211 __ shld(edx, Operand(ebx, ecx, times_4, 10000)); 212 __ shl(edx, 1); 213 __ shl(edx, 6); 214 __ shl_cl(edx); 215 __ shl(Operand(ebx, ecx, times_4, 10000), 1); 216 __ shl(Operand(ebx, ecx, times_4, 10000), 6); 217 __ shl_cl(Operand(ebx, ecx, times_4, 10000)); 218 __ shrd(edx, Operand(ebx, ecx, times_4, 10000)); 219 __ shr(edx, 1); 220 __ shr(edx, 7); 221 __ shr_cl(edx); 222 __ shr(Operand(ebx, ecx, times_4, 10000), 1); 223 __ shr(Operand(ebx, ecx, times_4, 10000), 6); 224 __ shr_cl(Operand(ebx, ecx, times_4, 10000)); 225 226 227 // Immediates 228 229 __ adc(edx, 12345); 230 231 __ add(ebx, Immediate(12)); 232 __ add(Operand(edx, ecx, times_4, 10000), Immediate(12)); 233 234 __ and_(ebx, 12345); 235 236 __ cmp(ebx, 12345); 237 __ cmp(ebx, Immediate(12)); 238 __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12)); 239 __ cmpb(eax, 100); 240 241 __ or_(ebx, 12345); 242 243 __ sub(ebx, Immediate(12)); 244 __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12)); 245 246 __ xor_(ebx, 12345); 247 248 __ imul(edx, ecx, 12); 249 __ imul(edx, ecx, 1000); 250 251 __ cld(); 252 __ rep_movs(); 253 __ rep_stos(); 254 __ stos(); 255 256 __ sub(edx, Operand(ebx, ecx, times_4, 10000)); 257 __ sub(edx, ebx); 258 259 __ test(edx, Immediate(12345)); 260 __ test(edx, Operand(ebx, ecx, times_8, 10000)); 261 __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000)); 262 __ test_b(edx, Operand(ecx, ebx, times_2, 1000)); 263 __ test_b(Operand(eax, -20), 0x9A); 264 __ nop(); 265 266 __ xor_(edx, 12345); 267 __ xor_(edx, Operand(ebx, ecx, times_8, 10000)); 268 __ bts(Operand(ebx, ecx, times_8, 10000), edx); 269 __ hlt(); 270 __ int3(); 271 __ ret(0); 272 __ ret(8); 273 274 // Calls 275 276 Label L1, L2; 277 __ bind(&L1); 278 __ nop(); 279 __ call(&L1); 280 __ call(&L2); 281 __ nop(); 282 __ bind(&L2); 283 __ call(Operand(ebx, ecx, times_4, 10000)); 284 __ nop(); 285 Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL)); 286 __ call(ic, RelocInfo::CODE_TARGET); 287 __ nop(); 288 __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY); 289 __ nop(); 290 291 __ jmp(&L1); 292 __ jmp(Operand(ebx, ecx, times_4, 10000)); 293 ExternalReference after_break_target = 294 ExternalReference::debug_after_break_target_address(isolate); 295 __ jmp(Operand::StaticVariable(after_break_target)); 296 __ jmp(ic, RelocInfo::CODE_TARGET); 297 __ nop(); 298 299 300 Label Ljcc; 301 __ nop(); 302 // long jumps 303 __ j(overflow, &Ljcc); 304 __ j(no_overflow, &Ljcc); 305 __ j(below, &Ljcc); 306 __ j(above_equal, &Ljcc); 307 __ j(equal, &Ljcc); 308 __ j(not_equal, &Ljcc); 309 __ j(below_equal, &Ljcc); 310 __ j(above, &Ljcc); 311 __ j(sign, &Ljcc); 312 __ j(not_sign, &Ljcc); 313 __ j(parity_even, &Ljcc); 314 __ j(parity_odd, &Ljcc); 315 __ j(less, &Ljcc); 316 __ j(greater_equal, &Ljcc); 317 __ j(less_equal, &Ljcc); 318 __ j(greater, &Ljcc); 319 __ nop(); 320 __ bind(&Ljcc); 321 // short jumps 322 __ j(overflow, &Ljcc); 323 __ j(no_overflow, &Ljcc); 324 __ j(below, &Ljcc); 325 __ j(above_equal, &Ljcc); 326 __ j(equal, &Ljcc); 327 __ j(not_equal, &Ljcc); 328 __ j(below_equal, &Ljcc); 329 __ j(above, &Ljcc); 330 __ j(sign, &Ljcc); 331 __ j(not_sign, &Ljcc); 332 __ j(parity_even, &Ljcc); 333 __ j(parity_odd, &Ljcc); 334 __ j(less, &Ljcc); 335 __ j(greater_equal, &Ljcc); 336 __ j(less_equal, &Ljcc); 337 __ j(greater, &Ljcc); 338 339 // 0xD9 instructions 340 __ nop(); 341 342 __ fld(1); 343 __ fld1(); 344 __ fldz(); 345 __ fldpi(); 346 __ fabs(); 347 __ fchs(); 348 __ fprem(); 349 __ fprem1(); 350 __ fincstp(); 351 __ ftst(); 352 __ fxam(); 353 __ fxch(3); 354 __ fld_s(Operand(ebx, ecx, times_4, 10000)); 355 __ fstp_s(Operand(ebx, ecx, times_4, 10000)); 356 __ ffree(3); 357 __ fld_d(Operand(ebx, ecx, times_4, 10000)); 358 __ fstp_d(Operand(ebx, ecx, times_4, 10000)); 359 __ nop(); 360 361 __ fild_s(Operand(ebx, ecx, times_4, 10000)); 362 __ fistp_s(Operand(ebx, ecx, times_4, 10000)); 363 __ fild_d(Operand(ebx, ecx, times_4, 10000)); 364 __ fistp_d(Operand(ebx, ecx, times_4, 10000)); 365 __ fnstsw_ax(); 366 __ nop(); 367 __ fadd(3); 368 __ fsub(3); 369 __ fmul(3); 370 __ fdiv(3); 371 372 __ faddp(3); 373 __ fsubp(3); 374 __ fmulp(3); 375 __ fdivp(3); 376 __ fcompp(); 377 __ fwait(); 378 __ frndint(); 379 __ fninit(); 380 __ nop(); 381 382 __ fldcw(Operand(ebx, ecx, times_4, 10000)); 383 __ fnstcw(Operand(ebx, ecx, times_4, 10000)); 384 __ fadd_d(Operand(ebx, ecx, times_4, 10000)); 385 __ fnsave(Operand(ebx, ecx, times_4, 10000)); 386 __ frstor(Operand(ebx, ecx, times_4, 10000)); 387 388 // xchg. 389 { 390 __ xchg(eax, eax); 391 __ xchg(eax, ebx); 392 __ xchg(ebx, ebx); 393 __ xchg(ebx, Operand(esp, 12)); 394 } 395 396 // Nop instructions 397 for (int i = 0; i < 16; i++) { 398 __ Nop(i); 399 } 400 401 __ ret(0); 402 403 CodeDesc desc; 404 assm.GetCode(&desc); 405 Handle<Code> code = isolate->factory()->NewCode( 406 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 407 USE(code); 408#ifdef OBJECT_PRINT 409 OFStream os(stdout); 410 code->Print(os); 411 byte* begin = code->instruction_start(); 412 byte* end = begin + code->instruction_size(); 413 disasm::Disassembler::Disassemble(stdout, begin, end); 414#endif 415} 416 417#undef __ 418