1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Redistribution and use in source and binary forms, with or without 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// modification, are permitted provided that the following conditions are 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// met: 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * Redistributions of source code must retain the above copyright 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// notice, this list of conditions and the following disclaimer. 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * Redistributions in binary form must reproduce the above 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// copyright notice, this list of conditions and the following 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// disclaimer in the documentation and/or other materials provided 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// with the distribution. 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// contributors may be used to endorse or promote products derived 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// from this software without specific prior written permission. 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <stdlib.h> 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h" 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/disasm.h" 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/disassembler.h" 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/macro-assembler.h" 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "test/cctest/cctest.h" 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochusing namespace v8::internal; 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool DisassembleAndCompare(byte* pc, const char* compare_string) { 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch disasm::NameConverter converter; 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch disasm::Disassembler disasm(converter); 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmbeddedVector<char, 128> disasm_buffer; 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch disasm.InstructionDecode(disasm_buffer, pc); 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (strcmp(compare_string, disasm_buffer.start()) != 0) { 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fprintf(stderr, 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "expected: \n" 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "%s\n" 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "disassembled: \n" 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "%s\n\n", 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch compare_string, disasm_buffer.start()); 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Set up V8 to a state where we can at least run the assembler and 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// disassembler. Declare the variables and allocate the data structures used 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// in the rest of the macros. 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SET_UP() \ 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CcTest::InitializeVM(); \ 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::i_isolate(); \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte* buffer = reinterpret_cast<byte*>(malloc(4 * 1024)); \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler assm(isolate, buffer, 4 * 1024); \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool failure = false; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This macro assembles one instruction using the preallocated assembler and 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// disassembles the generated instruction, comparing the output to the expected 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// value. If the comparison fails an error message is printed, but the test 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// continues to run until the end. 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE(asm_, compare_string) \ 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { \ 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pc_offset = assm.pc_offset(); \ 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte* progcounter = &buffer[pc_offset]; \ 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch assm.asm_; \ 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \ 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Force emission of any pending literals into a pool. 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define EMIT_PENDING_LITERALS() assm.CheckConstPool(true, false) 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Verify that all invocations of the COMPARE macro passed successfully. 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Exit with a failure if at least one of the tests failed. 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define VERIFY_RUN() \ 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (failure) { \ 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V8_Fatal(__FILE__, __LINE__, "PPC Disassembler tests failed.\n"); \ 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(DisasmPPC) { 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SET_UP(); 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9"); 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20"); 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, ip, 63"); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0"); 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0"); 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4"); 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(and_(r3, r6, r5), "7cc32838 and r3, r6, r5"); 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(and_(r6, r0, r6, SetRC), "7c063039 and. r6, r0, r6"); 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // skipping branches (for now?) 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(bctr(), "4e800420 bctr"); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(bctrl(), "4e800421 bctrl"); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(blr(), "4e800020 blr"); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// skipping call - only used in simulator 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmpi(r0, Operand(5)), "2fa00005 cmpi r0, 5"); 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmpi(r0, Operand(5)), "2f800005 cmpi r0, 5"); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmpl(r6, r7), "7fa63840 cmpl r6, r7"); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmpl(r6, r7), "7f863840 cmpl r6, r7"); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmp(r5, r11), "7fa55800 cmp r5, r11"); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(cmp(r5, r11), "7f855800 cmp r5, r11"); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // skipping crxor - incomplete disassembly 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(lbz(r4, MemOperand(r4, 7)), "88840007 lbz r4, 7(r4)"); 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)"); 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(li(r0, Operand(16)), "38000010 li r0, 16"); 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560"); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz ip, 44(r19)"); 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, ip"); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(mflr(r0), "7c0802a6 mflr r0"); 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4"); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(mtctr(r0), "7c0903a6 mtctr r0"); 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(mtlr(r15), "7de803a6 mtlr r15"); 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(ori(r8, r8, Operand(42849)), "6108a761 ori r8, r8, 42849"); 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(orx(r5, r3, r4), "7c652378 or r5, r3, r4"); 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(rlwinm(r4, r3, 2, 0, 29), "5464103a rlwinm r4, r3, 2, 0, 29"); 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(rlwinm(r0, r3, 0, 31, 31, SetRC), 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "546007ff rlwinm. r0, r3, 0, 31, 31"); 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(srawi(r3, r6, 1), "7cc30e70 srawi r3,r6,1"); 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(stb(r5, MemOperand(r11, 11)), "98ab000b stb r5, 11(r11)"); 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(stfd(d2, MemOperand(sp, 8)), "d8410008 stfd d2, 8(sp)"); 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(stw(r16, MemOperand(sp, 64)), "92010040 stw r16, 64(sp)"); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(stwu(r3, MemOperand(sp, -4)), "9461fffc stwu r3, -4(sp)"); 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(sub(r3, r3, r4), "7c641850 subf r3, r4, r3"); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(sub(r0, r9, r8, LeaveOE, SetRC), "7c084851 subf. r0, r8, r9"); 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch COMPARE(xor_(r6, r5, r4), "7ca62278 xor r6, r5, r4"); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VERIFY_RUN(); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 155