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