tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testAssemblerCodeGen.cpp (5556B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "jit/Disassemble.h"
      9 #include "jit/Linker.h"
     10 #include "jit/MacroAssembler.h"
     11 #include "js/GCAPI.h"
     12 
     13 #include "jsapi-tests/tests.h"
     14 #include "jsapi-tests/testsJit.h"
     15 
     16 #include "jit/MacroAssembler-inl.h"
     17 
     18 using namespace js;
     19 using namespace js::jit;
     20 
     21 #if defined(JS_JITSPEW) && defined(JS_CODEGEN_X64)
     22 using DisasmCharVector = js::Vector<char, 64, SystemAllocPolicy>;
     23 static MOZ_THREAD_LOCAL(DisasmCharVector*) disasmResult;
     24 
     25 static void CaptureDisasmText(const char* text) {
     26  // Skip the instruction offset (8 bytes) and two space characters, because the
     27  // offsets make it harder to modify the test.
     28  MOZ_RELEASE_ASSERT(strlen(text) > 10);
     29  text = text + 10;
     30  MOZ_RELEASE_ASSERT(disasmResult.get()->append(text, text + strlen(text)));
     31  MOZ_RELEASE_ASSERT(disasmResult.get()->append('\n'));
     32 }
     33 
     34 BEGIN_TEST(testAssemblerCodeGen_x64_cmp8) {
     35  TempAllocator tempAlloc(&cx->tempLifoAlloc());
     36  JitContext jcx(cx);
     37  StackMacroAssembler masm(cx, tempAlloc);
     38  AutoCreatedBy acb(masm, __func__);
     39 
     40  masm.cmp8(Operand(rax), rbx);
     41  masm.cmp8(Operand(rax), rdi);
     42  masm.cmp8(Operand(rdi), rax);
     43  masm.cmp8(Operand(rdi), rdi);
     44  masm.cmp8(Operand(r10), r13);
     45 
     46  masm.cmp8(Operand(Address(rax, 0)), rbx);
     47  masm.cmp8(Operand(Address(rax, 1)), rdi);
     48  masm.cmp8(Operand(Address(rdi, 0x10)), rax);
     49  masm.cmp8(Operand(Address(rdi, 0x20)), rdi);
     50  masm.cmp8(Operand(Address(r10, 0x30)), r11);
     51  masm.cmp8(Operand(Address(rsp, 0x40)), rdi);
     52 
     53  masm.cmp8(Operand(BaseIndex(rax, rbx, TimesFour, 0)), rcx);
     54  masm.cmp8(Operand(BaseIndex(rax, rbx, TimesEight, 1)), rdi);
     55  masm.cmp8(Operand(BaseIndex(rdi, rax, TimesOne, 2)), rdi);
     56  masm.cmp8(Operand(BaseIndex(rax, rdi, TimesTwo, 3)), rdi);
     57  masm.cmp8(Operand(BaseIndex(r10, r11, TimesFour, 4)), r12);
     58  masm.cmp8(Operand(BaseIndex(rsp, rax, TimesEight, 5)), rdi);
     59 
     60  void* ptr = (void*)0x1234;
     61  masm.cmp8(Operand(AbsoluteAddress(ptr)), rax);
     62  masm.cmp8(Operand(AbsoluteAddress(ptr)), rsi);
     63  masm.cmp8(Operand(AbsoluteAddress(ptr)), r15);
     64 
     65  // For Imm32(0) we emit a |test| instruction.
     66  masm.cmp8(Operand(rax), Imm32(0));
     67  masm.cmp8(Operand(rbx), Imm32(0));
     68  masm.cmp8(Operand(rdi), Imm32(0));
     69  masm.cmp8(Operand(r8), Imm32(0));
     70  masm.cmp8(Operand(rax), Imm32(1));
     71  masm.cmp8(Operand(rbx), Imm32(-1));
     72  masm.cmp8(Operand(rdi), Imm32(2));
     73  masm.cmp8(Operand(r8), Imm32(-2));
     74 
     75  CHECK(!masm.oom());
     76 
     77  Linker linker(masm);
     78  JitCode* code = linker.newCode(cx, CodeKind::Other);
     79  CHECK(code);
     80 
     81  DisasmCharVector disassembled;
     82  disasmResult.set(&disassembled);
     83  auto onFinish = mozilla::MakeScopeExit([&] { disasmResult.set(nullptr); });
     84 
     85  {
     86    // jit::Disassemble can't GC.
     87    JS::AutoSuppressGCAnalysis nogc;
     88    jit::Disassemble(code->raw(), code->instructionsSize(), &CaptureDisasmText);
     89  }
     90 
     91  static const char* expected =
     92      "3a c3                                 cmp %bl, %al\n"
     93      "40 3a c7                              cmp %dil, %al\n"
     94      "40 3a f8                              cmp %al, %dil\n"
     95      "40 3a ff                              cmp %dil, %dil\n"
     96      "45 3a d5                              cmp %r13b, %r10b\n"
     97 
     98      "38 18                                 cmpb %bl, (%rax)\n"
     99      "40 38 78 01                           cmpb %dil, 0x01(%rax)\n"
    100      "38 47 10                              cmpb %al, 0x10(%rdi)\n"
    101      "40 38 7f 20                           cmpb %dil, 0x20(%rdi)\n"
    102      "45 38 5a 30                           cmpb %r11b, 0x30(%r10)\n"
    103      "40 38 7c 24 40                        cmpb %dil, 0x40(%rsp)\n"
    104 
    105      "38 0c 98                              cmpb %cl, (%rax,%rbx,4)\n"
    106      "40 38 7c d8 01                        cmpb %dil, 0x01(%rax,%rbx,8)\n"
    107      "40 38 7c 07 02                        cmpb %dil, 0x02(%rdi,%rax,1)\n"
    108      "40 38 7c 78 03                        cmpb %dil, 0x03(%rax,%rdi,2)\n"
    109      "47 38 64 9a 04                        cmpb %r12b, 0x04(%r10,%r11,4)\n"
    110      "40 38 7c c4 05                        cmpb %dil, 0x05(%rsp,%rax,8)\n"
    111 
    112      "38 04 25 34 12 00 00                  cmpb %al, 0x0000000000001234\n"
    113      "40 38 34 25 34 12 00 00               cmpb %sil, 0x0000000000001234\n"
    114      "44 38 3c 25 34 12 00 00               cmpb %r15b, 0x0000000000001234\n"
    115 
    116      "84 c0                                 test %al, %al\n"
    117      "84 db                                 test %bl, %bl\n"
    118      "40 84 ff                              test %dil, %dil\n"
    119      "45 84 c0                              test %r8b, %r8b\n"
    120      "3c 01                                 cmp $0x01, %al\n"
    121      "80 fb ff                              cmp $-0x01, %bl\n"
    122      "40 80 ff 02                           cmp $0x02, %dil\n"
    123      "41 80 f8 fe                           cmp $-0x02, %r8b\n"
    124 
    125      "0f 0b                                 ud2\n";
    126 
    127  bool matched = disassembled.length() == strlen(expected) &&
    128                 memcmp(expected, disassembled.begin(), strlen(expected)) == 0;
    129  if (!matched) {
    130    CHECK(disassembled.append('\0'));
    131    fprintf(stderr, "Generated:\n%s\n", disassembled.begin());
    132    fprintf(stderr, "Expected:\n%s\n", expected);
    133  }
    134  CHECK(matched);
    135 
    136  return true;
    137 }
    138 END_TEST(testAssemblerCodeGen_x64_cmp8)
    139 
    140 #endif  // defined(JS_JITSPEW) && defined(JS_CODEGEN_X64)