112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Copyright (c) 1994-2006 Sun Microsystems Inc.
212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// All Rights Reserved.
312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Redistribution and use in source and binary forms, with or without
512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// modification, are permitted provided that the following conditions are
612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// met:
712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// - Redistributions of source code must retain the above copyright notice,
912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// this list of conditions and the following disclaimer.
1012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
1112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// - Redistribution in binary form must reproduce the above copyright
1212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// notice, this list of conditions and the following disclaimer in the
1312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// documentation and/or other materials provided with the distribution.
1412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
1512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// - Neither the name of Sun Microsystems or the names of contributors may
1612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// be used to endorse or promote products derived from this software without
1712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// specific prior written permission.
1812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
1912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
2012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The original source code covered by the above license above has been
3212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// modified significantly by Google Inc.
3312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
3412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/v8.h"
3712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if V8_TARGET_ARCH_MIPS64
3912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/base/cpu.h"
4112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/mips64/assembler-mips64-inl.h"
4212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/serialize.h"
4312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace v8 {
4512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace internal {
4612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Get the CPU features enabled by the build. For cross compilation the
4912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
5012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// can be defined to enable FPU instructions when building the
5112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// snapshot.
5212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgstatic unsigned CpuFeaturesImpliedByCompiler() {
5312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  unsigned answer = 0;
5412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef CAN_USE_FPU_INSTRUCTIONS
5512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  answer |= 1u << FPU;
5612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif  // def CAN_USE_FPU_INSTRUCTIONS
5712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
5812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // If the compiler is allowed to use FPU then we can use FPU too in our code
5912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // generation even when generating snapshots.  This won't work for cross
6012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // compilation.
6112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
6212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  answer |= 1u << FPU;
6312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
6412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return answer;
6612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
6712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst char* DoubleRegister::AllocationIndexToString(int index) {
70e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
7112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  const char* const names[] = {
7212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f0",
7312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f2",
7412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f4",
7512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f6",
7612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f8",
7712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f10",
7812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f12",
7912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f14",
8012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f16",
8112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f18",
8212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f20",
8312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f22",
8412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f24",
8512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    "f26"
8612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  };
8712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return names[index];
8812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
8912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid CpuFeatures::ProbeImpl(bool cross_compile) {
9212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  supported_ |= CpuFeaturesImpliedByCompiler();
9312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Only use statically determined features for cross compile (snapshot).
9512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (cross_compile) return;
9612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // If the compiler is allowed to use fpu then we can use fpu too in our
9812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // code generation.
9912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifndef __mips__
10012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // For the simulator build, use FPU.
10112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  supported_ |= 1u << FPU;
10212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#else
10312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Probe for additional features at runtime.
10412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  base::CPU cpu;
10512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (cpu.has_fpu()) supported_ |= 1u << FPU;
10612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
10712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
10812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
10912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
11012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid CpuFeatures::PrintTarget() { }
11112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid CpuFeatures::PrintFeatures() { }
11212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
11312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
11412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint ToNumber(Register reg) {
115e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reg.is_valid());
11612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  const int kNumbers[] = {
11712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    0,    // zero_reg
11812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    1,    // at
11912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    2,    // v0
12012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    3,    // v1
12112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    4,    // a0
12212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    5,    // a1
12312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    6,    // a2
12412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    7,    // a3
12512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    8,    // a4
12612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    9,    // a5
12712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    10,   // a6
12812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    11,   // a7
12912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    12,   // t0
13012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    13,   // t1
13112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    14,   // t2
13212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    15,   // t3
13312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    16,   // s0
13412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    17,   // s1
13512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    18,   // s2
13612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    19,   // s3
13712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    20,   // s4
13812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    21,   // s5
13912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    22,   // s6
14012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    23,   // s7
14112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    24,   // t8
14212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    25,   // t9
14312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    26,   // k0
14412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    27,   // k1
14512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    28,   // gp
14612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    29,   // sp
14712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    30,   // fp
14812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    31,   // ra
14912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  };
15012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return kNumbers[reg.code()];
15112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
15212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
15312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
15412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgRegister ToRegister(int num) {
155e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num >= 0 && num < kNumRegisters);
15612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  const Register kRegisters[] = {
15712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    zero_reg,
15812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    at,
15912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    v0, v1,
16012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    a0, a1, a2, a3, a4, a5, a6, a7,
16112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    t0, t1, t2, t3,
16212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    s0, s1, s2, s3, s4, s5, s6, s7,
16312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    t8, t9,
16412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    k0, k1,
16512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    gp,
16612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    sp,
16712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    fp,
16812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    ra
16912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  };
17012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return kRegisters[num];
17112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
17212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
17312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
17412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// -----------------------------------------------------------------------------
17512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Implementation of RelocInfo.
17612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
17712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
17812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  1 << RelocInfo::INTERNAL_REFERENCE;
17912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool RelocInfo::IsCodedSpecially() {
18212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // The deserializer needs to know whether a pointer is specially coded.  Being
18312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // specially coded on MIPS means that it is a lui/ori instruction, and that is
18412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // always the case inside code objects.
18512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return true;
18612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
18712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool RelocInfo::IsInConstantPool() {
19012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return false;
19112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
19212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
19312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
19412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Patch the code at the current address with the supplied instructions.
19512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) {
19612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr* pc = reinterpret_cast<Instr*>(pc_);
19712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr* instr = reinterpret_cast<Instr*>(instructions);
19812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  for (int i = 0; i < instruction_count; i++) {
19912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    *(pc + i) = *(instr + i);
20012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
20112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
20212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Indicate that code has changed.
20312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
20412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
20512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
20612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
20712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Patch the code at the current PC with a call to the target address.
20812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Additional guard instructions can be added if required.
20912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
21012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Patch the code at the current address with a call to the target.
21112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  UNIMPLEMENTED_MIPS();
21212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
21312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
21412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
21512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// -----------------------------------------------------------------------------
21612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Implementation of Operand and MemOperand.
21712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// See assembler-mips-inl.h for inlined constructors.
21812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
21912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgOperand::Operand(Handle<Object> handle) {
22012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  AllowDeferredHandleDereference using_raw_address;
22112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rm_ = no_reg;
22212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Verify all Objects referred by code are NOT in new space.
22312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Object* obj = *handle;
22412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (obj->IsHeapObject()) {
225e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
22612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm64_ = reinterpret_cast<intptr_t>(handle.location());
22712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    rmode_ = RelocInfo::EMBEDDED_OBJECT;
22812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
22912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // No relocation needed.
23012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm64_ = reinterpret_cast<intptr_t>(obj);
23112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    rmode_ = RelocInfo::NONE64;
23212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
23312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
23412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgMemOperand::MemOperand(Register rm, int64_t offset) : Operand(rm) {
23712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  offset_ = offset;
23812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
23912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgMemOperand::MemOperand(Register rm, int64_t unit, int64_t multiplier,
24212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                       OffsetAddend offset_addend) : Operand(rm) {
24312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  offset_ = unit * multiplier + offset_addend;
24412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
24512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// -----------------------------------------------------------------------------
24812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Specific instructions, constants, and masks.
24912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
25012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgstatic const int kNegOffset = 0x00008000;
25112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
25212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// operations as post-increment of sp.
25312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kPopInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
25412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (kRegister_sp_Code << kRtShift)
25512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (kPointerSize & kImm16Mask);  // NOLINT
25612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
25712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kPushInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
25812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (kRegister_sp_Code << kRtShift)
25912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (-kPointerSize & kImm16Mask);  // NOLINT
26012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// sd(r, MemOperand(sp, 0))
26112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kPushRegPattern = SD | (kRegister_sp_Code << kRsShift)
26212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (0 & kImm16Mask);  // NOLINT
26312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//  ld(r, MemOperand(sp, 0))
26412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kPopRegPattern = LD | (kRegister_sp_Code << kRsShift)
26512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (0 & kImm16Mask);  // NOLINT
26612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
26712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
26812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (0 & kImm16Mask);  // NOLINT
26912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
27012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
27112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (0 & kImm16Mask);  // NOLINT
27212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
27312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
27412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (kNegOffset & kImm16Mask);  // NOLINT
27512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
27612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
27712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      |  (kNegOffset & kImm16Mask);  // NOLINT
27812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// A mask for the Rt register for push, pop, lw, sw instructions.
27912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kRtMask = kRtFieldMask;
28012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kLwSwInstrTypeMask = 0xffe00000;
28112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
28212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst Instr kLwSwOffsetMask = kImm16Mask;
28312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
28412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
28512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
28612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    : AssemblerBase(isolate, buffer, buffer_size),
28712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      recorded_ast_id_(TypeFeedbackId::None()),
28812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      positions_recorder_(this) {
28912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
29012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
29112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  last_trampoline_pool_end_ = 0;
29212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  no_trampoline_pool_before_ = 0;
29312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  trampoline_pool_blocked_nesting_ = 0;
29412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We leave space (16 * kTrampolineSlotsSize)
29512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // for BlockTrampolinePoolScope buffer.
29612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  next_buffer_check_ = FLAG_force_long_branches
29712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
29812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  internal_trampoline_exception_ = false;
29912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  last_bound_pos_ = 0;
30012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  trampoline_emitted_ = FLAG_force_long_branches;
30212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  unbound_labels_count_ = 0;
30312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  block_buffer_growth_ = false;
30412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  ClearRecordedAstId();
30612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
30712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GetCode(CodeDesc* desc) {
310e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
31112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Set up code descriptor.
31212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc->buffer = buffer_;
31312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc->buffer_size = buffer_size_;
31412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc->instr_size = pc_offset();
31512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
31612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc->origin = this;
31712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
31812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
31912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::Align(int m) {
32121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
32212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  while ((pc_offset() & (m - 1)) != 0) {
32312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    nop();
32412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
32512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
32612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::CodeTargetAlign() {
32912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // No advantage to aligning branch/call targets to more than
33012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // single instruction, that I am aware of.
33112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Align(4);
33212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
33312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
33412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
33512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgRegister Assembler::GetRtReg(Instr instr) {
33612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register rt;
33712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rt.code_ = (instr & kRtFieldMask) >> kRtShift;
33812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return rt;
33912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
34012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
34112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
34212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgRegister Assembler::GetRsReg(Instr instr) {
34312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register rs;
34412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rs.code_ = (instr & kRsFieldMask) >> kRsShift;
34512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return rs;
34612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
34712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
34812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
34912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgRegister Assembler::GetRdReg(Instr instr) {
35012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register rd;
35112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rd.code_ = (instr & kRdFieldMask) >> kRdShift;
35212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return rd;
35312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
35412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
35512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
35612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRt(Instr instr) {
35712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & kRtFieldMask) >> kRtShift;
35812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
35912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
36012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
36112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRtField(Instr instr) {
36212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kRtFieldMask;
36312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
36412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
36512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
36612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRs(Instr instr) {
36712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & kRsFieldMask) >> kRsShift;
36812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
36912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
37012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
37112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRsField(Instr instr) {
37212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kRsFieldMask;
37312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
37412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
37512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
37612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRd(Instr instr) {
37712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return  (instr & kRdFieldMask) >> kRdShift;
37812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
37912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
38012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
38112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetRdField(Instr instr) {
38212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return  instr & kRdFieldMask;
38312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
38412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
38512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
38612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetSa(Instr instr) {
38712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & kSaFieldMask) >> kSaShift;
38812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
38912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
39012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
39112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetSaField(Instr instr) {
39212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kSaFieldMask;
39312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
39412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
39512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
39612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetOpcodeField(Instr instr) {
39712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kOpcodeMask;
39812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
39912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
40012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
40112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetFunction(Instr instr) {
40212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & kFunctionFieldMask) >> kFunctionShift;
40312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
40412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
40512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
40612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetFunctionField(Instr instr) {
40712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kFunctionFieldMask;
40812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
40912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
41012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
41112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetImmediate16(Instr instr) {
41212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & kImm16Mask;
41312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
41412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
41512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
41612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint32_t Assembler::GetLabelConst(Instr instr) {
41712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return instr & ~kImm16Mask;
41812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
41912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
42012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
42112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsPop(Instr instr) {
42212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & ~kRtMask) == kPopRegPattern;
42312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
42412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
42512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
42612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsPush(Instr instr) {
42712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (instr & ~kRtMask) == kPushRegPattern;
42812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
42912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
43012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
43112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsSwRegFpOffset(Instr instr) {
43212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
43312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
43412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
43512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
43612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsLwRegFpOffset(Instr instr) {
43712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
43812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
43912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
44012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
44112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsSwRegFpNegOffset(Instr instr) {
44212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
44312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          kSwRegFpNegOffsetPattern);
44412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
44512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
44612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
44712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsLwRegFpNegOffset(Instr instr) {
44812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
44912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          kLwRegFpNegOffsetPattern);
45012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
45112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
45212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
45312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Labels refer to positions in the (to be) generated code.
45412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// There are bound, linked, and unused labels.
45512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
45612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Bound labels refer to known positions in the already
45712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// generated code. pos() is the position the label refers to.
45812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
45912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Linked labels refer to unknown positions in the code
46012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// to be generated; pos() is the position of the last
46112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// instruction using the label.
46212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
46312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The link chain is terminated by a value in the instruction of -1,
46412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// which is an otherwise illegal value (branch -1 is inf loop).
46512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The instruction 16-bit offset field addresses 32-bit words, but in
46612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// code is conv to an 18-bit value addressing bytes, hence the -4 value.
46712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
46812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst int kEndOfChain = -4;
46912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Determines the end of the Jump chain (a subset of the label link chain).
47012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst int kEndOfJumpChain = 0;
47112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
47212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
47312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsBranch(Instr instr) {
47412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode   = GetOpcodeField(instr);
47512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rt_field = GetRtField(instr);
47612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rs_field = GetRsField(instr);
47712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Checks if the instruction is a branch.
47812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return opcode == BEQ ||
47912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BNE ||
48012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BLEZ ||
48112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BGTZ ||
48212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BEQL ||
48312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BNEL ||
48412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BLEZL ||
48512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode == BGTZL ||
48612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
48712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                            rt_field == BLTZAL || rt_field == BGEZAL)) ||
488dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
489dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      (opcode == COP1 && rs_field == BC1EQZ) ||
490dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      (opcode == COP1 && rs_field == BC1NEZ);
49112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
49212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
49312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
49412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsEmittedConstant(Instr instr) {
49512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t label_constant = GetLabelConst(instr);
49612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return label_constant == 0;  // Emitted label const in reg-exp engine.
49712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
49812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
49912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
50012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsBeq(Instr instr) {
50112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == BEQ;
50212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
50312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
50412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
50512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsBne(Instr instr) {
50612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == BNE;
50712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
50812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
50912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
51012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsJump(Instr instr) {
51112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode   = GetOpcodeField(instr);
51212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rt_field = GetRtField(instr);
51312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rd_field = GetRdField(instr);
51412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t function_field = GetFunctionField(instr);
51512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Checks if the instruction is a jump.
51612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return opcode == J || opcode == JAL ||
51712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      (opcode == SPECIAL && rt_field == 0 &&
51812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
51912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
52012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
52112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
52212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsJ(Instr instr) {
52312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode = GetOpcodeField(instr);
52412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Checks if the instruction is a jump.
52512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return opcode == J;
52612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
52712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
52812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
52912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsJal(Instr instr) {
53012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == JAL;
53112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
53212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
53312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
53412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsJr(Instr instr) {
53512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
53612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
53712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
53812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
53912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsJalr(Instr instr) {
54012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR;
54112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
54212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
54312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
54412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsLui(Instr instr) {
54512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode = GetOpcodeField(instr);
54612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Checks if the instruction is a load upper immediate.
54712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return opcode == LUI;
54812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
54912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
55012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
55112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsOri(Instr instr) {
55212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode = GetOpcodeField(instr);
55312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Checks if the instruction is a load upper immediate.
55412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return opcode == ORI;
55512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
55612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
55712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
55812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsNop(Instr instr, unsigned int type) {
55912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // See Assembler::nop(type).
560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(type < 32);
56112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t opcode = GetOpcodeField(instr);
56212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t function = GetFunctionField(instr);
56312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rt = GetRt(instr);
56412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rd = GetRd(instr);
56512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t sa = GetSa(instr);
56612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
56712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Traditional mips nop == sll(zero_reg, zero_reg, 0)
56812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // When marking non-zero type, use sll(zero_reg, at, type)
56912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // to avoid use of mips ssnop and ehb special encodings
57012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // of the sll instruction.
57112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
57212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register nop_rt_reg = (type == 0) ? zero_reg : at;
57312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool ret = (opcode == SPECIAL && function == SLL &&
57412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org              rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
57512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org              rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
57612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org              sa == type);
57712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
57812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ret;
57912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
58012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
58112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
58212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint32_t Assembler::GetBranchOffset(Instr instr) {
583e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsBranch(instr));
58412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
58512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
58612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
58712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
58812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsLw(Instr instr) {
58912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kOpcodeMask) == LW);
59012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
59112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
59212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
59312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint16_t Assembler::GetLwOffset(Instr instr) {
594e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsLw(instr));
59512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kImm16Mask));
59612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
59712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
59812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
59912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgInstr Assembler::SetLwOffset(Instr instr, int16_t offset) {
600e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsLw(instr));
60112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
60212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We actually create a new lw instruction based on the original one.
60312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
60412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (offset & kImm16Mask);
60512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
60612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return temp_instr;
60712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
60812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
60912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
61012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsSw(Instr instr) {
61112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kOpcodeMask) == SW);
61212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
61312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
61412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
61512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgInstr Assembler::SetSwOffset(Instr instr, int16_t offset) {
616e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsSw(instr));
61712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
61812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
61912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
62012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
62112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsAddImmediate(Instr instr) {
62212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & kOpcodeMask) == ADDIU || (instr & kOpcodeMask) == DADDIU);
62312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
62412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
62512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
62612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgInstr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
627e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsAddImmediate(instr));
62812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
62912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
63012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
63112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
63212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::IsAndImmediate(Instr instr) {
63312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return GetOpcodeField(instr) == ANDI;
63412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
63512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
63612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
63712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint64_t Assembler::target_at(int64_t pos) {
63812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = instr_at(pos);
63912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if ((instr & ~kImm16Mask) == 0) {
64012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Emitted label constant, not part of a branch.
64112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (instr == 0) {
64212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org       return kEndOfChain;
64312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org     } else {
64412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org       int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
64512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org       return (imm18 + pos);
64612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org     }
64712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
64812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Check we have a branch or jump instruction.
649e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
65012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
65112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // the compiler uses arithmetic shifts for signed integers.
65212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (IsBranch(instr)) {
65312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
65412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (imm18 == kEndOfChain) {
65512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // EndOfChain sentinel is returned directly, not relative to pc or pos.
65612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return kEndOfChain;
65712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
65812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return pos + kBranchPCOffset + imm18;
65912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
66012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else if (IsLui(instr)) {
66112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
66212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
66312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
664e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori));
665e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori2));
66612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
66712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // TODO(plind) create named constants for shift values.
66812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int64_t imm = static_cast<int64_t>(instr_lui & kImm16Mask) << 48;
66912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm |= static_cast<int64_t>(instr_ori & kImm16Mask) << 32;
67012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm |= static_cast<int64_t>(instr_ori2 & kImm16Mask) << 16;
67112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Sign extend address;
67212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm >>= 16;
67312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
67412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (imm == kEndOfJumpChain) {
67512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // EndOfChain sentinel is returned directly, not relative to pc or pos.
67612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return kEndOfChain;
67712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
67812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
67912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int64_t delta = instr_address - imm;
680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(pos > delta);
68112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return pos - delta;
68212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
68312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
68412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
68512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (imm28 == kEndOfJumpChain) {
68612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // EndOfChain sentinel is returned directly, not relative to pc or pos.
68712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return kEndOfChain;
68812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
68912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
69012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      instr_address &= kImm28Mask;
69112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int64_t delta = instr_address - imm28;
692e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(pos > delta);
69312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return pos - delta;
69412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
69512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
69612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
69712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
69812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
69912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::target_at_put(int64_t pos, int64_t target_pos) {
70012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = instr_at(pos);
70112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if ((instr & ~kImm16Mask) == 0) {
702e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target_pos == kEndOfChain || target_pos >= 0);
70312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Emitted label constant, not part of a branch.
70412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Make label relative to Code* of generated Code object.
70512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
70612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return;
70712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
70812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
709e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
71012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (IsBranch(instr)) {
71112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t imm18 = target_pos - (pos + kBranchPCOffset);
712e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm18 & 3) == 0);
71312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
71412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr &= ~kImm16Mask;
71512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t imm16 = imm18 >> 2;
716e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_int16(imm16));
71712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
71812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos, instr | (imm16 & kImm16Mask));
71912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else if (IsLui(instr)) {
72012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
72112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
72212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
723e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori));
724e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori2));
72512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
72612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
727e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm & 3) == 0);
72812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
72912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_lui &= ~kImm16Mask;
73012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_ori &= ~kImm16Mask;
73112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_ori2 &= ~kImm16Mask;
73212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
73312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos + 0 * Assembler::kInstrSize,
73412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_lui | ((imm >> 32) & kImm16Mask));
73512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos + 1 * Assembler::kInstrSize,
73612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_ori | ((imm >> 16) & kImm16Mask));
73712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos + 3 * Assembler::kInstrSize,
73812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_ori2 | (imm & kImm16Mask));
73912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
74012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint64_t imm28 = reinterpret_cast<uint64_t>(buffer_) + target_pos;
74112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm28 &= kImm28Mask;
742e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm28 & 3) == 0);
74312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
74412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr &= ~kImm26Mask;
74512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t imm26 = imm28 >> 2;
746e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_uint26(imm26));
74712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
74812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pos, instr | (imm26 & kImm26Mask));
74912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
75012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
75112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
75212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
75312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::print(Label* L) {
75412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_unused()) {
75512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    PrintF("unused label\n");
75612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else if (L->is_bound()) {
75712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    PrintF("bound label to %d\n", L->pos());
75812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else if (L->is_linked()) {
75912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Label l = *L;
76012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    PrintF("unbound label");
76112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    while (l.is_linked()) {
76212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      PrintF("@ %d ", l.pos());
76312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      Instr instr = instr_at(l.pos());
76412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if ((instr & ~kImm16Mask) == 0) {
76512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        PrintF("value\n");
76612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      } else {
76712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        PrintF("%d\n", instr);
76812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
76912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      next(&l);
77012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
77112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
77212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
77312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
77412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
77512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
77612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
77712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bind_to(Label* L, int pos) {
778e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
77912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int32_t trampoline_pos = kInvalidSlotPos;
78012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_linked() && !trampoline_emitted_) {
78112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    unbound_labels_count_--;
78212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    next_buffer_check_ += kTrampolineSlotsSize;
78312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
78412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
78512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  while (L->is_linked()) {
78612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t fixup_pos = L->pos();
78712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int32_t dist = pos - fixup_pos;
78812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    next(L);  // Call next before overwriting link with target at fixup_pos.
78912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr = instr_at(fixup_pos);
79012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (IsBranch(instr)) {
79112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if (dist > kMaxBranchOffset) {
79212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        if (trampoline_pos == kInvalidSlotPos) {
79312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          trampoline_pos = get_trampoline_entry(fixup_pos);
79412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          CHECK(trampoline_pos != kInvalidSlotPos);
79512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        }
796e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
79712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        target_at_put(fixup_pos, trampoline_pos);
79812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        fixup_pos = trampoline_pos;
79912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        dist = pos - fixup_pos;
80012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
80112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_at_put(fixup_pos, pos);
80212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
803e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
80412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_at_put(fixup_pos, pos);
80512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
80612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
80712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  L->bind_to(pos);
80812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
80912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Keep track of the last bound label so we don't eliminate any instructions
81012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // before a bound label.
81112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (pos > last_bound_pos_)
81212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    last_bound_pos_ = pos;
81312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
81412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
81512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
81612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bind(Label* L) {
817e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!L->is_bound());  // Label can only be bound once.
81812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bind_to(L, pc_offset());
81912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
82012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
82112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
82212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::next(Label* L) {
823e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(L->is_linked());
82412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int link = target_at(L->pos());
82512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (link == kEndOfChain) {
82612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    L->Unuse();
82712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
828e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(link >= 0);
82912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    L->link_to(link);
83012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
83112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
83212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
83312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
83412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::is_near(Label* L) {
83512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_bound()) {
83612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize);
83712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
83812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return false;
83912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
84012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
84112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
84212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// We have to use a temporary register for things that can be relocated even
84312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
84412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// space.  There is no guarantee that the relocated location can be similarly
84512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// encoded.
84612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Assembler::MustUseReg(RelocInfo::Mode rmode) {
84712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return !RelocInfo::IsNone(rmode);
84812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
84912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
85012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
85112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rs,
85212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rt,
85312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rd,
85412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 uint16_t sa,
85512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
85712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
85812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (rd.code() << kRdShift) | (sa << kSaShift) | func;
85912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
86012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
86112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
86212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
86312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
86412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rs,
86512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rt,
86612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 uint16_t msb,
86712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 uint16_t lsb,
86812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
869e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
87012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
87112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (msb << kRdShift) | (lsb << kSaShift) | func;
87212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
87312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
87412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
87512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
87612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
87712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField fmt,
87812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister ft,
87912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fs,
88012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fd,
88112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
882e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
88312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
88412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (fd.code() << kFdShift) | func;
88512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
88612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
88712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
88812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
88912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
89012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fr,
89112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister ft,
89212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fs,
89312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fd,
89412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
89612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
89712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
89812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
89912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
90012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
90112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
90212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
90312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField fmt,
90412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rt,
90512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fs,
90612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPURegister fd,
90712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
908e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
90912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | fmt | (rt.code() << kRtShift)
91012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
91112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
91212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
91312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
91412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
91512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrRegister(Opcode opcode,
91612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField fmt,
91712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 Register rt,
91812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 FPUControlRegister fs,
91912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                 SecondaryField func) {
920e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fs.is_valid() && rt.is_valid());
92112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr =
92212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
92312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
92412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
92512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
92612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
92712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Instructions with immediate value.
92812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Registers are in the order of the instruction encoding, from left to right.
92912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode,
93012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  Register rs,
93112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  Register rt,
93212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  int32_t j) {
933e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
93412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
93512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (j & kImm16Mask);
93612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
93712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
93812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
93912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
94012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode,
94112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  Register rs,
94212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  SecondaryField SF,
94312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  int32_t j) {
944e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
94512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
94612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
94712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
94812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
94912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
95012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrImmediate(Opcode opcode,
95112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  Register rs,
95212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  FPURegister ft,
95312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                  int32_t j) {
954e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
95512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
95612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (j & kImm16Mask);
95712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
95812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
95912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
96012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
96112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GenInstrJump(Opcode opcode,
96212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                             uint32_t address) {
96312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
964e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint26(address));
96512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = opcode | address;
96612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
96712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
96812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
96912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
97012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
97112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Returns the next free trampoline entry.
97212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint32_t Assembler::get_trampoline_entry(int32_t pos) {
97312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int32_t trampoline_entry = kInvalidSlotPos;
97412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (!internal_trampoline_exception_) {
97512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (trampoline_.start() > pos) {
97612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org     trampoline_entry = trampoline_.take_slot();
97712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
97812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
97912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (kInvalidSlotPos == trampoline_entry) {
98012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      internal_trampoline_exception_ = true;
98112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
98212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
98312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return trampoline_entry;
98412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
98512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
98612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
98712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orguint64_t Assembler::jump_address(Label* L) {
98812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int64_t target_pos;
98912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_bound()) {
99012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    target_pos = L->pos();
99112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
99212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (L->is_linked()) {
99312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_pos = L->pos();  // L's link.
99412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      L->link_to(pc_offset());
99512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
99612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      L->link_to(pc_offset());
99712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return kEndOfJumpChain;
99812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
99912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
100012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
100112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
1002e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((imm & 3) == 0);
100312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
100412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return imm;
100512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
100612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
100712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
100812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
100912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int32_t target_pos;
101012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_bound()) {
101112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    target_pos = L->pos();
101212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
101312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (L->is_linked()) {
101412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_pos = L->pos();
101512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      L->link_to(pc_offset());
101612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
101712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      L->link_to(pc_offset());
101812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if (!trampoline_emitted_) {
101912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        unbound_labels_count_++;
102012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        next_buffer_check_ -= kTrampolineSlotsSize;
102112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
102212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return kEndOfChain;
102312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
102412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
102512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
102612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1027e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset & 3) == 0);
1028e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int16(offset >> 2));
102912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
103012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return offset;
103112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
103212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
103312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1034dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgint32_t Assembler::branch_offset_compact(Label* L,
1035dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    bool jump_elimination_allowed) {
1036dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t target_pos;
1037dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (L->is_bound()) {
1038dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    target_pos = L->pos();
1039dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
1040dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    if (L->is_linked()) {
1041dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      target_pos = L->pos();
1042dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1043dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    } else {
1044dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1045dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      if (!trampoline_emitted_) {
1046dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        unbound_labels_count_++;
1047dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        next_buffer_check_ -= kTrampolineSlotsSize;
1048dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      }
1049dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      return kEndOfChain;
1050dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    }
1051dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  }
1052dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1053dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t offset = target_pos - pc_offset();
1054e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset & 3) == 0);
1055e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int16(offset >> 2));
1056dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1057dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  return offset;
1058dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1059dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1060dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1061dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgint32_t Assembler::branch_offset21(Label* L, bool jump_elimination_allowed) {
1062dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t target_pos;
1063dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (L->is_bound()) {
1064dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    target_pos = L->pos();
1065dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
1066dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    if (L->is_linked()) {
1067dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      target_pos = L->pos();
1068dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1069dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    } else {
1070dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1071dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      if (!trampoline_emitted_) {
1072dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        unbound_labels_count_++;
1073dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        next_buffer_check_ -= kTrampolineSlotsSize;
1074dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      }
1075dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      return kEndOfChain;
1076dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    }
1077dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  }
1078dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1079dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1080e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset & 3) == 0);
1081e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(((offset >> 2) & 0xFFE00000) == 0);  // Offset is 21bit width.
1082dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1083dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  return offset;
1084dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1085dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1086dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1087dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgint32_t Assembler::branch_offset21_compact(Label* L,
1088dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    bool jump_elimination_allowed) {
1089dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t target_pos;
1090dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (L->is_bound()) {
1091dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    target_pos = L->pos();
1092dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
1093dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    if (L->is_linked()) {
1094dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      target_pos = L->pos();
1095dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1096dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    } else {
1097dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      L->link_to(pc_offset());
1098dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      if (!trampoline_emitted_) {
1099dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        unbound_labels_count_++;
1100dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org        next_buffer_check_ -= kTrampolineSlotsSize;
1101dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      }
1102dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      return kEndOfChain;
1103dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    }
1104dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  }
1105dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1106dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  int32_t offset = target_pos - pc_offset();
1107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((offset & 3) == 0);
1108e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(((offset >> 2) & 0xFFE00000) == 0);  // Offset is 21bit width.
1109dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1110dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  return offset;
1111dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1112dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1113dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
111412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::label_at_put(Label* L, int at_offset) {
111512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int target_pos;
111612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (L->is_bound()) {
111712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    target_pos = L->pos();
111812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
111912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
112012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (L->is_linked()) {
112112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_pos = L->pos();  // L's link.
112212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int32_t imm18 = target_pos - at_offset;
1123e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK((imm18 & 3) == 0);
112412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int32_t imm16 = imm18 >> 2;
1125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_int16(imm16));
112612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      instr_at_put(at_offset, (imm16 & kImm16Mask));
112712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
112812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      target_pos = kEndOfChain;
112912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      instr_at_put(at_offset, 0);
113012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if (!trampoline_emitted_) {
113112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        unbound_labels_count_++;
113212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        next_buffer_check_ -= kTrampolineSlotsSize;
113312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
113412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
113512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    L->link_to(at_offset);
113612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
113712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
113812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
113912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
114012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//------- Branch and jump instructions --------
114112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
114212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::b(int16_t offset) {
114312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  beq(zero_reg, zero_reg, offset);
114412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
114512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
114612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
114712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bal(int16_t offset) {
114812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
114912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bgezal(zero_reg, offset);
115012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
115112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
115212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
115312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::beq(Register rs, Register rt, int16_t offset) {
115412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
115512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(BEQ, rs, rt, offset);
115612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
115712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
115812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
115912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
116012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bgez(Register rs, int16_t offset) {
116112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
116212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(REGIMM, rs, BGEZ, offset);
116312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
116412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
116512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
116612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1167dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgezc(Register rt, int16_t offset) {
1168e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1169e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1170dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZL, rt, rt, offset);
1171dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1172dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1173dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1174dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
1175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1176e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1177e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1178e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() != rt.code());
1179dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZ, rs, rt, offset);
1180dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1181dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1182dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1183dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgec(Register rs, Register rt, int16_t offset) {
1184e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1185e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1187e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() != rt.code());
1188dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZL, rs, rt, offset);
1189dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1190dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1191dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
119212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bgezal(Register rs, int16_t offset) {
1193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
119412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
119512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
119612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
119712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
119812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
119912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
120012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
120112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bgtz(Register rs, int16_t offset) {
120212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
120312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(BGTZ, rs, zero_reg, offset);
120412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
120512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
120612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
120712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1208dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgtzc(Register rt, int16_t offset) {
1209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1211dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZL, zero_reg, rt, offset);
1212dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1213dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1214dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
121512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::blez(Register rs, int16_t offset) {
121612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
121712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(BLEZ, rs, zero_reg, offset);
121812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
121912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
122012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
122112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1222dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::blezc(Register rt, int16_t offset) {
1223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1224e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1225dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZL, zero_reg, rt, offset);
1226dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1227dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1228dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1229dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bltzc(Register rt, int16_t offset) {
1230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1232dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZL, rt, rt, offset);
1233dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1234dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1235dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1236dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bltuc(Register rs, Register rt, int16_t offset) {
1237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1238e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1239e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1240e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() != rt.code());
1241dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZ, rs, rt, offset);
1242dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1243dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1244dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1245dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bltc(Register rs, Register rt, int16_t offset) {
1246e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1247e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1248e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1249e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() != rt.code());
1250dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZL, rs, rt, offset);
1251dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1252dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1253dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
125412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bltz(Register rs, int16_t offset) {
125512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
125612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(REGIMM, rs, BLTZ, offset);
125712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
125812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
125912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
126012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
126112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bltzal(Register rs, int16_t offset) {
1262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
126312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
126412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
126512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
126612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
126712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
126812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
126912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
127012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bne(Register rs, Register rt, int16_t offset) {
127112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
127212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(BNE, rs, rt, offset);
127312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
127412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
127512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
127612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1277dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bovc(Register rs, Register rt, int16_t offset) {
1278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() >= rt.code());
1281dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(ADDI, rs, rt, offset);
1282dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1283dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1284dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1285dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bnvc(Register rs, Register rt, int16_t offset) {
1286e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1287e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() >= rt.code());
1289dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(DADDI, rs, rt, offset);
1290dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1291dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1292dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1293dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::blezalc(Register rt, int16_t offset) {
1294e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1296dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZ, zero_reg, rt, offset);
1297dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1298dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1299dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1300dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgezalc(Register rt, int16_t offset) {
1301e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1303dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BLEZ, rt, rt, offset);
1304dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1305dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1306dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1307dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgezall(Register rs, int16_t offset) {
1308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1310dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
1311dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1312dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1313dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1314dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bltzalc(Register rt, int16_t offset) {
1315e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1316e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1317dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZ, rt, rt, offset);
1318dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1319dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1320dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1321dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bgtzalc(Register rt, int16_t offset) {
1322e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1323e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1324dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(BGTZ, zero_reg, rt, offset);
1325dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1326dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1327dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1328dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::beqzalc(Register rt, int16_t offset) {
1329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1330e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1331dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(ADDI, zero_reg, rt, offset);
1332dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1333dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1334dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1335dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bnezalc(Register rt, int16_t offset) {
1336e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1337e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rt.is(zero_reg)));
1338dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(DADDI, zero_reg, rt, offset);
1339dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1340dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1341dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1342dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::beqc(Register rs, Register rt, int16_t offset) {
1343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() < rt.code());
1345dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(ADDI, rs, rt, offset);
1346dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1347dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1348dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1349dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::beqzc(Register rs, int32_t offset) {
1350e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1351e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1352dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = BEQZC | (rs.code() << kRsShift) | offset;
1353dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
1354dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1355dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1356dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1357dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bnec(Register rs, Register rt, int16_t offset) {
1358e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rs.code() < rt.code());
1360dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(DADDI, rs, rt, offset);
1361dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1362dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1363dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1364dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bnezc(Register rs, int32_t offset) {
1365e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1366e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!(rs.is(zero_reg)));
1367dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = BNEZC | (rs.code() << kRsShift) | offset;
1368dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
1369dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1370dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1371dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
137212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::j(int64_t target) {
137312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if DEBUG
137412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Get pc of delay slot.
137512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
137612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
137712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                  (kImm26Bits + kImmFieldShift)) == 0;
1378e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(in_range && ((target & 3) == 0));
137912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
138012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrJump(J, target >> 2);
138112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
138212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
138312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
138412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::jr(Register rs) {
1385dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (kArchVariant != kMips64r6) {
1386dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    BlockTrampolinePoolScope block_trampoline_pool(this);
1387dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    if (rs.is(ra)) {
1388dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      positions_recorder()->WriteRecordedPositions();
1389dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    }
1390dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
1391dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    BlockTrampolinePoolFor(1);  // For associated delay slot.
1392dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
1393dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    jalr(rs, zero_reg);
139412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
139512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
139612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
139712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
139812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::jal(int64_t target) {
139912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef DEBUG
140012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Get pc of delay slot.
140112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
140212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
140312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                  (kImm26Bits + kImmFieldShift)) == 0;
1404e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(in_range && ((target & 3) == 0));
140512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
140612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
140712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrJump(JAL, target >> 2);
140812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
140912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
141012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
141112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::jalr(Register rs, Register rd) {
141212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolScope block_trampoline_pool(this);
141312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
141412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
141512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(1);  // For associated delay slot.
141612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
141712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
141812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
141912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::j_or_jr(int64_t target, Register rs) {
142012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Get pc of delay slot.
142112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
142212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
142312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                  (kImm26Bits + kImmFieldShift)) == 0;
142412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (in_range) {
142512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      j(target);
142612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
142712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      jr(t9);
142812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
142912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
143012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
143112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
143212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::jal_or_jalr(int64_t target, Register rs) {
143312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Get pc of delay slot.
143412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
143512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
143612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                  (kImm26Bits+kImmFieldShift)) == 0;
143712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (in_range) {
143812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      jal(target);
143912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
144012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      jalr(t9);
144112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
144212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
144312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
144412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
144512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// -------Data-processing-instructions---------
144612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
144712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Arithmetic.
144812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
144912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::addu(Register rd, Register rs, Register rt) {
145012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
145112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
145212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
145312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
145412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::addiu(Register rd, Register rs, int32_t j) {
145512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(ADDIU, rs, rd, j);
145612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
145712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
145812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
145912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::subu(Register rd, Register rs, Register rt) {
146012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
146112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
146212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
146312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
146412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mul(Register rd, Register rs, Register rt) {
1465dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (kArchVariant == kMips64r6) {
1466dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
1467dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
1468dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
1469dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  }
1470dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1471dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1472dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1473dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::muh(Register rd, Register rs, Register rt) {
1474e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1475dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
1476dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1477dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1478dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1479dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::mulu(Register rd, Register rs, Register rt) {
1480e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1481dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
1482dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1483dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1484dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1485dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::muhu(Register rd, Register rs, Register rt) {
1486e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1487dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
1488dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1489dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1490dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1491dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmul(Register rd, Register rs, Register rt) {
1492e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1493dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH);
1494dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1495dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1496dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1497dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmuh(Register rd, Register rs, Register rt) {
1498e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1499dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH);
1500dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1501dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1502dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1503dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmulu(Register rd, Register rs, Register rt) {
1504e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1505dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH_U);
1506dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1507dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1508dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1509dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmuhu(Register rd, Register rs, Register rt) {
1510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1511dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH_U);
151212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
151312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
151412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
151512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mult(Register rs, Register rt) {
1516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant != kMips64r6);
151712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
151812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
151912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
152012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
152112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::multu(Register rs, Register rt) {
1522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant != kMips64r6);
152312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
152412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
152512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
152612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
152712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::daddiu(Register rd, Register rs, int32_t j) {
152812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(DADDIU, rs, rd, j);
152912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
153012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
153112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
153212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::div(Register rs, Register rt) {
153312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
153412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
153512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
153612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1537dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::div(Register rd, Register rs, Register rt) {
1538e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1539dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
1540dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1541dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1542dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1543dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::mod(Register rd, Register rs, Register rt) {
1544e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1545dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
1546dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1547dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1548dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
154912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::divu(Register rs, Register rt) {
155012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
155112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
155212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
155312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1554dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::divu(Register rd, Register rs, Register rt) {
1555e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1556dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
1557dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1558dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1559dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1560dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::modu(Register rd, Register rs, Register rt) {
1561e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1562dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
1563dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1564dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1565dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
156612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::daddu(Register rd, Register rs, Register rt) {
156712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DADDU);
156812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
156912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
157012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
157112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsubu(Register rd, Register rs, Register rt) {
157212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSUBU);
157312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
157412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
157512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
157612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dmult(Register rs, Register rt) {
157712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULT);
157812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
157912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
158012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
158112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dmultu(Register rs, Register rt) {
158212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULTU);
158312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
158412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
158512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
158612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ddiv(Register rs, Register rt) {
158712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIV);
158812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
158912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
159012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1591dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::ddiv(Register rd, Register rs, Register rt) {
1592e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1593dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD);
1594dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1595dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1596dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1597dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmod(Register rd, Register rs, Register rt) {
1598e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1599dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD);
1600dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1601dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1602dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
160312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ddivu(Register rs, Register rt) {
160412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIVU);
160512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
160612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
160712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1608dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::ddivu(Register rd, Register rs, Register rt) {
1609e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1610dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD_U);
1611dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1612dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1613dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1614dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dmodu(Register rd, Register rs, Register rt) {
1615e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
1616dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD_U);
1617dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1618dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1619dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
162012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Logical.
162112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
162212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::and_(Register rd, Register rs, Register rt) {
162312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
162412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
162512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
162612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
162712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::andi(Register rt, Register rs, int32_t j) {
1628e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
162912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(ANDI, rs, rt, j);
163012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
163112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
163212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
163312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::or_(Register rd, Register rs, Register rt) {
163412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
163512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
163612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
163712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
163812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ori(Register rt, Register rs, int32_t j) {
1639e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
164012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(ORI, rs, rt, j);
164112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
164212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
164312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
164412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::xor_(Register rd, Register rs, Register rt) {
164512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
164612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
164712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
164812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
164912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::xori(Register rt, Register rs, int32_t j) {
1650e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
165112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(XORI, rs, rt, j);
165212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
165312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
165412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
165512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::nor(Register rd, Register rs, Register rt) {
165612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
165712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
165812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
165912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
166012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Shifts.
166112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sll(Register rd,
166212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                    Register rt,
166312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                    uint16_t sa,
166412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                    bool coming_from_nop) {
166512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
166612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // generated using the sll instruction. They must be generated using
166712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo
166812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // instructions.
1669e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
167012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SLL);
167112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
167212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
167312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
167412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sllv(Register rd, Register rt, Register rs) {
167512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
167612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
167712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
167812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
167912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::srl(Register rd, Register rt, uint16_t sa) {
168012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRL);
168112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
168212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
168312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
168412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::srlv(Register rd, Register rt, Register rs) {
168512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
168612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
168712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
168812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
168912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sra(Register rd, Register rt, uint16_t sa) {
169012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRA);
169112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
169212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
169312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
169412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::srav(Register rd, Register rt, Register rs) {
169512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
169612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
169712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
169812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
169912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::rotr(Register rd, Register rt, uint16_t sa) {
170012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Should be called via MacroAssembler::Ror.
1701e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1702e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
170312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
170412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
170512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
170612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
170712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
170812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
170912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::rotrv(Register rd, Register rt, Register rs) {
171012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Should be called via MacroAssembler::Ror.
1711e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1712e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
171312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
171412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org     | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
171512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
171612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
171712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
171812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
171912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsll(Register rd, Register rt, uint16_t sa) {
172012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSLL);
172112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
172212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
172312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
172412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsllv(Register rd, Register rt, Register rs) {
172512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSLLV);
172612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
172712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
172812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
172912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsrl(Register rd, Register rt, uint16_t sa) {
173012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRL);
173112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
173212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
173312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
173412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsrlv(Register rd, Register rt, Register rs) {
173512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRLV);
173612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
173712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
173812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
173912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::drotr(Register rd, Register rt, uint16_t sa) {
1740e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
174112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
174212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (rd.code() << kRdShift) | (sa << kSaShift) | DSRL;
174312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
174412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
174512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
174612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
174712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::drotrv(Register rd, Register rt, Register rs) {
1748e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
174912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
175012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (rd.code() << kRdShift) | (1 << kSaShift) | DSRLV;
175112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
175212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
175312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
175412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
175512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsra(Register rd, Register rt, uint16_t sa) {
175612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRA);
175712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
175812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
175912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
176012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsrav(Register rd, Register rt, Register rs) {
176112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRAV);
176212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
176312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
176412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
176512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsll32(Register rd, Register rt, uint16_t sa) {
176612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSLL32);
176712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
176812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
176912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
177012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsrl32(Register rd, Register rt, uint16_t sa) {
177112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRL32);
177212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
177312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
177412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
177512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dsra32(Register rd, Register rt, uint16_t sa) {
177612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRA32);
177712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
177812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
177912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
178012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// ------------Memory-instructions-------------
178112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
178212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Helper for base-reg + offset, when offset is larger than int16.
178312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
1784e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!src.rm().is(at));
1785e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_int32(src.offset_));
178612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  daddiu(at, zero_reg, (src.offset_ >> kLuiShift) & kImm16Mask);
178712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  dsll(at, at, kLuiShift);
178812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
178912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  daddu(at, at, src.rm());  // Add base register.
179012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
179112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
179212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
179312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lb(Register rd, const MemOperand& rs) {
179412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
179512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
179612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
179712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
179812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LB, at, rd, 0);  // Equiv to lb(rd, MemOperand(at, 0));
179912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
180012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
180112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
180212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
180312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lbu(Register rd, const MemOperand& rs) {
180412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
180512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
180612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
180712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
180812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LBU, at, rd, 0);  // Equiv to lbu(rd, MemOperand(at, 0));
180912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
181012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
181112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
181212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
181312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lh(Register rd, const MemOperand& rs) {
181412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
181512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
181612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
181712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
181812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LH, at, rd, 0);  // Equiv to lh(rd, MemOperand(at, 0));
181912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
182012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
182112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
182212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
182312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lhu(Register rd, const MemOperand& rs) {
182412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
182512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
182612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
182712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
182812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LHU, at, rd, 0);  // Equiv to lhu(rd, MemOperand(at, 0));
182912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
183012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
183112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
183212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
183312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lw(Register rd, const MemOperand& rs) {
183412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
183512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
183612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
183712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
183812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LW, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
183912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
184012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
184112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
184212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
184312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lwu(Register rd, const MemOperand& rs) {
184412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
184512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
184612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
184712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
184812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LWU, at, rd, 0);  // Equiv to lwu(rd, MemOperand(at, 0));
184912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
185012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
185112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
185212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
185312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lwl(Register rd, const MemOperand& rs) {
185412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
185512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
185612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
185712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
185812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lwr(Register rd, const MemOperand& rs) {
185912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
186012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
186112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
186212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
186312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sb(Register rd, const MemOperand& rs) {
186412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
186512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
186612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to store.
186712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
186812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SB, at, rd, 0);  // Equiv to sb(rd, MemOperand(at, 0));
186912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
187012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
187112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
187212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
187312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sh(Register rd, const MemOperand& rs) {
187412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
187512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
187612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to store.
187712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
187812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SH, at, rd, 0);  // Equiv to sh(rd, MemOperand(at, 0));
187912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
188012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
188112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
188212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
188312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sw(Register rd, const MemOperand& rs) {
188412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
188512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
188612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to store.
188712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
188812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SW, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
188912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
189012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
189112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
189212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
189312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::swl(Register rd, const MemOperand& rs) {
189412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
189512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
189612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
189712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
189812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::swr(Register rd, const MemOperand& rs) {
189912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
190012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
190112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
190212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
190312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lui(Register rd, int32_t j) {
1904e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
190512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LUI, zero_reg, rd, j);
190612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
190712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
190812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1909dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::aui(Register rs, Register rt, int32_t j) {
1910dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  // This instruction uses same opcode as 'lui'. The difference in encoding is
1911dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  // 'lui' has zero reg. for rs field.
1912e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
1913dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(LUI, rs, rt, j);
1914dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1915dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1916dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1917dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::daui(Register rs, Register rt, int32_t j) {
1918e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
1919dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(DAUI, rs, rt, j);
1920dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1921dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1922dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1923dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dahi(Register rs, int32_t j) {
1924e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
1925dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(REGIMM, rs, DAHI, j);
1926dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1927dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1928dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1929dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::dati(Register rs, int32_t j) {
1930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint16(j));
1931dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrImmediate(REGIMM, rs, DATI, j);
1932dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
1933dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
1934dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
193512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ldl(Register rd, const MemOperand& rs) {
193612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LDL, rs.rm(), rd, rs.offset_);
193712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
193812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
193912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
194012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ldr(Register rd, const MemOperand& rs) {
194112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LDR, rs.rm(), rd, rs.offset_);
194212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
194312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
194412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
194512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sdl(Register rd, const MemOperand& rs) {
194612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SDL, rs.rm(), rd, rs.offset_);
194712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
194812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
194912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
195012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sdr(Register rd, const MemOperand& rs) {
195112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
195212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
195312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
195412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
195512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ld(Register rd, const MemOperand& rs) {
195612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
195712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
195812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to load.
195912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
196012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(LD, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
196112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
196212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
196312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
196412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
196512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sd(Register rd, const MemOperand& rs) {
196612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (is_int16(rs.offset_)) {
196712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
196812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {  // Offset > 16 bits, use multiple instructions to store.
196912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    LoadRegPlusOffsetToAt(rs);
197012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    GenInstrImmediate(SD, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
197112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
197212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
197312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
197412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
197512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// -------------Misc-instructions--------------
197612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
197712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Break / Trap instructions.
197812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::break_(uint32_t code, bool break_as_stop) {
1979e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((code & ~0xfffff) == 0);
198012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We need to invalidate breaks that could be stops as well because the
198112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // simulator expects a char pointer after the stop instruction.
198212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // See constants-mips.h for explanation.
1983e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((break_as_stop &&
198412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          code <= kMaxStopCode &&
198512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          code > kMaxWatchpointCode) ||
198612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org         (!break_as_stop &&
198712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          (code > kMaxStopCode ||
198812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org           code <= kMaxWatchpointCode)));
198912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr break_instr = SPECIAL | BREAK | (code << 6);
199012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(break_instr);
199112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
199212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
199312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
199412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::stop(const char* msg, uint32_t code) {
1995e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code > kMaxWatchpointCode);
1996e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code <= kMaxStopCode);
199712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if defined(V8_HOST_ARCH_MIPS) || defined(V8_HOST_ARCH_MIPS64)
199812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  break_(0x54321);
199912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#else  // V8_HOST_ARCH_MIPS
200012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolFor(3);
200112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // The Simulator will handle the stop instruction and get the message address.
200212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // On MIPS stop() is just a special kind of break_().
200312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  break_(code, true);
200412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(reinterpret_cast<uint64_t>(msg));
200512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
200612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
200712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
200812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
200912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::tge(Register rs, Register rt, uint16_t code) {
2010e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
201112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | TGE | rs.code() << kRsShift
201212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | rt.code() << kRtShift | code << 6;
201312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
201412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
201512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
201612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
201712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::tgeu(Register rs, Register rt, uint16_t code) {
2018e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
201912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
202012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | rt.code() << kRtShift | code << 6;
202112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
202212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
202312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
202412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
202512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::tlt(Register rs, Register rt, uint16_t code) {
2026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
202712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr =
202812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
202912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
203012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
203112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
203212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
203312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::tltu(Register rs, Register rt, uint16_t code) {
2034e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
203512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr =
203612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      SPECIAL | TLTU | rs.code() << kRsShift
203712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | rt.code() << kRtShift | code << 6;
203812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
203912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
204012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
204112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
204212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::teq(Register rs, Register rt, uint16_t code) {
2043e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
204412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr =
204512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
204612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
204712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
204812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
204912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
205012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::tne(Register rs, Register rt, uint16_t code) {
2051e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint10(code));
205212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr =
205312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
205412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
205512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
205612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
205712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
205812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Move from HI/LO register.
205912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
206012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mfhi(Register rd) {
206112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
206212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
206312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
206412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
206512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mflo(Register rd) {
206612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
206712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
206812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
206912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
207012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Set on less than instructions.
207112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::slt(Register rd, Register rs, Register rt) {
207212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
207312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
207412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
207512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
207612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sltu(Register rd, Register rs, Register rt) {
207712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
207812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
207912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
208012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
208112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::slti(Register rt, Register rs, int32_t j) {
208212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SLTI, rs, rt, j);
208312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
208412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
208512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
208612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sltiu(Register rt, Register rs, int32_t j) {
208712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SLTIU, rs, rt, j);
208812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
208912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
209012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
209112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Conditional move.
209212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::movz(Register rd, Register rs, Register rt) {
209312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
209412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
209512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
209612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
209712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::movn(Register rd, Register rs, Register rt) {
209812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
209912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
210012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
210112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
210212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::movt(Register rd, Register rs, uint16_t cc) {
210312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register rt;
210412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rt.code_ = (cc & 0x0007) << 2 | 1;
210512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
210612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
210712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
210812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
210912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::movf(Register rd, Register rs, uint16_t cc) {
211012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Register rt;
211112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rt.code_ = (cc & 0x0007) << 2 | 0;
211212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
211312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
211412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
211512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2116dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::sel(SecondaryField fmt, FPURegister fd,
2117dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister ft, FPURegister fs, uint8_t sel) {
2118e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == D);
2120e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == S);
2121dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2122dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2123dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      fs.code() << kFsShift | fd.code() << kFdShift | SEL;
2124dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2125dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2126dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2127dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2128dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// GPR.
2129dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::seleqz(Register rs, Register rt, Register rd) {
2130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2131dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
2132dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2133dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2134dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2135dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// FPR.
2136dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::seleqz(SecondaryField fmt, FPURegister fd,
2137dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister ft, FPURegister fs) {
2138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == D);
2140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == S);
2141dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2142dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2143dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      fs.code() << kFsShift | fd.code() << kFdShift | SELEQZ_C;
2144dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2145dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2146dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2147dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2148dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// GPR.
2149dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::selnez(Register rs, Register rt, Register rd) {
2150e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2151dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
2152dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2153dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2154dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2155dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// FPR.
2156dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::selnez(SecondaryField fmt, FPURegister fd,
2157dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister ft, FPURegister fs) {
2158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2159e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == D);
2160e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(fmt == S);
2161dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2162dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2163dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      fs.code() << kFsShift | fd.code() << kFdShift | SELNEZ_C;
2164dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2165dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2166dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2167dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
216812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Bit twiddling.
216912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::clz(Register rd, Register rs) {
2170dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (kArchVariant != kMips64r6) {
2171dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    // Clz instr requires same GPR number in 'rd' and 'rt' fields.
2172dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
2173dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  } else {
2174dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
2175dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  }
217612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
217712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
217812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
217912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
218012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Should be called via MacroAssembler::Ins.
218112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
2182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((kArchVariant == kMips64r2) || (kArchVariant == kMips64r6));
218312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
218412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
218512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
218612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
218712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
218812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Should be called via MacroAssembler::Ext.
218912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
2190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
219112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
219212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
219312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
219412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
219512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::pref(int32_t hint, const MemOperand& rs) {
2196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
219712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
219812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (rs.offset_);
219912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
220012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
220112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
220212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
220312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// --------Coprocessor-instructions----------------
220412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
220512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Load, store, move.
220612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::lwc1(FPURegister fd, const MemOperand& src) {
220712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
220812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
220912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
221012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
221112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ldc1(FPURegister fd, const MemOperand& src) {
221212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
221312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
221412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
221512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
221612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::swc1(FPURegister fd, const MemOperand& src) {
221712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
221812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
221912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
222012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
222112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sdc1(FPURegister fd, const MemOperand& src) {
222212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
222312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
222412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
222512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
222612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mtc1(Register rt, FPURegister fs) {
222712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, MTC1, rt, fs, f0);
222812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
222912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
223012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
223112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mthc1(Register rt, FPURegister fs) {
223212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, MTHC1, rt, fs, f0);
223312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
223412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
223512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
223612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dmtc1(Register rt, FPURegister fs) {
223712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, DMTC1, rt, fs, f0);
223812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
223912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
224012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
224112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mfc1(Register rt, FPURegister fs) {
224212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, MFC1, rt, fs, f0);
224312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
224412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
224512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
224612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mfhc1(Register rt, FPURegister fs) {
224712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, MFHC1, rt, fs, f0);
224812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
224912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
225012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
225112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dmfc1(Register rt, FPURegister fs) {
225212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, DMFC1, rt, fs, f0);
225312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
225412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
225512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
225612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ctc1(Register rt, FPUControlRegister fs) {
225712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, CTC1, rt, fs);
225812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
225912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
226012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
226112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cfc1(Register rt, FPUControlRegister fs) {
226212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, CFC1, rt, fs);
226312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
226412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
226512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
226612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
226712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t i;
226812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  memcpy(&i, &d, 8);
226912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
227012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *lo = i & 0xffffffff;
227112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *hi = i >> 32;
227212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
227312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
227412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
227512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Arithmetic.
227612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
227712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
227812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
227912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
228012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
228112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
228212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
228312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
228412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
228512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
228612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
228712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
228812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
228912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
229012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
229112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
229212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
229312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    FPURegister ft) {
229412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
229512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
229612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
229712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
229812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
229912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
230012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
230112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
230212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
230312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::abs_d(FPURegister fd, FPURegister fs) {
230412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
230512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
230612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
230712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
230812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::mov_d(FPURegister fd, FPURegister fs) {
230912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
231012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
231112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
231212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
231312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::neg_d(FPURegister fd, FPURegister fs) {
231412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
231512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
231612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
231712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
231812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
231912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
232012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
232112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
232212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
232312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Conversions.
232412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
232512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
232612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
232712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
232812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
232912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
233012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
233112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
233212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
233312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
233412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
233512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
233612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
233712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
233812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
233912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
234012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
234112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
234212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
234312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
234412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
234512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::round_w_s(FPURegister fd, FPURegister fs) {
234612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
234712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
234812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
234912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
235012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::round_w_d(FPURegister fd, FPURegister fs) {
235112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
235212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
235312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
235412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
235512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
235612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
235712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
235812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
235912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
236012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
236112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
236212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
236312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
236412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
236512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
236612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
236712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
236812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
236912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
237012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
237112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
237212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
237312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
237412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
237512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
2376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
237712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
237812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
237912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
238012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
238112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
2382e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
238312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
238412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
238512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
238612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
238712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
2388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
238912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
239012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
239112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
239212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
239312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
2394e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
239512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
239612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
239712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
239812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
239912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::round_l_s(FPURegister fd, FPURegister fs) {
240012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
240112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
240212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
240312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
240412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::round_l_d(FPURegister fd, FPURegister fs) {
240512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
240612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
240712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
240812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
240912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
241012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
241112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
241212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
241312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
241412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
241512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
241612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
241712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
241812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
241912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
242012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
242112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
242212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
242312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
242412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
242512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
242612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
242712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
242812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2429dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister ft,
2430dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister fs) {
2431e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2432e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt == D) || (fmt == S));
2433dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
2434dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2435dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2436dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2437dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister ft,
2438dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister fs) {
2439e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2440e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt == D) || (fmt == S));
2441dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
2442dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2443dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2444dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2445dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister ft,
2446dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister fs) {
2447e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt == D) || (fmt == S));
2449dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
2450dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2451dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2452dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2453dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister ft,
2454dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister fs) {
2455e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2456e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt == D) || (fmt == S));
2457dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
2458dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2459dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2460dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
246112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
246212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
246312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
246412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
246512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
246612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
2467e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
246812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
246912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
247012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
247112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
247212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
247312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
247412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
247512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
247612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
247712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
247812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
247912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
248012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
248112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
248212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
2483e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r2);
248412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
248512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
248612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
248712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
248812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
248912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
249012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
249112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
249212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2493dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// Conditions for >= MIPSr6.
2494dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::cmp(FPUCondition cond, SecondaryField fmt,
2495dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    FPURegister fd, FPURegister fs, FPURegister ft) {
2496e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2497e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt & ~(31 << kRsShift)) == 0);
2498dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | fmt | ft.code() << kFtShift |
2499dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
2500dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2501dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2502dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2503dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2504dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bc1eqz(int16_t offset, FPURegister ft) {
2505e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2506dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
2507dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2508dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2509dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2510dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2511dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Assembler::bc1nez(int16_t offset, FPURegister ft) {
2512e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant == kMips64r6);
2513dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
2514dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  emit(instr);
2515dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org}
2516dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2517dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org
2518dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// Conditions for < MIPSr6.
251912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::c(FPUCondition cond, SecondaryField fmt,
252012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    FPURegister fs, FPURegister ft, uint16_t cc) {
2521e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kArchVariant != kMips64r6);
2522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint3(cc));
2523e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((fmt & ~(31 << kRsShift)) == 0);
2524dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
252512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | cc << 8 | 3 << 4 | cond;
252612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
252712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
252812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
252912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
253012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::fcmp(FPURegister src1, const double src2,
253112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      FPUCondition cond) {
2532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(src2 == 0.0);
253312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  mtc1(zero_reg, f14);
253412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  cvt_d_w(f14, f14);
253512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  c(cond, D, src1, f14, 0);
253612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
253712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
253812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
253912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bc1f(int16_t offset, uint16_t cc) {
2540e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint3(cc));
254112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
254212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
254312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
254412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
254512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
254612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::bc1t(int16_t offset, uint16_t cc) {
2547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_uint3(cc));
254812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
254912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  emit(instr);
255012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
255112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
255212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
255312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Debugging.
255412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::RecordJSReturn() {
255512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
255612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CheckBuffer();
255712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  RecordRelocInfo(RelocInfo::JS_RETURN);
255812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
255912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
256012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
256112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::RecordDebugBreakSlot() {
256212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  positions_recorder()->WriteRecordedPositions();
256312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CheckBuffer();
256412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
256512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
256612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
256712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
256812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::RecordComment(const char* msg) {
256912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (FLAG_code_comments) {
257012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    CheckBuffer();
257112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
257212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
257312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
257412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
257512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
257612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
257712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr = instr_at(pc);
2578e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsJ(instr) || IsLui(instr));
257912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (IsLui(instr)) {
258012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
258112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
258212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize);
2583e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori));
2584e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOri(instr_ori2));
258512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // TODO(plind): symbolic names for the shifts.
258612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
258712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
258812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)) << 16;
258912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Sign extend address.
259012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm >>= 16;
259112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
259212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (imm == kEndOfJumpChain) {
259312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return 0;  // Number of instructions patched.
259412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
259512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm += pc_delta;
2596e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm & 3) == 0);
259712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
259812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_lui &= ~kImm16Mask;
259912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_ori &= ~kImm16Mask;
260012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_ori2 &= ~kImm16Mask;
260112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
260212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pc + 0 * Assembler::kInstrSize,
260312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_lui | ((imm >> 32) & kImm16Mask));
260412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pc + 1 * Assembler::kInstrSize,
260512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_ori | (imm >> 16 & kImm16Mask));
260612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pc + 3 * Assembler::kInstrSize,
260712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                 instr_ori2 | (imm & kImm16Mask));
260812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return 4;  // Number of instructions patched.
260912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
261012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
261112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
261212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return 0;  // Number of instructions patched.
261312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
261412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
261512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm28 += pc_delta;
261612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    imm28 &= kImm28Mask;
2617e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((imm28 & 3) == 0);
261812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
261912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr &= ~kImm26Mask;
262012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t imm26 = imm28 >> 2;
2621e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_uint26(imm26));
262212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
262312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    instr_at_put(pc, instr | (imm26 & kImm26Mask));
262412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return 1;  // Number of instructions patched.
262512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
262612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
262712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
262812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
262912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::GrowBuffer() {
263012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (!own_buffer_) FATAL("external code buffer is too small");
263112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
263212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Compute new buffer size.
263312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CodeDesc desc;  // The new buffer.
26349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  if (buffer_size_ < 1 * MB) {
263512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    desc.buffer_size = 2*buffer_size_;
263612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
263712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    desc.buffer_size = buffer_size_ + 1*MB;
263812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
263912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CHECK_GT(desc.buffer_size, 0);  // No overflow.
264012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
264112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Set up new buffer.
264212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc.buffer = NewArray<byte>(desc.buffer_size);
264312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
264412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc.instr_size = pc_offset();
264512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
264612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
264712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Copy the data.
264812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  intptr_t pc_delta = desc.buffer - buffer_;
264912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
265012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      (buffer_ + buffer_size_);
265112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  MemMove(desc.buffer, buffer_, desc.instr_size);
265212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  MemMove(reloc_info_writer.pos() + rc_delta,
265312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org              reloc_info_writer.pos(), desc.reloc_size);
265412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
265512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Switch buffers.
265612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  DeleteArray(buffer_);
265712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  buffer_ = desc.buffer;
265812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  buffer_size_ = desc.buffer_size;
265912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  pc_ += pc_delta;
266012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
266112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                               reloc_info_writer.last_pc() + pc_delta);
266212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
266312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Relocate runtime entries.
266412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  for (RelocIterator it(desc); !it.done(); it.next()) {
266512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    RelocInfo::Mode rmode = it.rinfo()->rmode();
266612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
266712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
266812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      RelocateInternalReference(p, pc_delta);
266912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
267012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
267112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2672e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!overflow());
267312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
267412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
267512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
267612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::db(uint8_t data) {
267712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CheckBuffer();
267812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *reinterpret_cast<uint8_t*>(pc_) = data;
267912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  pc_ += sizeof(uint8_t);
268012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
268112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
268212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
268312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::dd(uint32_t data) {
268412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CheckBuffer();
268512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *reinterpret_cast<uint32_t*>(pc_) = data;
268612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  pc_ += sizeof(uint32_t);
268712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
268812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
268912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
269012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::emit_code_stub_address(Code* stub) {
269112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CheckBuffer();
269212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *reinterpret_cast<uint64_t*>(pc_) =
269312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      reinterpret_cast<uint64_t>(stub->instruction_start());
269412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  pc_ += sizeof(uint64_t);
269512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
269612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
269712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
269812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
269912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We do not try to reuse pool constants.
270012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  RelocInfo rinfo(pc_, rmode, data, NULL);
270112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
270212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Adjust code for new modes.
2703e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(RelocInfo::IsDebugBreakSlot(rmode)
270412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org           || RelocInfo::IsJSReturn(rmode)
270512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org           || RelocInfo::IsComment(rmode)
270612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org           || RelocInfo::IsPosition(rmode));
270712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // These modes do not need an entry in the constant pool.
270812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
270912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (!RelocInfo::IsNone(rinfo.rmode())) {
271012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Don't record external references unless the heap will be serialized.
271112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
271212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        !serializer_enabled() && !emit_debug_code()) {
271312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      return;
271412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
2715e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
271612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
271712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      RelocInfo reloc_info_with_ast_id(pc_,
271812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                       rmode,
271912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                       RecordedAstId().ToInt(),
272012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                       NULL);
272112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ClearRecordedAstId();
272212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      reloc_info_writer.Write(&reloc_info_with_ast_id);
272312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
272412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      reloc_info_writer.Write(&rinfo);
272512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
272612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
272712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
272812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
272912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
273012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::BlockTrampolinePoolFor(int instructions) {
273112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
273212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
273312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
273412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
273512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::CheckTrampolinePool() {
273612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Some small sequences of instructions must not be broken up by the
273712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // insertion of a trampoline pool; such sequences are protected by setting
273812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
273912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // which are both checked here. Also, recursive calls to CheckTrampolinePool
274012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // are blocked by trampoline_pool_blocked_nesting_.
274112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if ((trampoline_pool_blocked_nesting_ > 0) ||
274212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      (pc_offset() < no_trampoline_pool_before_)) {
274312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Emission is currently blocked; make sure we try again as soon as
274412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // possible.
274512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    if (trampoline_pool_blocked_nesting_ > 0) {
274612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      next_buffer_check_ = pc_offset() + kInstrSize;
274712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    } else {
274812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      next_buffer_check_ = no_trampoline_pool_before_;
274912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
275012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return;
275112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
275212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2753e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!trampoline_emitted_);
2754e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(unbound_labels_count_ >= 0);
275512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (unbound_labels_count_ > 0) {
275612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // First we emit jump (2 instructions), then we emit trampoline pool.
275712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    { BlockTrampolinePoolScope block_trampoline_pool(this);
275812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      Label after_pool;
275912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      b(&after_pool);
276012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      nop();
276112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
276212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int pool_start = pc_offset();
276312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      for (int i = 0; i < unbound_labels_count_; i++) {
276412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        uint64_t imm64;
276512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        imm64 = jump_address(&after_pool);
276612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        { BlockGrowBufferScope block_buf_growth(this);
276712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          // Buffer growth (and relocation) must be blocked for internal
276812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          // references until associated instructions are emitted and available
276912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          // to be patched.
277012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
277112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          // TODO(plind): Verify this, presume I cannot use macro-assembler
277212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          // here.
277312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          lui(at, (imm64 >> 32) & kImm16Mask);
277412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          ori(at, at, (imm64 >> 16) & kImm16Mask);
277512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          dsll(at, at, 16);
277612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          ori(at, at, imm64 & kImm16Mask);
277712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        }
277812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        jr(at);
277912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        nop();
278012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
278112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      bind(&after_pool);
278212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      trampoline_ = Trampoline(pool_start, unbound_labels_count_);
278312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
278412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      trampoline_emitted_ = true;
278512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // As we are only going to emit trampoline once, we need to prevent any
278612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      // further emission.
278712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      next_buffer_check_ = kMaxInt;
278812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
278912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else {
279012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Number of branches to unbound label at this point is zero, so we can
279112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // move next buffer check to maximum.
279212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    next_buffer_check_ = pc_offset() +
279312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        kMaxBranchOffset - kTrampolineSlotsSize * 16;
279412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
279512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return;
279612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
279712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
279812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
279912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgAddress Assembler::target_address_at(Address pc) {
280012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr0 = instr_at(pc);
280112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr1 = instr_at(pc + 1 * kInstrSize);
280212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr3 = instr_at(pc + 3 * kInstrSize);
280312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
280412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Interpret 4 instructions for address generated by li: See listing in
280512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Assembler::set_target_address_at() just below.
280612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if ((GetOpcodeField(instr0) == LUI) && (GetOpcodeField(instr1) == ORI) &&
280712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      (GetOpcodeField(instr3) == ORI)) {
280812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Assemble the 48 bit value.
280912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org     int64_t addr  = static_cast<int64_t>(
281012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          ((uint64_t)(GetImmediate16(instr0)) << 32) |
281112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          ((uint64_t)(GetImmediate16(instr1)) << 16) |
281212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          ((uint64_t)(GetImmediate16(instr3))));
281312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
281412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Sign extend to get canonical address.
281512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    addr = (addr << 16) >> 16;
281612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    return reinterpret_cast<Address>(addr);
281712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
281812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We should never get here, force a bad address if we do.
281912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  UNREACHABLE();
282012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return (Address)0x0;
282112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
282212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
282312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
282412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
282512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
282612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
282712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// OS::nan_value() returns a qNaN.
282812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::QuietNaN(HeapObject* object) {
282912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  HeapNumber::cast(object)->set_value(base::OS::nan_value());
283012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
283112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
283212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
283312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// On Mips64, a target address is stored in a 4-instruction sequence:
283412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//    0: lui(rd, (j.imm64_ >> 32) & kImm16Mask);
283512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//    1: ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
283612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//    2: dsll(rd, rd, 16);
283712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//    3: ori(rd, rd, j.imm32_ & kImm16Mask);
283812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
283912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Patching the address must replace all the lui & ori instructions,
284012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// and flush the i-cache.
284112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org//
284212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// There is an optimization below, which emits a nop when the address
284312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// fits in just 16 bits. This is unlikely to help, and should be benchmarked,
284412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// and possibly removed.
284512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::set_target_address_at(Address pc,
284612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                      Address target,
284712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                      ICacheFlushMode icache_flush_mode) {
284812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// There is an optimization where only 4 instructions are used to load address
284912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// in code on MIP64 because only 48-bits of address is effectively used.
285012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// It relies on fact the upper [63:48] bits are not used for virtual address
285112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// translation and they have to be set according to value of bit 47 in order
285212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// get canonical address.
285312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr1 = instr_at(pc + kInstrSize);
285412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t rt_code = GetRt(instr1);
285512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t* p = reinterpret_cast<uint32_t*>(pc);
285612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint64_t itarget = reinterpret_cast<uint64_t>(target);
285712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
285812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef DEBUG
285912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Check we have the result from a li macro-instruction.
286012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr0 = instr_at(pc);
286112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr3 = instr_at(pc + kInstrSize * 3);
286212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CHECK((GetOpcodeField(instr0) == LUI && GetOpcodeField(instr1) == ORI &&
286312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org         GetOpcodeField(instr3) == ORI));
286412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
286512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
286612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Must use 4 instructions to insure patchable code.
286712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // lui rt, upper-16.
286812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ori rt, rt, lower-16.
286912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // dsll rt, rt, 16.
287012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ori rt rt, lower-16.
287112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *p = LUI | (rt_code << kRtShift) | ((itarget >> 32) & kImm16Mask);
287212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *(p + 1) = ORI | (rt_code << kRtShift) | (rt_code << kRsShift)
287312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | ((itarget >> 16) & kImm16Mask);
287412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  *(p + 3) = ORI | (rt_code << kRsShift) | (rt_code << kRtShift)
287512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      | (itarget & kImm16Mask);
287612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
287712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
287812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    CpuFeatures::FlushICache(pc, 4 * Assembler::kInstrSize);
287912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
288012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
288112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
288212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
288312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::JumpLabelToJumpRegister(Address pc) {
288412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Address pc points to lui/ori instructions.
288512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Jump to label may follow at pc + 2 * kInstrSize.
288612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  uint32_t* p = reinterpret_cast<uint32_t*>(pc);
288712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef DEBUG
288812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr1 = instr_at(pc);
288912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
289012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr2 = instr_at(pc + 1 * kInstrSize);
289112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Instr instr3 = instr_at(pc + 6 * kInstrSize);
289212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  bool patched = false;
289312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
289412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (IsJal(instr3)) {
2895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(GetOpcodeField(instr1) == LUI);
2896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(GetOpcodeField(instr2) == ORI);
289712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
289812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t rs_field = GetRt(instr2) << kRsShift;
289912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t rd_field = ra.code() << kRdShift;  // Return-address (ra) reg.
290012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    *(p+6) = SPECIAL | rs_field | rd_field | JALR;
290112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    patched = true;
290212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  } else if (IsJ(instr3)) {
2903e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(GetOpcodeField(instr1) == LUI);
2904e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(GetOpcodeField(instr2) == ORI);
290512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
290612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    uint32_t rs_field = GetRt(instr2) << kRsShift;
290712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    *(p+6) = SPECIAL | rs_field | JR;
290812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    patched = true;
290912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
291012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
291112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (patched) {
291212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      CpuFeatures::FlushICache(pc+6, sizeof(int32_t));
291312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
291412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
291512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
291612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
291712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgHandle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
291812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // No out-of-line constant pool support.
2919e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!FLAG_enable_ool_constant_pool);
292012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return isolate->factory()->empty_constant_pool_array();
292112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
292212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
292312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
292412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
292512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // No out-of-line constant pool support.
2926e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!FLAG_enable_ool_constant_pool);
292712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return;
292812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
292912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
293012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
293112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} }  // namespace v8::internal
293212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
293312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif  // V8_TARGET_ARCH_MIPS64
2934