Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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 | |
| 29 | #include <stdlib.h> |
| 30 | |
| 31 | #include "src/v8.h" |
| 32 | |
| 33 | #include "src/debug/debug.h" |
| 34 | #include "src/disasm.h" |
| 35 | #include "src/disassembler.h" |
| 36 | #include "src/macro-assembler.h" |
| 37 | #include "test/cctest/cctest.h" |
| 38 | |
| 39 | using namespace v8::internal; |
| 40 | |
| 41 | |
| 42 | bool DisassembleAndCompare(byte* pc, const char* compare_string) { |
| 43 | disasm::NameConverter converter; |
| 44 | disasm::Disassembler disasm(converter); |
| 45 | EmbeddedVector<char, 128> disasm_buffer; |
| 46 | |
| 47 | disasm.InstructionDecode(disasm_buffer, pc); |
| 48 | |
| 49 | if (strcmp(compare_string, disasm_buffer.start()) != 0) { |
| 50 | fprintf(stderr, |
| 51 | "expected: \n" |
| 52 | "%s\n" |
| 53 | "disassembled: \n" |
| 54 | "%s\n\n", |
| 55 | compare_string, disasm_buffer.start()); |
| 56 | return false; |
| 57 | } |
| 58 | return true; |
| 59 | } |
| 60 | |
| 61 | |
| 62 | // Set up V8 to a state where we can at least run the assembler and |
| 63 | // disassembler. Declare the variables and allocate the data structures used |
| 64 | // in the rest of the macros. |
| 65 | #define SET_UP() \ |
| 66 | CcTest::InitializeVM(); \ |
| 67 | Isolate* isolate = CcTest::i_isolate(); \ |
| 68 | HandleScope scope(isolate); \ |
| 69 | byte* buffer = reinterpret_cast<byte*>(malloc(4 * 1024)); \ |
| 70 | Assembler assm(isolate, buffer, 4 * 1024); \ |
| 71 | bool failure = false; |
| 72 | |
| 73 | |
| 74 | // This macro assembles one instruction using the preallocated assembler and |
| 75 | // disassembles the generated instruction, comparing the output to the expected |
| 76 | // value. If the comparison fails an error message is printed, but the test |
| 77 | // continues to run until the end. |
| 78 | #define COMPARE(asm_, compare_string) \ |
| 79 | { \ |
| 80 | int pc_offset = assm.pc_offset(); \ |
| 81 | byte* progcounter = &buffer[pc_offset]; \ |
| 82 | assm.asm_; \ |
| 83 | if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \ |
| 84 | } |
| 85 | |
| 86 | // Force emission of any pending literals into a pool. |
| 87 | #define EMIT_PENDING_LITERALS() assm.CheckConstPool(true, false) |
| 88 | |
| 89 | |
| 90 | // Verify that all invocations of the COMPARE macro passed successfully. |
| 91 | // Exit with a failure if at least one of the tests failed. |
| 92 | #define VERIFY_RUN() \ |
| 93 | if (failure) { \ |
| 94 | V8_Fatal(__FILE__, __LINE__, "PPC Disassembler tests failed.\n"); \ |
| 95 | } |
| 96 | |
| 97 | TEST(DisasmPPC) { |
| 98 | SET_UP(); |
| 99 | |
| 100 | COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9"); |
| 101 | COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20"); |
| 102 | COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, ip, 63"); |
| 103 | COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0"); |
| 104 | COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0"); |
| 105 | COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4"); |
| 106 | COMPARE(and_(r3, r6, r5), "7cc32838 and r3, r6, r5"); |
| 107 | COMPARE(and_(r6, r0, r6, SetRC), "7c063039 and. r6, r0, r6"); |
| 108 | // skipping branches (for now?) |
| 109 | COMPARE(bctr(), "4e800420 bctr"); |
| 110 | COMPARE(bctrl(), "4e800421 bctrl"); |
| 111 | COMPARE(blr(), "4e800020 blr"); |
| 112 | // skipping call - only used in simulator |
| 113 | #if V8_TARGET_ARCH_PPC64 |
| 114 | COMPARE(cmpi(r0, Operand(5)), "2fa00005 cmpi r0, 5"); |
| 115 | #else |
| 116 | COMPARE(cmpi(r0, Operand(5)), "2f800005 cmpi r0, 5"); |
| 117 | #endif |
| 118 | #if V8_TARGET_ARCH_PPC64 |
| 119 | COMPARE(cmpl(r6, r7), "7fa63840 cmpl r6, r7"); |
| 120 | #else |
| 121 | COMPARE(cmpl(r6, r7), "7f863840 cmpl r6, r7"); |
| 122 | #endif |
| 123 | #if V8_TARGET_ARCH_PPC64 |
| 124 | COMPARE(cmp(r5, r11), "7fa55800 cmp r5, r11"); |
| 125 | #else |
| 126 | COMPARE(cmp(r5, r11), "7f855800 cmp r5, r11"); |
| 127 | #endif |
| 128 | // skipping crxor - incomplete disassembly |
| 129 | COMPARE(lbz(r4, MemOperand(r4, 7)), "88840007 lbz r4, 7(r4)"); |
| 130 | COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)"); |
| 131 | COMPARE(li(r0, Operand(16)), "38000010 li r0, 16"); |
| 132 | COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560"); |
| 133 | COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz ip, 44(r19)"); |
| 134 | COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, ip"); |
| 135 | COMPARE(mflr(r0), "7c0802a6 mflr r0"); |
| 136 | COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4"); |
| 137 | COMPARE(mtctr(r0), "7c0903a6 mtctr r0"); |
| 138 | COMPARE(mtlr(r15), "7de803a6 mtlr r15"); |
| 139 | COMPARE(ori(r8, r8, Operand(42849)), "6108a761 ori r8, r8, 42849"); |
| 140 | COMPARE(orx(r5, r3, r4), "7c652378 or r5, r3, r4"); |
| 141 | COMPARE(rlwinm(r4, r3, 2, 0, 29), "5464103a rlwinm r4, r3, 2, 0, 29"); |
| 142 | COMPARE(rlwinm(r0, r3, 0, 31, 31, SetRC), |
| 143 | "546007ff rlwinm. r0, r3, 0, 31, 31"); |
| 144 | COMPARE(srawi(r3, r6, 1), "7cc30e70 srawi r3,r6,1"); |
| 145 | COMPARE(stb(r5, MemOperand(r11, 11)), "98ab000b stb r5, 11(r11)"); |
| 146 | COMPARE(stfd(d2, MemOperand(sp, 8)), "d8410008 stfd d2, 8(sp)"); |
| 147 | COMPARE(stw(r16, MemOperand(sp, 64)), "92010040 stw r16, 64(sp)"); |
| 148 | COMPARE(stwu(r3, MemOperand(sp, -4)), "9461fffc stwu r3, -4(sp)"); |
| 149 | COMPARE(sub(r3, r3, r4), "7c641850 subf r3, r4, r3"); |
| 150 | COMPARE(sub(r0, r9, r8, LeaveOE, SetRC), "7c084851 subf. r0, r8, r9"); |
| 151 | COMPARE(xor_(r6, r5, r4), "7ca62278 xor r6, r5, r4"); |
| 152 | |
| 153 | VERIFY_RUN(); |
| 154 | } |