1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright (c) 1994-2006 Sun Microsystems Inc. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// All Rights Reserved. 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Redistribution and use in source and binary forms, with or without 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// modification, are permitted provided that the following conditions 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// are met: 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Redistributions of source code must retain the above copyright notice, 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// this list of conditions and the following disclaimer. 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Redistribution in binary form must reproduce the above copyright 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// notice, this list of conditions and the following disclaimer in the 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// documentation and/or other materials provided with the 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// distribution. 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// - Neither the name of Sun Microsystems or the names of contributors may 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// be used to endorse or promote products derived from this software without 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// specific prior written permission. 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// OF THE POSSIBILITY OF SUCH DAMAGE. 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The original source code covered by the above license above has been 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// modified significantly by Google Inc. 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// A light-weight PPC Assembler 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Generates user mode instructions for the PPC architecture up 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifndef V8_PPC_ASSEMBLER_PPC_H_ 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define V8_PPC_ASSEMBLER_PPC_H_ 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <stdio.h> 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <vector> 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/assembler.h" 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/constants-ppc.h" 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 49109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#if V8_HOST_ARCH_PPC && \ 50109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN)) 51109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_USES_FUNCTION_DESCRIPTORS 1 52109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#else 53109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_USES_FUNCTION_DESCRIPTORS 0 54109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 56109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 57109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_PASSES_HANDLES_IN_REGS 1 58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#else 59109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_PASSES_HANDLES_IN_REGS 0 60109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 62109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#if !V8_HOST_ARCH_PPC || !V8_TARGET_ARCH_PPC64 || V8_TARGET_LITTLE_ENDIAN 63109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 1 64109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#else 65109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_RETURNS_OBJECT_PAIRS_IN_REGS 0 66109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if !V8_HOST_ARCH_PPC || (V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ABI_CALL_VIA_IP 1 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ABI_CALL_VIA_IP 0 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 75109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_TOC_REGISTER 2 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 77109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ABI_TOC_REGISTER 13 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clang-format off 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \ 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp) 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_EMBEDDED_CONSTANT_POOL 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r3) V(r4) V(r5) V(r6) V(r7) \ 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) V(r9) V(r10) V(r14) V(r15) \ 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r24) V(r25) V(r26) V(r27) V(r30) 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r3) V(r4) V(r5) V(r6) V(r7) \ 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) V(r9) V(r10) V(r14) V(r15) \ 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r24) V(r25) V(r26) V(r27) V(r28) V(r30) 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \ 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SIMD128_REGISTERS DOUBLE_REGISTERS 114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) \ 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clang-format on 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// CPU Registers. 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 1) We would prefer to use an enum, but enum values are assignment- 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// compatible with int, which has caused code-generation bugs. 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 2) We would prefer to use a class instead of a struct but we don't like 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the register initialization to depend on the particular initialization 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// order (which appears to be different on OS X, Linux, and Windows for the 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// installed versions of C++ we tried). Using a struct permits C-style 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// "initialization". Also, the Register objects cannot be const as this 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// forces initialization stubs in MSVC, making us dependent on initialization 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// order. 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// 3) By not using an enum, we are possibly preventing the compiler from 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// doing certain constant folds, which may significantly reduce the 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// code generated for some assembly instructions (because they boil down 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// to a few constants). If this is a problem, we could change the code 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// such that we use an enum in optimized mode, and the struct in debug 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// mode. This way we get the compile-time error checking in debug mode 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// and best performance in optimized code. 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct Register { 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_COUNT(R) 1 + 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumAllocatable = 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0; 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_COUNT 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_BIT(R) 1 << kCode_##R | 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const RegList kAllocatable = 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT)0; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_BIT 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Register from_code(int code) { 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code >= 0); 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code < kNumRegisters); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register r = {code}; 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return r; 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int code() const { 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit() const { 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_code(int code) { 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg_code = code; 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_LITTLE_ENDIAN 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMantissaOffset = 0; 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kExponentOffset = 4; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMantissaOffset = 4; 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kExponentOffset = 0; 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Unfortunately we can't make this private in a struct. 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Aliases 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kLithiumScratch = r11; // lithium scratch. 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kConstantPoolRegister = r28; // Constant pool. 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kRootRegister = r29; // Roots array pointer. 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register cp = r30; // JavaScript context pointer. 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic const bool kSimpleFPAliasing = true; 20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic const bool kSimdMaskRegisters = false; 21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Double word FP register. 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct DoubleRegister { 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = kNumRegisters; 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int code() const { 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit() const { 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static DoubleRegister from_code(int code) { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister r = {code}; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return r; 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef DoubleRegister FloatRegister; 244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// TODO(ppc) Define SIMD registers. 246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef DoubleRegister Simd128Register; 247bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \ 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const DoubleRegister R = {DoubleRegister::kCode_##R}; 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER) 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_dreg = {Register::kCode_no_reg}; 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Aliases for double registers. Defined using #define instead of 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// "static const DoubleRegister&" because Clang complains otherwise when a 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// compilation unit that includes this header doesn't use the variables. 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kFirstCalleeSavedDoubleReg d14 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kLastCalleeSavedDoubleReg d31 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kDoubleRegZero d14 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kScratchDoubleReg d13 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegister ToRegister(int num); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Coprocessor register 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct CRegister { 266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < 8; } 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(CRegister creg) const { return reg_code == creg.reg_code; } 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int code() const { 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int bit() const { 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_valid()); 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Unfortunately we can't make this private in a struct. 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister no_creg = {-1}; 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr0 = {0}; 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr1 = {1}; 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr2 = {2}; 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr3 = {3}; 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr4 = {4}; 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr5 = {5}; 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr6 = {6}; 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst CRegister cr7 = {7}; 292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// ----------------------------------------------------------------------------- 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Machine instruction Operands 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64; 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32; 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Class Operand represents a shifter operand in data processing instructions 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Operand BASE_EMBEDDED { 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // immediate 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(explicit Operand(intptr_t immediate, 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RelocInfo::Mode rmode = kRelocInfo_NONEPTR)); 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(explicit Operand(const ExternalReference& f)); 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit Operand(Handle<Object> handle); 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(explicit Operand(Smi* value)); 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // rm 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(explicit Operand(Register rm)); 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return true if this is a register operand. 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(bool is_reg() const); 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool must_output_reloc_info(const Assembler* assembler) const; 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline intptr_t immediate() const { 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!rm_.is_valid()); 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return imm_; 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register rm() const { return rm_; } 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register rm_; 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t imm_; // valid if rm_ == no_reg 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RelocInfo::Mode rmode_; 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class Assembler; 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class MacroAssembler; 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Class MemOperand represents a memory operand in load and store instructions 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// On PowerPC we have base register + 16bit signed value 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Alternatively we can have a 16bit signed value immediate 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass MemOperand BASE_EMBEDDED { 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit MemOperand(Register rn, int32_t offset = 0); 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit MemOperand(Register ra, Register rb); 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset() const { 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(rb_.is(no_reg)); 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return offset_; 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // PowerPC - base register 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register ra() const { 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!ra_.is(no_reg)); 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ra_; 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register rb() const { 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(offset_ == 0 && !rb_.is(no_reg)); 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return rb_; 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register ra_; // base 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t offset_; // offset 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register rb_; // index 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class Assembler; 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DeferredRelocInfo { 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeferredRelocInfo() {} 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data) 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : position_(position), rmode_(rmode), data_(data) {} 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position() const { return position_; } 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode rmode() const { return rmode_; } 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t data() const { return data_; } 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position_; 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode rmode_; 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t data_; 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Assembler : public AssemblerBase { 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Create an assembler. Instructions and relocation information are emitted 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // into a buffer, with the instructions starting from the beginning and the 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // relocation information starting from the end of the buffer. See CodeDesc 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for a detailed comment on the layout (globals.h). 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the provided buffer is NULL, the assembler allocates and grows its own 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // buffer, and buffer_size determines the initial buffer size. The buffer is 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // owned by the assembler and deallocated upon destruction of the assembler. 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the provided buffer is not NULL, the assembler uses the provided buffer 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for code generation and assumes its size to be buffer_size. If the buffer 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // is too small, a fatal error occurs. No deallocation of the buffer is done 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // upon destruction of the assembler. 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Assembler(Isolate* isolate, void* buffer, int buffer_size); 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier virtual ~Assembler() {} 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // GetCode emits any pending (non-emitted) code and fills the descriptor 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // desc. GetCode() is idempotent; it returns the same result if no other 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assembler functions are invoked in between GetCode() calls. 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void GetCode(CodeDesc* desc); 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Label operations & relative jumps (PPUM Appendix D) 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Takes a branch opcode (cc) and a label (L) and generates 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // either a backward branch or a forward branch and links it 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to the label fixup chain. Usage: 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Label L; // unbound label 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // j(cc, &L); // forward branch to unbound label 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // bind(&L); // bind label to the current pc 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // j(cc, &L); // backward branch to bound label 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // bind(&L); // illegal: a label may be bound only once 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Note: The same Label can be used for forward and backward branches 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // but it may be bound only once. 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bind(Label* L); // binds an unbound label L to the current code position 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Links a label at the current pc_offset(). If already bound, returns the 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // bound position. If already linked, returns the position of the prior link. 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise, returns the current pc_offset(). 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int link(Label* L); 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Determines if Label is bound and near enough so that a single 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // branch instruction can be used to reach it. 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_near(Label* L, Condition cond); 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Returns the branch offset to the given label from the current code position 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Links the label to the current position if it is still unbound 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int branch_offset(Label* L) { 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (L->is_unused() && !trampoline_emitted_) { 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TrackBranch(); 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return link(L) - pc_offset(); 445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Puts a labels target address at the given position. 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The high 8 bits are set to zero. 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void label_at_put(Label* L, int at_offset); 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static bool IsConstantPoolLoadStart( 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address pc, ConstantPoolEntry::Access* access = nullptr)); 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static bool IsConstantPoolLoadEnd( 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address pc, ConstantPoolEntry::Access* access = nullptr)); 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static int GetConstantPoolOffset(Address pc, 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type)); 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(void PatchConstantPoolAccessInstruction( 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pc_offset, int offset, ConstantPoolEntry::Access access, 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type)); 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return the address in the constant pool of the code target address used by 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the branch/call instruction at pc, or the object in a mov. 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(static Address target_constant_pool_address_at( 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address pc, Address constant_pool, ConstantPoolEntry::Access access, 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type)); 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Read/Modify the code target address in the branch/call instruction at pc. 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(static Address target_address_at(Address pc, Address constant_pool)); 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(static void set_target_address_at( 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch INLINE(static Address target_address_at(Address pc, Code* code)); 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(static void set_target_address_at( 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return the code target address at a call site from the return address 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // of that call in the instruction stream. 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline static Address target_address_from_return_address(Address pc); 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Given the address of the beginning of a call, return the address 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // in the instruction stream that the call will return to. 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier INLINE(static Address return_address_from_call_start(Address pc)); 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This sets the branch destination. 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This is for calls and branches within generated code. 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline static void deserialization_set_special_target_at( 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target); 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Size of an instruction. 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kInstrSize = sizeof(Instr); 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Here we are patching the address in the LUI/ORI instruction pair. 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // These values are used in the serialization process and must be zero for 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // PPC platform, as Code, Embedded Object or External-reference pointers 503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // are split across two consecutive instructions and don't exist separately 504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // in the code, so the serializer should not step forwards in memory after 505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // a target is resolved and written. 506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kSpecialTargetSize = 0; 507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Number of instructions to load an address via a mov sequence. 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMovInstructionsConstantPool = 1; 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMovInstructionsNoConstantPool = 5; 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(V8_PPC_TAGGING_OPT) 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kTaggedLoadInstructions = 1; 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kTaggedLoadInstructions = 2; 516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMovInstructionsConstantPool = 1; 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMovInstructionsNoConstantPool = 2; 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kTaggedLoadInstructions = 1; 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMovInstructions = FLAG_enable_embedded_constant_pool 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kMovInstructionsConstantPool 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : kMovInstructionsNoConstantPool; 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Distance between the instruction referring to the address of the call 527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // target and the return address. 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call sequence is a FIXED_SEQUENCE: 530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mov r8, @ call address 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mtlr r8 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // blrl 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // @ return address 534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kCallTargetAddressOffset = 535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kMovInstructions + 2) * kInstrSize; 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Distance between start of patched debug break slot and the emitted address 538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to jump to. 539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Patched debug break slot code is a FIXED_SEQUENCE: 540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mov r0, <address> 541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mtlr r0 542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // blrl 543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This is the length of the code sequence from SetDebugBreakAtSlot() 546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // FIXED_SEQUENCE 547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kDebugBreakSlotInstructions = 548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMovInstructionsNoConstantPool + 2; 549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kDebugBreakSlotLength = 550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kDebugBreakSlotInstructions * kInstrSize; 551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ((cr.code() * CRWIDTH) + crbit); 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // --------------------------------------------------------------------------- 557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code generation 558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Insert the smallest number of nop instructions 560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // possible to align the pc offset to a multiple 561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // of m. m must be a power of 2 (>= 4). 562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Align(int m); 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Aligns code to something that's optimal for a jump target for the platform. 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CodeTargetAlign(); 568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Branch instructions 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bclr(BOfield bo, int condition_bit, LKBit lk); 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void blr(); 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bc(int branch_offset, BOfield bo, int condition_bit, LKBit lk = LeaveLK); 573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void b(int branch_offset, LKBit lk); 574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bcctr(BOfield bo, int condition_bit, LKBit lk); 576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bctr(); 577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bctrl(); 578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Convenience branch instructions using labels 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void b(Label* L, LKBit lk = LeaveLK) { b(branch_offset(L), lk); } 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline CRegister cmpi_optimization(CRegister cr) { 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check whether the branch is preceeded by an optimizable cmpi against 0. 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The cmpi can be deleted if it is also preceeded by an instruction that 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // sets the register used by the compare and supports a dot form. 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned int sradi_mask = kOpcodeMask | kExt2OpcodeVariant2Mask; 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned int srawi_mask = kOpcodeMask | kExt2OpcodeMask; 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pos = pc_offset(); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int cmpi_pos = pc_offset() - kInstrSize; 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cmpi_pos > 0 && optimizable_cmpi_pos_ == cmpi_pos && 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpi_cr_.code() == cr.code() && last_bound_pos_ != pos) { 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int xpos = cmpi_pos - kInstrSize; 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int xinstr = instr_at(xpos); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int cmpi_ra = (instr_at(cmpi_pos) & 0x1f0000) >> 16; 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // ra is at the same bit position for the three cases below. 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ra = (xinstr & 0x1f0000) >> 16; 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cmpi_ra == ra) { 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((xinstr & sradi_mask) == (EXT2 | SRADIX)) { 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cr0; 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(xpos, xinstr | SetRC); 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ -= kInstrSize; 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if ((xinstr & srawi_mask) == (EXT2 | SRAWIX)) { 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cr0; 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr_at_put(xpos, xinstr | SetRC); 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ -= kInstrSize; 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if ((xinstr & kOpcodeMask) == ANDIx) { 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cr0; 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ -= kInstrSize; 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // nothing to do here since andi. records. 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // didn't match one of the above, must keep cmpwi. 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return cr; 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bc_short(Condition cond, Label* L, CRegister cr = cr7, 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LKBit lk = LeaveLK) { 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(cond != al); 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(cr.code() >= 0 && cr.code() <= 7); 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cmpi_optimization(cr); 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int b_offset = branch_offset(L); 626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (cond) { 628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case eq: 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BT, encode_crbit(cr, CR_EQ), lk); 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ne: 632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BF, encode_crbit(cr, CR_EQ), lk); 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case gt: 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BT, encode_crbit(cr, CR_GT), lk); 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case le: 638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BF, encode_crbit(cr, CR_GT), lk); 639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case lt: 641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BT, encode_crbit(cr, CR_LT), lk); 642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ge: 644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BF, encode_crbit(cr, CR_LT), lk); 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case unordered: 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BT, encode_crbit(cr, CR_FU), lk); 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case ordered: 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BF, encode_crbit(cr, CR_FU), lk); 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case overflow: 653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BT, encode_crbit(cr, CR_SO), lk); 654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case nooverflow: 656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc(b_offset, BF, encode_crbit(cr, CR_SO), lk); 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNIMPLEMENTED(); 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bclr(Condition cond, CRegister cr = cr7, LKBit lk = LeaveLK) { 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cond != al); 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cr.code() >= 0 && cr.code() <= 7); 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cmpi_optimization(cr); 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cond) { 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case eq: 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BT, encode_crbit(cr, CR_EQ), lk); 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ne: 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BF, encode_crbit(cr, CR_EQ), lk); 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case gt: 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BT, encode_crbit(cr, CR_GT), lk); 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case le: 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BF, encode_crbit(cr, CR_GT), lk); 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case lt: 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BT, encode_crbit(cr, CR_LT), lk); 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ge: 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BF, encode_crbit(cr, CR_LT), lk); 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case unordered: 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BT, encode_crbit(cr, CR_FU), lk); 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ordered: 692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BF, encode_crbit(cr, CR_FU), lk); 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case overflow: 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BT, encode_crbit(cr, CR_SO), lk); 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case nooverflow: 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bclr(BF, encode_crbit(cr, CR_SO), lk); 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void isel(Register rt, Register ra, Register rb, int cb); 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void isel(Condition cond, Register rt, Register ra, Register rb, 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cr = cr7) { 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cond != al); 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cr.code() >= 0 && cr.code() <= 7); 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr = cmpi_optimization(cr); 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cond) { 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case eq: 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, ra, rb, encode_crbit(cr, CR_EQ)); 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ne: 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, rb, ra, encode_crbit(cr, CR_EQ)); 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case gt: 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, ra, rb, encode_crbit(cr, CR_GT)); 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case le: 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, rb, ra, encode_crbit(cr, CR_GT)); 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case lt: 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, ra, rb, encode_crbit(cr, CR_LT)); 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ge: 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, rb, ra, encode_crbit(cr, CR_LT)); 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case unordered: 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, ra, rb, encode_crbit(cr, CR_FU)); 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ordered: 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, rb, ra, encode_crbit(cr, CR_FU)); 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case overflow: 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, ra, rb, encode_crbit(cr, CR_SO)); 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case nooverflow: 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isel(rt, rb, ra, encode_crbit(cr, CR_SO)); 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void b(Condition cond, Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (cond == al) { 751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(L, lk); 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((L->is_bound() && is_near(L, cond)) || !is_trampoline_emitted()) { 756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc_short(cond, L, cr, lk); 757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label skip; 761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Condition neg_cond = NegateCondition(cond); 762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bc_short(neg_cond, &skip, cr); 763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(L, lk); 764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bind(&skip); 765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bne(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(ne, L, cr, lk); 769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void beq(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(eq, L, cr, lk); 772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void blt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(lt, L, cr, lk); 775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bge(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(ge, L, cr, lk); 778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ble(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(le, L, cr, lk); 781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bgt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(gt, L, cr, lk); 784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bunordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(unordered, L, cr, lk); 787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) { 789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(ordered, L, cr, lk); 790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void boverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) { 792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(overflow, L, cr, lk); 793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bnooverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) { 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier b(nooverflow, L, cr, lk); 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Decrement CTR; branch if CTR != 0 799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bdnz(Label* L, LKBit lk = LeaveLK) { 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bc(branch_offset(L), DCBNZ, 0, lk); 801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Data-processing instructions 804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sub(Register dst, Register src1, Register src2, OEBit s = LeaveOE, 806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void subc(Register dst, Register src1, Register src2, OEBit s = LeaveOE, 8093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RCBit r = LeaveRC); 8103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void sube(Register dst, Register src1, Register src2, OEBit s = LeaveOE, 8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RCBit r = LeaveRC); 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void subfic(Register dst, Register src, const Operand& imm); 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void add(Register dst, Register src1, Register src2, OEBit s = LeaveOE, 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addc(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 8203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void adde(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 8213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RCBit r = LeaveRC); 8223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void addze(Register dst, Register src1, OEBit o = LeaveOE, RCBit r = LeaveRC); 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mullw(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulhw(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulhwu(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divw(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void divwu(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit r = LeaveRC); 83462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void modsw(Register rt, Register ra, Register rb); 83562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void moduw(Register rt, Register ra, Register rb); 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addi(Register dst, Register src, const Operand& imm); 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addis(Register dst, Register src, const Operand& imm); 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addic(Register dst, Register src, const Operand& imm); 840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void and_(Register dst, Register src1, Register src2, RCBit rc = LeaveRC); 842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void andc(Register dst, Register src1, Register src2, RCBit rc = LeaveRC); 843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void andi(Register ra, Register rs, const Operand& imm); 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void andis(Register ra, Register rs, const Operand& imm); 845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void nor(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void notx(Register dst, Register src, RCBit r = LeaveRC); 847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ori(Register dst, Register src, const Operand& imm); 848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void oris(Register dst, Register src, const Operand& imm); 849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void orx(Register dst, Register src1, Register src2, RCBit rc = LeaveRC); 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void orc(Register dst, Register src1, Register src2, RCBit rc = LeaveRC); 851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void xori(Register dst, Register src, const Operand& imm); 852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void xoris(Register ra, Register rs, const Operand& imm); 853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void xor_(Register dst, Register src1, Register src2, RCBit rc = LeaveRC); 854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmpi(Register src1, const Operand& src2, CRegister cr = cr7); 855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmpli(Register src1, const Operand& src2, CRegister cr = cr7); 856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmpwi(Register src1, const Operand& src2, CRegister cr = cr7); 857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmplwi(Register src1, const Operand& src2, CRegister cr = cr7); 858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void li(Register dst, const Operand& src); 859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lis(Register dst, const Operand& imm); 860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mr(Register dst, Register src); 861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lbz(Register dst, const MemOperand& src); 863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lbzx(Register dst, const MemOperand& src); 864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lbzux(Register dst, const MemOperand& src); 865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lhz(Register dst, const MemOperand& src); 866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lhzx(Register dst, const MemOperand& src); 867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lhzux(Register dst, const MemOperand& src); 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lha(Register dst, const MemOperand& src); 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lhax(Register dst, const MemOperand& src); 870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwz(Register dst, const MemOperand& src); 871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwzu(Register dst, const MemOperand& src); 872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwzx(Register dst, const MemOperand& src); 873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwzux(Register dst, const MemOperand& src); 874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwa(Register dst, const MemOperand& src); 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lwax(Register dst, const MemOperand& src); 876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ldbrx(Register dst, const MemOperand& src); 877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void lwbrx(Register dst, const MemOperand& src); 878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void lhbrx(Register dst, const MemOperand& src); 879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stb(Register dst, const MemOperand& src); 880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stbx(Register dst, const MemOperand& src); 881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stbux(Register dst, const MemOperand& src); 882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sth(Register dst, const MemOperand& src); 883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sthx(Register dst, const MemOperand& src); 884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sthux(Register dst, const MemOperand& src); 885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stw(Register dst, const MemOperand& src); 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stwu(Register dst, const MemOperand& src); 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stwx(Register rs, const MemOperand& src); 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stwux(Register rs, const MemOperand& src); 889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void extsb(Register rs, Register ra, RCBit r = LeaveRC); 891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void extsh(Register rs, Register ra, RCBit r = LeaveRC); 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void extsw(Register rs, Register ra, RCBit r = LeaveRC); 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void neg(Register rt, Register ra, OEBit o = LeaveOE, RCBit c = LeaveRC); 895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ld(Register rd, const MemOperand& src); 898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ldx(Register rd, const MemOperand& src); 899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ldu(Register rd, const MemOperand& src); 900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ldux(Register rd, const MemOperand& src); 901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void std(Register rs, const MemOperand& src); 902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stdx(Register rs, const MemOperand& src); 903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stdu(Register rs, const MemOperand& src); 904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stdux(Register rs, const MemOperand& src); 905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rldic(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC); 906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rldicl(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC); 907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rldcl(Register ra, Register rs, Register rb, int mb, RCBit r = LeaveRC); 908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rldicr(Register dst, Register src, int sh, int me, RCBit r = LeaveRC); 909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rldimi(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC); 910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sldi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC); 911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srdi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC); 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void clrrdi(Register dst, Register src, const Operand& val, 913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void clrldi(Register dst, Register src, const Operand& val, 915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sradi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srd(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sld(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srad(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotld(Register ra, Register rs, Register rb, RCBit r = LeaveRC); 921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotldi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotrdi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cntlzd_(Register dst, Register src, RCBit rc = LeaveRC); 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntd(Register dst, Register src); 925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void divdu(Register dst, Register src1, Register src2, OEBit o = LeaveOE, 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit r = LeaveRC); 93162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void modsd(Register rt, Register ra, Register rb); 93262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void modud(Register rt, Register ra, Register rb); 933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rlwinm(Register ra, Register rs, int sh, int mb, int me, 936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rlwimi(Register ra, Register rs, int sh, int mb, int me, 938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rlwnm(Register ra, Register rs, Register rb, int mb, int me, 940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void slwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC); 942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC); 943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void clrrwi(Register dst, Register src, const Operand& val, 944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void clrlwi(Register dst, Register src, const Operand& val, 946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srawi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void srw(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void slw(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sraw(Register dst, Register src1, Register src2, RCBit r = LeaveRC); 951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotlw(Register ra, Register rs, Register rb, RCBit r = LeaveRC); 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotlwi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void rotrwi(Register ra, Register rs, int sh, RCBit r = LeaveRC); 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cntlzw_(Register dst, Register src, RCBit rc = LeaveRC); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntw(Register dst, Register src); 957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subi(Register dst, Register src1, const Operand& src2); 959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmp(Register src1, Register src2, CRegister cr = cr7); 961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmpl(Register src1, Register src2, CRegister cr = cr7); 962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmpw(Register src1, Register src2, CRegister cr = cr7); 963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cmplw(Register src1, Register src2, CRegister cr = cr7); 964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov(Register dst, const Operand& src); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bitwise_mov(Register dst, intptr_t value); 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bitwise_mov32(Register dst, int32_t value); 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bitwise_add32(Register dst, Register src, int32_t value); 969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Load the position of the label relative to the generated code object 971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // pointer in a register. 972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov_label_offset(Register dst, Label* label); 973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // dst = base + label position + delta 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void add_label_offset(Register dst, Register base, Label* label, 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int delta = 0); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the address of the label in a register and associate with an 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // internal reference relocation. 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mov_label_addr(Register dst, Label* label); 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit the address of the label (i.e. a jump table entry) and associate with 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // an internal reference relocation. 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void emit_label_addr(Label* label); 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Multiply instructions 987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE, 988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r = LeaveRC); 989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Miscellaneous arithmetic instructions 991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Special register access 993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void crxor(int bt, int ba, int bb); 994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void crclr(int bt) { crxor(bt, bt, bt); } 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void creqv(int bt, int ba, int bb); 996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void crset(int bt) { creqv(bt, bt, bt); } 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mflr(Register dst); 998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtlr(Register src); 999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtctr(Register src); 1000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtxer(Register src); 1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mcrfs(CRegister cr, FPSCRBit bit); 1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mfcr(Register dst); 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mffprd(Register dst, DoubleRegister src); 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mffprwz(Register dst, DoubleRegister src); 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtfprd(DoubleRegister dst, Register src); 1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtfprwz(DoubleRegister dst, Register src); 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtfprwa(DoubleRegister dst, Register src); 1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void function_descriptor(); 1012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Exception-generating instructions and debugging support 1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stop(const char* msg, Condition cond = al, 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t code = kDefaultStopCode, CRegister cr = cr7); 1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bkpt(uint32_t imm16); // v5 and above 1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void dcbf(Register ra, Register rb); 1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sync(); 1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lwsync(); 1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void icbi(Register ra, Register rb); 1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void isync(); 1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Support for floating point 1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfd(const DoubleRegister frt, const MemOperand& src); 1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfdu(const DoubleRegister frt, const MemOperand& src); 1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfdx(const DoubleRegister frt, const MemOperand& src); 1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfdux(const DoubleRegister frt, const MemOperand& src); 1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfs(const DoubleRegister frt, const MemOperand& src); 1031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfsu(const DoubleRegister frt, const MemOperand& src); 1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfsx(const DoubleRegister frt, const MemOperand& src); 1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void lfsux(const DoubleRegister frt, const MemOperand& src); 1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfd(const DoubleRegister frs, const MemOperand& src); 1035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfdu(const DoubleRegister frs, const MemOperand& src); 1036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfdx(const DoubleRegister frs, const MemOperand& src); 1037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfdux(const DoubleRegister frs, const MemOperand& src); 1038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfs(const DoubleRegister frs, const MemOperand& src); 1039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfsu(const DoubleRegister frs, const MemOperand& src); 1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfsx(const DoubleRegister frs, const MemOperand& src); 1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void stfsux(const DoubleRegister frs, const MemOperand& src); 1042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fadd(const DoubleRegister frt, const DoubleRegister fra, 1044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frb, RCBit rc = LeaveRC); 1045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fsub(const DoubleRegister frt, const DoubleRegister fra, 1046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frb, RCBit rc = LeaveRC); 1047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fdiv(const DoubleRegister frt, const DoubleRegister fra, 1048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frb, RCBit rc = LeaveRC); 1049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fmul(const DoubleRegister frt, const DoubleRegister fra, 1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frc, RCBit rc = LeaveRC); 1051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fcmpu(const DoubleRegister fra, const DoubleRegister frb, 1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CRegister cr = cr7); 1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fmr(const DoubleRegister frt, const DoubleRegister frb, 1054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fctiwz(const DoubleRegister frt, const DoubleRegister frb); 1056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fctiw(const DoubleRegister frt, const DoubleRegister frb); 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void frin(const DoubleRegister frt, const DoubleRegister frb, 1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void friz(const DoubleRegister frt, const DoubleRegister frb, 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void frip(const DoubleRegister frt, const DoubleRegister frb, 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void frim(const DoubleRegister frt, const DoubleRegister frb, 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void frsp(const DoubleRegister frt, const DoubleRegister frb, 1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fcfid(const DoubleRegister frt, const DoubleRegister frb, 1068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fcfidu(const DoubleRegister frt, const DoubleRegister frb, 1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fcfidus(const DoubleRegister frt, const DoubleRegister frb, 1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fcfids(const DoubleRegister frt, const DoubleRegister frb, 1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fctid(const DoubleRegister frt, const DoubleRegister frb, 1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fctidz(const DoubleRegister frt, const DoubleRegister frb, 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fctidu(const DoubleRegister frt, const DoubleRegister frb, 1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fctiduz(const DoubleRegister frt, const DoubleRegister frb, 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit rc = LeaveRC); 1083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fsel(const DoubleRegister frt, const DoubleRegister fra, 1084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frc, const DoubleRegister frb, 1085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fneg(const DoubleRegister frt, const DoubleRegister frb, 1087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mtfsb0(FPSCRBit bit, RCBit rc = LeaveRC); 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mtfsb1(FPSCRBit bit, RCBit rc = LeaveRC); 1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtfsfi(int bf, int immediate, RCBit rc = LeaveRC); 1091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mffs(const DoubleRegister frt, RCBit rc = LeaveRC); 1092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mtfsf(const DoubleRegister frb, bool L = 1, int FLM = 0, bool W = 0, 1093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fsqrt(const DoubleRegister frt, const DoubleRegister frb, 1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fabs(const DoubleRegister frt, const DoubleRegister frb, 1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fmadd(const DoubleRegister frt, const DoubleRegister fra, 1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frc, const DoubleRegister frb, 1100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void fmsub(const DoubleRegister frt, const DoubleRegister fra, 1102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const DoubleRegister frc, const DoubleRegister frb, 1103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit rc = LeaveRC); 1104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 110562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Support for VSX instructions 110662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 110762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void xsadddp(const DoubleRegister frt, const DoubleRegister fra, 110862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const DoubleRegister frb); 110962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void xssubdp(const DoubleRegister frt, const DoubleRegister fra, 111062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const DoubleRegister frb); 111162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void xsdivdp(const DoubleRegister frt, const DoubleRegister fra, 111262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const DoubleRegister frb); 111362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void xsmuldp(const DoubleRegister frt, const DoubleRegister fra, 111462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const DoubleRegister frc); 111562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Pseudo instructions 1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Different nop operations are used by the code generator to detect certain 1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // states of the generated code. 1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum NopMarkerTypes { 1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NON_MARKING_NOP = 0, 1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GROUP_ENDING_NOP, 1123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEBUG_BREAK_NOP, 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // IC markers. 1125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PROPERTY_ACCESS_INLINED, 1126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PROPERTY_ACCESS_INLINED_CONTEXT, 1127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 1128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Helper values. 1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LAST_CODE_MARKER, 1130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED 1131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 1132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void nop(int type = 0); // 0 is the default non-marking type. 1134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void push(Register src) { 1136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stdu(src, MemOperand(sp, -kPointerSize)); 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 1139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier stwu(src, MemOperand(sp, -kPointerSize)); 1140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pop(Register dst) { 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ld(dst, MemOperand(sp)); 1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier lwz(dst, MemOperand(sp)); 1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier addi(sp, sp, Operand(kPointerSize)); 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pop() { addi(sp, sp, Operand(kPointerSize)); } 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Jump unconditionally to given label. 1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void jmp(Label* L) { b(L); } 1156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check the code size generated from label to here. 1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int SizeOfCodeGeneratedSince(Label* label) { 1159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return pc_offset() - label->pos(); 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check the number of instructions generated from label to here. 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int InstructionsGeneratedSince(Label* label) { 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return SizeOfCodeGeneratedSince(label) / kInstrSize; 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Class for scoping postponing the trampoline pool generation. 1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class BlockTrampolinePoolScope { 1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) { 1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier assem_->StartBlockTrampolinePool(); 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); } 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Assembler* assem_; 1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Class for scoping disabling constant pool entry merging 1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class BlockConstantPoolEntrySharingScope { 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit BlockConstantPoolEntrySharingScope(Assembler* assem) 1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : assem_(assem) { 1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch assem_->StartBlockConstantPoolEntrySharing(); 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~BlockConstantPoolEntrySharingScope() { 1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch assem_->EndBlockConstantPoolEntrySharing(); 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler* assem_; 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope); 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Debugging 1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Mark address of a debug break slot. 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Record the AST id of the CallIC being compiled, so that it can be placed 1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // in the relocation information. 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetRecordedAstId(TypeFeedbackId ast_id) { 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Causes compiler to fail 1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // DCHECK(recorded_ast_id_.IsNone()); 1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier recorded_ast_id_ = ast_id; 1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeFeedbackId RecordedAstId() { 1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Causes compiler to fail 1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // DCHECK(!recorded_ast_id_.IsNone()); 1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return recorded_ast_id_; 1215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } 1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Record a comment relocation entry that can be used by a disassembler. 1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Use --code-comments to enable. 1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordComment(const char* msg); 1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 1225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position, 1226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int id); 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Writes a single byte or word of data in the code stream. Used 1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for inline tables, e.g., jump-tables. 1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void db(uint8_t data); 1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void dd(uint32_t data); 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data); 1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Read/patch instructions 1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instr_at_put(int pos, Instr instr) { 1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void instr_at_put(byte* pc, Instr instr) { 1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *reinterpret_cast<Instr*>(pc) = instr; 1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Condition GetCondition(Instr instr); 1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsLis(Instr instr); 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsLi(Instr instr); 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsAddic(Instr instr); 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsOri(Instr instr); 1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsBranch(Instr instr); 1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Register GetRA(Instr instr); 1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Register GetRB(Instr instr); 1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3, 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr instr4, Instr instr5); 1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else 1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool Is32BitLoadIntoR12(Instr instr1, Instr instr2); 1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsCmpRegister(Instr instr); 1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsCmpImmediate(Instr instr); 1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsRlwinm(Instr instr); 1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsAndi(Instr instr); 1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsRldicl(Instr instr); 1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsCrSet(Instr instr); 1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Register GetCmpImmediateRegister(Instr instr); 1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static int GetCmpImmediateRawImmediate(Instr instr); 1271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Postpone the generation of the trampoline pool for the specified number of 1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // instructions. 1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void BlockTrampolinePoolFor(int instructions); 1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CheckTrampolinePool(); 1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For mov. Return the number of actual instructions required to 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // load the operand into a register. This can be anywhere from 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // one (constant pool small section) to five instructions (full 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 64-bit sequence). 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The value returned is only valid as long as no entries are added to the 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // constant pool between this call and the actual instruction being emitted. 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int instructions_required_for_mov(Register dst, const Operand& src) const; 1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Decide between using the constant pool vs. a mov immediate sequence. 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool use_constant_pool_for_mov(Register dst, const Operand& src, 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool canOptimize) const; 1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The code currently calls CheckBuffer() too often. This has the side 1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // effect of randomly growing the buffer in the middle of multi-instruction 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // sequences. 1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This function allows outside callers to check and grow the buffer 1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EnsureSpaceFor(int space_needed); 1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int EmitConstantPool() { return constant_pool_builder_.Emit(this); } 1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool ConstantPoolAccessIsInOverflow() const { 1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) == 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::OVERFLOWED; 1303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* ConstantPoolPosition() { 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return constant_pool_builder_.EmittedPosition(); 1307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitRelocations(); 1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier protected: 1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Relocation for a type-recording IC has the AST id added to it. This 1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // member variable is a way to pass the information from the call site to 1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the relocation info. 1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeFeedbackId recorded_ast_id_; 1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int buffer_space() const { return reloc_info_writer.pos() - pc_; } 1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Decode instruction(s) at pos and return backchain to previous 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // label reference or kEndOfChain. 1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int target_at(int pos); 1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch instruction(s) at pos to target target_pos (e.g. branch) 1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void target_at_put(int pos, int target_pos, bool* is_branch = nullptr); 1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Record reloc info for current pc_ 1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode, 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t value) { 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool sharing_ok = RelocInfo::IsNone(rmode) || 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !(serializer_enabled() || rmode < RelocInfo::CELL || 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_constant_pool_entry_sharing_blocked()); 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok); 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access ConstantPoolAddEntry(double value) { 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return constant_pool_builder_.AddEntry(pc_offset(), value); 1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Block the emission of the trampoline pool before pc_offset. 1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void BlockTrampolinePoolBefore(int pc_offset) { 1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (no_trampoline_pool_before_ < pc_offset) 1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier no_trampoline_pool_before_ = pc_offset; 1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } 1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndBlockTrampolinePool() { 1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int count = --trampoline_pool_blocked_nesting_; 1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (count == 0) CheckTrampolinePoolQuick(); 1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_trampoline_pool_blocked() const { 1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return trampoline_pool_blocked_nesting_ > 0; 1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void StartBlockConstantPoolEntrySharing() { 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant_pool_entry_sharing_blocked_nesting_++; 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EndBlockConstantPoolEntrySharing() { 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant_pool_entry_sharing_blocked_nesting_--; 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_constant_pool_entry_sharing_blocked() const { 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return constant_pool_entry_sharing_blocked_nesting_ > 0; 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_exception() const { return internal_trampoline_exception_; } 1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_trampoline_emitted() const { return trampoline_emitted_; } 1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code generation 1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The relocation writer's position is at least kGap bytes below the end of 1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the generated instructions. This is so that multi-instruction sequences do 1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // not have to check for overflow. The same is true for writes of large 1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // relocation info entries. 1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kGap = 32; 1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Repeated checking whether the trampoline pool should be emitted is rather 1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // expensive. By default we only check again once a number of instructions 1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // has been generated. 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int next_trampoline_check_; // pc offset of next buffer check. 1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emission of the trampoline pool may be blocked in some code sequences. 1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int no_trampoline_pool_before_; // Block emission before this pc offset. 1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do not share constant pool entries. 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int constant_pool_entry_sharing_blocked_nesting_; 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Relocation info generation 1389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Each relocation is encoded as a variable size value 1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RelocInfoWriter reloc_info_writer; 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::vector<DeferredRelocInfo> relocations_; 1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The bound position, before this we cannot do instruction elimination. 1395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int last_bound_pos_; 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimizable cmpi information. 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int optimizable_cmpi_pos_; 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cmpi_cr_; 1399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ConstantPoolBuilder constant_pool_builder_; 1401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code emission 1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void CheckBuffer(); 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GrowBuffer(int needed = 0); 1405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit(Instr x); 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void TrackBranch(); 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void UntrackBranch(); 1408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void CheckTrampolinePoolQuick(); 1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Instruction generation 1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, 1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DoubleRegister frb, RCBit r); 1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void d_form(Instr instr, Register rt, Register ra, const intptr_t val, 1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool signed_disp); 1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); 1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, 1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r); 141862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void xx3_form(Instr instr, DoubleRegister t, DoubleRegister a, 141962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DoubleRegister b); 1420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void md_form(Instr instr, Register ra, Register rs, int shift, int maskbit, 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r); 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mds_form(Instr instr, Register ra, Register rs, Register rb, int maskbit, 1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RCBit r); 1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Labels 1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void print(Label* L); 1427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int max_reach_from(int pos); 1428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void bind_to(Label* L, int pos); 1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void next(Label* L); 1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class Trampoline { 1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Trampoline() { 1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_slot_ = 0; 1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier free_slot_count_ = 0; 1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Trampoline(int start, int slot_count) { 1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_slot_ = start; 1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier free_slot_count_ = slot_count; 1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int take_slot() { 1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int trampoline_slot = kInvalidSlotPos; 1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (free_slot_count_ <= 0) { 1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We have run out of space on trampolines. 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Make sure we fail in debug mode, so we become aware of each case 1446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // when this happens. 1447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(0); 1448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Internal exception will be caught. 1449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier trampoline_slot = next_slot_; 1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier free_slot_count_--; 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_slot_ += kTrampolineSlotsSize; 1453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return trampoline_slot; 1455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int next_slot_; 1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int free_slot_count_; 1460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 1461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t get_trampoline_entry(); 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int tracked_branch_count_; 1464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If trampoline is emitted, generated code is becoming large. As 1465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // this is already a slow case which can possibly break our code 1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // generation for the extreme case, we use this information to 1467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // trigger different mode of branch instruction generation, where we 1468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // no longer use a single branch instruction. 1469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool trampoline_emitted_; 1470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kTrampolineSlotsSize = kInstrSize; 1471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMaxCondBranchReach = (1 << (16 - 1)) - 1; 1472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMaxBlockTrampolineSectionSize = 64 * kInstrSize; 1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kInvalidSlotPos = -1; 1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Trampoline trampoline_; 1476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool internal_trampoline_exception_; 1477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class RegExpMacroAssemblerPPC; 1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class RelocInfo; 1480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class CodePatcher; 1481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class BlockTrampolinePoolScope; 1482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class EnsureSpace; 1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass EnsureSpace BASE_EMBEDDED { 1487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } 1489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_PPC_ASSEMBLER_PPC_H_ 1494