test-disasm-x87.cc revision 537ba893e2530051ec7f296e769fdd37bb4ae4a0
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/code-factory.h" 33#include "src/debug/debug.h" 34#include "src/disasm.h" 35#include "src/disassembler.h" 36#include "src/macro-assembler.h" 37#include "src/x87/frames-x87.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(edx, Operand(ebx)); 100 __ adc(ecx, 12); 101 __ adc(ecx, 1000); 102 __ nop(); 103 __ and_(edx, 3); 104 __ and_(edx, Operand(esp, 4)); 105 __ cmp(edx, 3); 106 __ cmp(edx, Operand(esp, 4)); 107 __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000)); 108 Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED); 109 __ cmp(ebx, foo2); 110 __ cmpb(ebx, Operand(ebp, ecx, times_2, 0)); 111 __ cmpb(Operand(ebp, ecx, times_2, 0), ebx); 112 __ or_(edx, 3); 113 __ xor_(edx, 3); 114 __ nop(); 115 __ cpuid(); 116 __ movsx_b(edx, ecx); 117 __ movsx_w(edx, ecx); 118 __ movzx_b(edx, ecx); 119 __ movzx_w(edx, ecx); 120 121 __ nop(); 122 __ imul(edx, ecx); 123 __ shld(edx, ecx, 10); 124 __ shld_cl(edx, ecx); 125 __ shrd(edx, ecx, 10); 126 __ shrd_cl(edx, ecx); 127 __ bts(edx, ecx); 128 __ bts(Operand(ebx, ecx, times_4, 0), ecx); 129 __ nop(); 130 __ pushad(); 131 __ popad(); 132 __ pushfd(); 133 __ popfd(); 134 __ push(Immediate(12)); 135 __ push(Immediate(23456)); 136 __ push(ecx); 137 __ push(esi); 138 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 139 __ push(Operand(ebx, ecx, times_4, 0)); 140 __ push(Operand(ebx, ecx, times_4, 0)); 141 __ push(Operand(ebx, ecx, times_4, 10000)); 142 __ pop(edx); 143 __ pop(eax); 144 __ pop(Operand(ebx, ecx, times_4, 0)); 145 __ nop(); 146 147 __ add(edx, Operand(esp, 16)); 148 __ add(edx, ecx); 149 __ mov_b(edx, ecx); 150 __ mov_b(ecx, 6); 151 __ mov_b(Operand(ebx, ecx, times_4, 10000), 6); 152 __ mov_b(Operand(esp, 16), edx); 153 __ mov_w(edx, Operand(esp, 16)); 154 __ mov_w(Operand(esp, 16), edx); 155 __ nop(); 156 __ movsx_w(edx, Operand(esp, 12)); 157 __ movsx_b(edx, Operand(esp, 12)); 158 __ movzx_w(edx, Operand(esp, 12)); 159 __ movzx_b(edx, Operand(esp, 12)); 160 __ nop(); 161 __ mov(edx, 1234567); 162 __ mov(edx, Operand(esp, 12)); 163 __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345)); 164 __ mov(Operand(ebx, ecx, times_4, 10000), edx); 165 __ nop(); 166 __ dec_b(edx); 167 __ dec_b(Operand(eax, 10)); 168 __ dec_b(Operand(ebx, ecx, times_4, 10000)); 169 __ dec(edx); 170 __ cdq(); 171 172 __ nop(); 173 __ idiv(edx); 174 __ idiv(Operand(edx, ecx, times_1, 1)); 175 __ idiv(Operand(esp, 12)); 176 __ div(edx); 177 __ div(Operand(edx, ecx, times_1, 1)); 178 __ div(Operand(esp, 12)); 179 __ mul(edx); 180 __ neg(edx); 181 __ not_(edx); 182 __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456)); 183 184 __ imul(edx, Operand(ebx, ecx, times_4, 10000)); 185 __ imul(edx, ecx, 12); 186 __ imul(edx, Operand(edx, eax, times_2, 42), 8); 187 __ imul(edx, ecx, 1000); 188 __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000); 189 190 __ inc(edx); 191 __ inc(Operand(ebx, ecx, times_4, 10000)); 192 __ push(Operand(ebx, ecx, times_4, 10000)); 193 __ pop(Operand(ebx, ecx, times_4, 10000)); 194 __ call(Operand(ebx, ecx, times_4, 10000)); 195 __ jmp(Operand(ebx, ecx, times_4, 10000)); 196 197 __ lea(edx, Operand(ebx, ecx, times_4, 10000)); 198 __ or_(edx, 12345); 199 __ or_(edx, Operand(ebx, ecx, times_4, 10000)); 200 201 __ nop(); 202 203 __ rcl(edx, 1); 204 __ rcl(edx, 7); 205 __ rcr(edx, 1); 206 __ rcr(edx, 7); 207 __ ror(edx, 1); 208 __ ror(edx, 6); 209 __ ror_cl(edx); 210 __ ror(Operand(ebx, ecx, times_4, 10000), 1); 211 __ ror(Operand(ebx, ecx, times_4, 10000), 6); 212 __ ror_cl(Operand(ebx, ecx, times_4, 10000)); 213 __ sar(edx, 1); 214 __ sar(edx, 6); 215 __ sar_cl(edx); 216 __ sar(Operand(ebx, ecx, times_4, 10000), 1); 217 __ sar(Operand(ebx, ecx, times_4, 10000), 6); 218 __ sar_cl(Operand(ebx, ecx, times_4, 10000)); 219 __ sbb(edx, Operand(ebx, ecx, times_4, 10000)); 220 __ shl(edx, 1); 221 __ shl(edx, 6); 222 __ shl_cl(edx); 223 __ shl(Operand(ebx, ecx, times_4, 10000), 1); 224 __ shl(Operand(ebx, ecx, times_4, 10000), 6); 225 __ shl_cl(Operand(ebx, ecx, times_4, 10000)); 226 __ shrd_cl(Operand(ebx, ecx, times_4, 10000), edx); 227 __ shr(edx, 1); 228 __ shr(edx, 7); 229 __ shr_cl(edx); 230 __ shr(Operand(ebx, ecx, times_4, 10000), 1); 231 __ shr(Operand(ebx, ecx, times_4, 10000), 6); 232 __ shr_cl(Operand(ebx, ecx, times_4, 10000)); 233 234 235 // Immediates 236 237 __ adc(edx, 12345); 238 239 __ add(ebx, Immediate(12)); 240 __ add(Operand(edx, ecx, times_4, 10000), Immediate(12)); 241 242 __ and_(ebx, 12345); 243 244 __ cmp(ebx, 12345); 245 __ cmp(ebx, Immediate(12)); 246 __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12)); 247 __ cmpb(eax, Immediate(100)); 248 249 __ or_(ebx, 12345); 250 251 __ sub(ebx, Immediate(12)); 252 __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12)); 253 254 __ xor_(ebx, 12345); 255 256 __ imul(edx, ecx, 12); 257 __ imul(edx, ecx, 1000); 258 259 __ cld(); 260 __ rep_movs(); 261 __ rep_stos(); 262 __ stos(); 263 264 __ sub(edx, Operand(ebx, ecx, times_4, 10000)); 265 __ sub(edx, ebx); 266 267 __ test(edx, Immediate(12345)); 268 __ test(edx, Operand(ebx, ecx, times_8, 10000)); 269 __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000)); 270 __ test_b(edx, Operand(ecx, ebx, times_2, 1000)); 271 __ test_b(Operand(eax, -20), Immediate(0x9A)); 272 __ nop(); 273 274 __ xor_(edx, 12345); 275 __ xor_(edx, Operand(ebx, ecx, times_8, 10000)); 276 __ bts(Operand(ebx, ecx, times_8, 10000), edx); 277 __ hlt(); 278 __ int3(); 279 __ ret(0); 280 __ ret(8); 281 282 // Calls 283 284 Label L1, L2; 285 __ bind(&L1); 286 __ nop(); 287 __ call(&L1); 288 __ call(&L2); 289 __ nop(); 290 __ bind(&L2); 291 __ call(Operand(ebx, ecx, times_4, 10000)); 292 __ nop(); 293 Handle<Code> ic(CodeFactory::LoadIC(isolate, NOT_INSIDE_TYPEOF).code()); 294 __ call(ic, RelocInfo::CODE_TARGET); 295 __ nop(); 296 __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY); 297 __ nop(); 298 299 __ jmp(&L1); 300 __ jmp(Operand(ebx, ecx, times_4, 10000)); 301 ExternalReference after_break_target = 302 ExternalReference::debug_after_break_target_address(isolate); 303 __ jmp(Operand::StaticVariable(after_break_target)); 304 __ jmp(ic, RelocInfo::CODE_TARGET); 305 __ nop(); 306 307 308 Label Ljcc; 309 __ nop(); 310 // long jumps 311 __ j(overflow, &Ljcc); 312 __ j(no_overflow, &Ljcc); 313 __ j(below, &Ljcc); 314 __ j(above_equal, &Ljcc); 315 __ j(equal, &Ljcc); 316 __ j(not_equal, &Ljcc); 317 __ j(below_equal, &Ljcc); 318 __ j(above, &Ljcc); 319 __ j(sign, &Ljcc); 320 __ j(not_sign, &Ljcc); 321 __ j(parity_even, &Ljcc); 322 __ j(parity_odd, &Ljcc); 323 __ j(less, &Ljcc); 324 __ j(greater_equal, &Ljcc); 325 __ j(less_equal, &Ljcc); 326 __ j(greater, &Ljcc); 327 __ nop(); 328 __ bind(&Ljcc); 329 // short jumps 330 __ j(overflow, &Ljcc); 331 __ j(no_overflow, &Ljcc); 332 __ j(below, &Ljcc); 333 __ j(above_equal, &Ljcc); 334 __ j(equal, &Ljcc); 335 __ j(not_equal, &Ljcc); 336 __ j(below_equal, &Ljcc); 337 __ j(above, &Ljcc); 338 __ j(sign, &Ljcc); 339 __ j(not_sign, &Ljcc); 340 __ j(parity_even, &Ljcc); 341 __ j(parity_odd, &Ljcc); 342 __ j(less, &Ljcc); 343 __ j(greater_equal, &Ljcc); 344 __ j(less_equal, &Ljcc); 345 __ j(greater, &Ljcc); 346 347 // 0xD9 instructions 348 __ nop(); 349 350 __ fld(1); 351 __ fld1(); 352 __ fldz(); 353 __ fldpi(); 354 __ fabs(); 355 __ fchs(); 356 __ fprem(); 357 __ fprem1(); 358 __ fincstp(); 359 __ ftst(); 360 __ fxam(); 361 __ fxch(3); 362 __ fld_s(Operand(ebx, ecx, times_4, 10000)); 363 __ fstp_s(Operand(ebx, ecx, times_4, 10000)); 364 __ ffree(3); 365 __ fld_d(Operand(ebx, ecx, times_4, 10000)); 366 __ fstp_d(Operand(ebx, ecx, times_4, 10000)); 367 __ nop(); 368 369 __ fild_s(Operand(ebx, ecx, times_4, 10000)); 370 __ fistp_s(Operand(ebx, ecx, times_4, 10000)); 371 __ fild_d(Operand(ebx, ecx, times_4, 10000)); 372 __ fistp_d(Operand(ebx, ecx, times_4, 10000)); 373 __ fnstsw_ax(); 374 __ nop(); 375 __ fadd(3); 376 __ fsub(3); 377 __ fmul(3); 378 __ fdiv(3); 379 380 __ faddp(3); 381 __ fsubp(3); 382 __ fmulp(3); 383 __ fdivp(3); 384 __ fcompp(); 385 __ fwait(); 386 __ frndint(); 387 __ fninit(); 388 __ nop(); 389 390 __ fldcw(Operand(ebx, ecx, times_4, 10000)); 391 __ fnstcw(Operand(ebx, ecx, times_4, 10000)); 392 __ fadd_d(Operand(ebx, ecx, times_4, 10000)); 393 __ fnsave(Operand(ebx, ecx, times_4, 10000)); 394 __ frstor(Operand(ebx, ecx, times_4, 10000)); 395 396 // xchg. 397 { 398 __ xchg(eax, eax); 399 __ xchg(eax, ebx); 400 __ xchg(ebx, ebx); 401 __ xchg(ebx, Operand(esp, 12)); 402 } 403 404 // Nop instructions 405 for (int i = 0; i < 16; i++) { 406 __ Nop(i); 407 } 408 409 __ ret(0); 410 411 CodeDesc desc; 412 assm.GetCode(&desc); 413 Handle<Code> code = isolate->factory()->NewCode( 414 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 415 USE(code); 416#ifdef OBJECT_PRINT 417 OFStream os(stdout); 418 code->Print(os); 419 byte* begin = code->instruction_start(); 420 byte* end = begin + code->instruction_size(); 421 disasm::Disassembler::Disassemble(stdout, begin, end); 422#endif 423} 424 425#undef __ 426