// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
#define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
#include <ctype.h>
-#include "v8globals.h"
-#include "globals.h"
+#include "src/globals.h"
-#include "arm64/assembler-arm64.h"
-#include "arm64/assembler-arm64-inl.h"
-#include "arm64/macro-assembler-arm64.h"
-#include "arm64/instrument-arm64.h"
+#include "src/arm64/assembler-arm64-inl.h"
+#include "src/arm64/assembler-arm64.h"
+#include "src/arm64/instrument-arm64.h"
+#include "src/arm64/macro-assembler-arm64.h"
+#include "src/base/bits.h"
namespace v8 {
Handle<Object> MacroAssembler::CodeObject() {
- ASSERT(!code_object_.is_null());
+ DCHECK(!code_object_.is_null());
return code_object_;
}
void MacroAssembler::And(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, AND);
}
void MacroAssembler::Ands(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, ANDS);
}
void MacroAssembler::Tst(const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS);
}
void MacroAssembler::Bic(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, BIC);
}
void MacroAssembler::Bics(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, BICS);
}
void MacroAssembler::Orr(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, ORR);
}
void MacroAssembler::Orn(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, ORN);
}
void MacroAssembler::Eor(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, EOR);
}
void MacroAssembler::Eon(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
LogicalMacro(rd, rn, operand, EON);
}
const Operand& operand,
StatusFlags nzcv,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- ConditionalCompareMacro(rn, -operand.immediate(), nzcv, cond, CCMN);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
+ ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMN);
} else {
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
}
const Operand& operand,
StatusFlags nzcv,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- ConditionalCompareMacro(rn, -operand.immediate(), nzcv, cond, CCMP);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
+ ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP);
} else {
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
}
void MacroAssembler::Add(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- AddSubMacro(rd, rn, -operand.immediate(), LeaveFlags, SUB);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
+ IsImmAddSub(-operand.ImmediateValue())) {
+ AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, SUB);
} else {
AddSubMacro(rd, rn, operand, LeaveFlags, ADD);
}
void MacroAssembler::Adds(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- AddSubMacro(rd, rn, -operand.immediate(), SetFlags, SUB);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
+ IsImmAddSub(-operand.ImmediateValue())) {
+ AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, SUB);
} else {
AddSubMacro(rd, rn, operand, SetFlags, ADD);
}
void MacroAssembler::Sub(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- AddSubMacro(rd, rn, -operand.immediate(), LeaveFlags, ADD);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
+ IsImmAddSub(-operand.ImmediateValue())) {
+ AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, ADD);
} else {
AddSubMacro(rd, rn, operand, LeaveFlags, SUB);
}
void MacroAssembler::Subs(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- if (operand.IsImmediate() && (operand.immediate() < 0)) {
- AddSubMacro(rd, rn, -operand.immediate(), SetFlags, ADD);
+ DCHECK(allow_macro_instructions_);
+ if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
+ IsImmAddSub(-operand.ImmediateValue())) {
+ AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, ADD);
} else {
AddSubMacro(rd, rn, operand, SetFlags, SUB);
}
void MacroAssembler::Cmn(const Register& rn, const Operand& operand) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
Adds(AppropriateZeroRegFor(rn), rn, operand);
}
void MacroAssembler::Cmp(const Register& rn, const Operand& operand) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
Subs(AppropriateZeroRegFor(rn), rn, operand);
}
void MacroAssembler::Neg(const Register& rd,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
if (operand.IsImmediate()) {
- Mov(rd, -operand.immediate());
+ Mov(rd, -operand.ImmediateValue());
} else {
Sub(rd, AppropriateZeroRegFor(rd), operand);
}
void MacroAssembler::Negs(const Register& rd,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
Subs(rd, AppropriateZeroRegFor(rd), operand);
}
void MacroAssembler::Adc(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, ADC);
}
void MacroAssembler::Adcs(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC);
}
void MacroAssembler::Sbc(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC);
}
void MacroAssembler::Sbcs(const Register& rd,
const Register& rn,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC);
}
void MacroAssembler::Ngc(const Register& rd,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
Register zr = AppropriateZeroRegFor(rd);
Sbc(rd, zr, operand);
}
void MacroAssembler::Ngcs(const Register& rd,
const Operand& operand) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
Register zr = AppropriateZeroRegFor(rd);
Sbcs(rd, zr, operand);
}
void MacroAssembler::Mvn(const Register& rd, uint64_t imm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
Mov(rd, ~imm);
}
#define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \
void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \
- ASSERT(allow_macro_instructions_); \
+ DCHECK(allow_macro_instructions_); \
LoadStoreMacro(REG, addr, OP); \
}
LS_MACRO_LIST(DEFINE_FUNCTION)
#undef DEFINE_FUNCTION
-void MacroAssembler::Adr(const Register& rd, Label* label) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- adr(rd, label);
-}
+#define DEFINE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
+ void MacroAssembler::FN(const REGTYPE REG, const REGTYPE REG2, \
+ const MemOperand& addr) { \
+ DCHECK(allow_macro_instructions_); \
+ LoadStorePairMacro(REG, REG2, addr, OP); \
+ }
+LSPAIR_MACRO_LIST(DEFINE_FUNCTION)
+#undef DEFINE_FUNCTION
void MacroAssembler::Asr(const Register& rd,
const Register& rn,
unsigned shift) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
asr(rd, rn, shift);
}
void MacroAssembler::Asr(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
asrv(rd, rn, rm);
}
void MacroAssembler::B(Condition cond, Label* label) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
B(label, cond);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
bfi(rd, rn, lsb, width);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
bfxil(rd, rn, lsb, width);
}
void MacroAssembler::Bind(Label* label) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
bind(label);
}
void MacroAssembler::Bl(Label* label) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
bl(label);
}
void MacroAssembler::Blr(const Register& xn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!xn.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!xn.IsZero());
blr(xn);
}
void MacroAssembler::Br(const Register& xn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!xn.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!xn.IsZero());
br(xn);
}
void MacroAssembler::Brk(int code) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
brk(code);
}
void MacroAssembler::Cinc(const Register& rd,
const Register& rn,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
cinc(rd, rn, cond);
}
void MacroAssembler::Cinv(const Register& rd,
const Register& rn,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
cinv(rd, rn, cond);
}
void MacroAssembler::Cls(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
cls(rd, rn);
}
void MacroAssembler::Clz(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
clz(rd, rn);
}
void MacroAssembler::Cneg(const Register& rd,
const Register& rn,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
cneg(rd, rn, cond);
}
// due to the truncation side-effect when used on W registers.
void MacroAssembler::CzeroX(const Register& rd,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsSP() && rd.Is64Bits());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsSP() && rd.Is64Bits());
+ DCHECK((cond != al) && (cond != nv));
csel(rd, xzr, rd, cond);
}
void MacroAssembler::CmovX(const Register& rd,
const Register& rn,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsSP());
- ASSERT(rd.Is64Bits() && rn.Is64Bits());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsSP());
+ DCHECK(rd.Is64Bits() && rn.Is64Bits());
+ DCHECK((cond != al) && (cond != nv));
if (!rd.is(rn)) {
csel(rd, rn, rd, cond);
}
void MacroAssembler::Cset(const Register& rd, Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
cset(rd, cond);
}
void MacroAssembler::Csetm(const Register& rd, Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
csetm(rd, cond);
}
const Register& rn,
const Register& rm,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
csinc(rd, rn, rm, cond);
}
const Register& rn,
const Register& rm,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
csinv(rd, rn, rm, cond);
}
const Register& rn,
const Register& rm,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ DCHECK((cond != al) && (cond != nv));
csneg(rd, rn, rm, cond);
}
void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
dmb(domain, type);
}
void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
dsb(domain, type);
}
void MacroAssembler::Debug(const char* message, uint32_t code, Instr params) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
debug(message, code, params);
}
const Register& rn,
const Register& rm,
unsigned lsb) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
extr(rd, rn, rm, lsb);
}
void MacroAssembler::Fabs(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fabs(fd, fn);
}
void MacroAssembler::Fadd(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fadd(fd, fn, fm);
}
const FPRegister& fm,
StatusFlags nzcv,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK((cond != al) && (cond != nv));
fccmp(fn, fm, nzcv, cond);
}
void MacroAssembler::Fcmp(const FPRegister& fn, const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fcmp(fn, fm);
}
void MacroAssembler::Fcmp(const FPRegister& fn, double value) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
if (value != 0.0) {
UseScratchRegisterScope temps(this);
FPRegister tmp = temps.AcquireSameSizeAs(fn);
const FPRegister& fn,
const FPRegister& fm,
Condition cond) {
- ASSERT(allow_macro_instructions_);
- ASSERT((cond != al) && (cond != nv));
+ DCHECK(allow_macro_instructions_);
+ DCHECK((cond != al) && (cond != nv));
fcsel(fd, fn, fm, cond);
}
void MacroAssembler::Fcvt(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fcvt(fd, fn);
}
void MacroAssembler::Fcvtas(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtas(rd, fn);
}
void MacroAssembler::Fcvtau(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtau(rd, fn);
}
void MacroAssembler::Fcvtms(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtms(rd, fn);
}
void MacroAssembler::Fcvtmu(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtmu(rd, fn);
}
void MacroAssembler::Fcvtns(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtns(rd, fn);
}
void MacroAssembler::Fcvtnu(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtnu(rd, fn);
}
void MacroAssembler::Fcvtzs(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtzs(rd, fn);
}
void MacroAssembler::Fcvtzu(const Register& rd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fcvtzu(rd, fn);
}
void MacroAssembler::Fdiv(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fdiv(fd, fn, fm);
}
const FPRegister& fn,
const FPRegister& fm,
const FPRegister& fa) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmadd(fd, fn, fm, fa);
}
void MacroAssembler::Fmax(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmax(fd, fn, fm);
}
void MacroAssembler::Fmaxnm(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmaxnm(fd, fn, fm);
}
void MacroAssembler::Fmin(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmin(fd, fn, fm);
}
void MacroAssembler::Fminnm(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fminnm(fd, fn, fm);
}
void MacroAssembler::Fmov(FPRegister fd, FPRegister fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
// Only emit an instruction if fd and fn are different, and they are both D
// registers. fmov(s0, s0) is not a no-op because it clears the top word of
// d0. Technically, fmov(d0, d0) is not a no-op either because it clears the
void MacroAssembler::Fmov(FPRegister fd, Register rn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmov(fd, rn);
}
void MacroAssembler::Fmov(FPRegister fd, double imm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
if (fd.Is32Bits()) {
Fmov(fd, static_cast<float>(imm));
return;
}
- ASSERT(fd.Is64Bits());
+ DCHECK(fd.Is64Bits());
if (IsImmFP64(imm)) {
fmov(fd, imm);
} else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
fmov(fd, xzr);
} else {
- UseScratchRegisterScope temps(this);
- Register tmp = temps.AcquireX();
- // TODO(all): Use Assembler::ldr(const FPRegister& ft, double imm).
- Mov(tmp, double_to_rawbits(imm));
- Fmov(fd, tmp);
+ Ldr(fd, imm);
}
}
void MacroAssembler::Fmov(FPRegister fd, float imm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
if (fd.Is64Bits()) {
Fmov(fd, static_cast<double>(imm));
return;
}
- ASSERT(fd.Is32Bits());
+ DCHECK(fd.Is32Bits());
if (IsImmFP32(imm)) {
fmov(fd, imm);
} else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
void MacroAssembler::Fmov(Register rd, FPRegister fn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
fmov(rd, fn);
}
const FPRegister& fn,
const FPRegister& fm,
const FPRegister& fa) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmsub(fd, fn, fm, fa);
}
void MacroAssembler::Fmul(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fmul(fd, fn, fm);
}
void MacroAssembler::Fneg(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fneg(fd, fn);
}
const FPRegister& fn,
const FPRegister& fm,
const FPRegister& fa) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fnmadd(fd, fn, fm, fa);
}
const FPRegister& fn,
const FPRegister& fm,
const FPRegister& fa) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fnmsub(fd, fn, fm, fa);
}
void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
frinta(fd, fn);
}
+void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) {
+ DCHECK(allow_macro_instructions_);
+ frintm(fd, fn);
+}
+
+
void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
frintn(fd, fn);
}
+void MacroAssembler::Frintp(const FPRegister& fd, const FPRegister& fn) {
+ DCHECK(allow_macro_instructions_);
+ frintp(fd, fn);
+}
+
+
void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
frintz(fd, fn);
}
void MacroAssembler::Fsqrt(const FPRegister& fd, const FPRegister& fn) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fsqrt(fd, fn);
}
void MacroAssembler::Fsub(const FPRegister& fd,
const FPRegister& fn,
const FPRegister& fm) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
fsub(fd, fn, fm);
}
void MacroAssembler::Hint(SystemHint code) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
hint(code);
}
void MacroAssembler::Hlt(int code) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
hlt(code);
}
void MacroAssembler::Isb() {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
isb();
}
void MacroAssembler::Ldnp(const CPURegister& rt,
const CPURegister& rt2,
const MemOperand& src) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!AreAliased(rt, rt2));
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!AreAliased(rt, rt2));
ldnp(rt, rt2, src);
}
-void MacroAssembler::Ldp(const CPURegister& rt,
- const CPURegister& rt2,
- const MemOperand& src) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!AreAliased(rt, rt2));
- ldp(rt, rt2, src);
-}
-
-
-void MacroAssembler::Ldpsw(const Register& rt,
- const Register& rt2,
- const MemOperand& src) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
- ASSERT(!rt2.IsZero());
- ldpsw(rt, rt2, src);
-}
-
-
-void MacroAssembler::Ldr(const FPRegister& ft, double imm) {
- ASSERT(allow_macro_instructions_);
- ldr(ft, imm);
+void MacroAssembler::Ldr(const CPURegister& rt, const Immediate& imm) {
+ DCHECK(allow_macro_instructions_);
+ ldr(rt, imm);
}
-void MacroAssembler::Ldr(const Register& rt, uint64_t imm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
- ldr(rt, imm);
+void MacroAssembler::Ldr(const CPURegister& rt, double imm) {
+ DCHECK(allow_macro_instructions_);
+ DCHECK(rt.Is64Bits());
+ ldr(rt, Immediate(double_to_rawbits(imm)));
}
void MacroAssembler::Lsl(const Register& rd,
const Register& rn,
unsigned shift) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
lsl(rd, rn, shift);
}
void MacroAssembler::Lsl(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
lslv(rd, rn, rm);
}
void MacroAssembler::Lsr(const Register& rd,
const Register& rn,
unsigned shift) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
lsr(rd, rn, shift);
}
void MacroAssembler::Lsr(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
lsrv(rd, rn, rm);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
madd(rd, rn, rm, ra);
}
void MacroAssembler::Mneg(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
mneg(rd, rn, rm);
}
void MacroAssembler::Mov(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
// Emit a register move only if the registers are distinct, or if they are
// not X registers. Note that mov(w0, w0) is not a no-op because it clears
// the top word of x0.
void MacroAssembler::Movk(const Register& rd, uint64_t imm, int shift) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
movk(rd, imm, shift);
}
void MacroAssembler::Mrs(const Register& rt, SystemRegister sysreg) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rt.IsZero());
mrs(rt, sysreg);
}
void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
+ DCHECK(allow_macro_instructions_);
msr(sysreg, rt);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
msub(rd, rn, rm, ra);
}
void MacroAssembler::Mul(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
mul(rd, rn, rm);
}
void MacroAssembler::Rbit(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
rbit(rd, rn);
}
void MacroAssembler::Ret(const Register& xn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!xn.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!xn.IsZero());
ret(xn);
CheckVeneerPool(false, false);
}
void MacroAssembler::Rev(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
rev(rd, rn);
}
void MacroAssembler::Rev16(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
rev16(rd, rn);
}
void MacroAssembler::Rev32(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
rev32(rd, rn);
}
void MacroAssembler::Ror(const Register& rd,
const Register& rs,
unsigned shift) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
ror(rd, rs, shift);
}
void MacroAssembler::Ror(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
rorv(rd, rn, rm);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sbfiz(rd, rn, lsb, width);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sbfx(rd, rn, lsb, width);
}
void MacroAssembler::Scvtf(const FPRegister& fd,
const Register& rn,
unsigned fbits) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
scvtf(fd, rn, fbits);
}
void MacroAssembler::Sdiv(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sdiv(rd, rn, rm);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
smaddl(rd, rn, rm, ra);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
smsubl(rd, rn, rm, ra);
}
void MacroAssembler::Smull(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
smull(rd, rn, rm);
}
void MacroAssembler::Smulh(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
smulh(rd, rn, rm);
}
+void MacroAssembler::Umull(const Register& rd, const Register& rn,
+ const Register& rm) {
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
+ umaddl(rd, rn, rm, xzr);
+}
+
+
void MacroAssembler::Stnp(const CPURegister& rt,
const CPURegister& rt2,
const MemOperand& dst) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
stnp(rt, rt2, dst);
}
-void MacroAssembler::Stp(const CPURegister& rt,
- const CPURegister& rt2,
- const MemOperand& dst) {
- ASSERT(allow_macro_instructions_);
- stp(rt, rt2, dst);
-}
-
-
void MacroAssembler::Sxtb(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sxtb(rd, rn);
}
void MacroAssembler::Sxth(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sxth(rd, rn);
}
void MacroAssembler::Sxtw(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
sxtw(rd, rn);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
ubfiz(rd, rn, lsb, width);
}
const Register& rn,
unsigned lsb,
unsigned width) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
ubfx(rd, rn, lsb, width);
}
void MacroAssembler::Ucvtf(const FPRegister& fd,
const Register& rn,
unsigned fbits) {
- ASSERT(allow_macro_instructions_);
+ DCHECK(allow_macro_instructions_);
ucvtf(fd, rn, fbits);
}
void MacroAssembler::Udiv(const Register& rd,
const Register& rn,
const Register& rm) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
udiv(rd, rn, rm);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
umaddl(rd, rn, rm, ra);
}
const Register& rn,
const Register& rm,
const Register& ra) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
umsubl(rd, rn, rm, ra);
}
void MacroAssembler::Uxtb(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
uxtb(rd, rn);
}
void MacroAssembler::Uxth(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
uxth(rd, rn);
}
void MacroAssembler::Uxtw(const Register& rd, const Register& rn) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
+ DCHECK(allow_macro_instructions_);
+ DCHECK(!rd.IsZero());
uxtw(rd, rn);
}
void MacroAssembler::BumpSystemStackPointer(const Operand& space) {
- ASSERT(!csp.Is(sp_));
- // TODO(jbramley): Several callers rely on this not using scratch registers,
- // so we use the assembler directly here. However, this means that large
- // immediate values of 'space' cannot be handled cleanly. (Only 24-bits
- // immediates or values of 'space' that can be encoded in one instruction are
- // accepted.) Once we implement our flexible scratch register idea, we could
- // greatly simplify this function.
- InstructionAccurateScope scope(this);
- if ((space.IsImmediate()) && !is_uint12(space.immediate())) {
- // The subtract instruction supports a 12-bit immediate, shifted left by
- // zero or 12 bits. So, in two instructions, we can subtract any immediate
- // between zero and (1 << 24) - 1.
- int64_t imm = space.immediate();
- ASSERT(is_uint24(imm));
-
- int64_t imm_top_12_bits = imm >> 12;
- sub(csp, StackPointer(), imm_top_12_bits << 12);
- imm -= imm_top_12_bits << 12;
- if (imm > 0) {
- sub(csp, csp, imm);
+ DCHECK(!csp.Is(sp_));
+ if (!TmpList()->IsEmpty()) {
+ if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
+ UseScratchRegisterScope temps(this);
+ Register temp = temps.AcquireX();
+ Sub(temp, StackPointer(), space);
+ Bic(csp, temp, 0xf);
+ } else {
+ Sub(csp, StackPointer(), space);
}
} else {
- sub(csp, StackPointer(), space);
+ // TODO(jbramley): Several callers rely on this not using scratch
+ // registers, so we use the assembler directly here. However, this means
+ // that large immediate values of 'space' cannot be handled cleanly. (Only
+ // 24-bits immediates or values of 'space' that can be encoded in one
+ // instruction are accepted.) Once we implement our flexible scratch
+ // register idea, we could greatly simplify this function.
+ InstructionAccurateScope scope(this);
+ DCHECK(space.IsImmediate());
+ // Align to 16 bytes.
+ uint64_t imm = RoundUp(space.ImmediateValue(), 0x10);
+ DCHECK(is_uint24(imm));
+
+ Register source = StackPointer();
+ if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
+ bic(csp, source, 0xf);
+ source = csp;
+ }
+ if (!is_uint12(imm)) {
+ int64_t imm_top_12_bits = imm >> 12;
+ sub(csp, source, imm_top_12_bits << 12);
+ source = csp;
+ imm -= imm_top_12_bits << 12;
+ }
+ if (imm > 0) {
+ sub(csp, source, imm);
+ }
}
+ AssertStackConsistency();
+}
+
+
+void MacroAssembler::SyncSystemStackPointer() {
+ DCHECK(emit_debug_code());
+ DCHECK(!csp.Is(sp_));
+ { InstructionAccurateScope scope(this);
+ if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
+ bic(csp, StackPointer(), 0xf);
+ } else {
+ mov(csp, StackPointer());
+ }
+ }
+ AssertStackConsistency();
}
void MacroAssembler::SmiTag(Register dst, Register src) {
- ASSERT(dst.Is64Bits() && src.Is64Bits());
+ STATIC_ASSERT(kXRegSizeInBits ==
+ static_cast<unsigned>(kSmiShift + kSmiValueSize));
+ DCHECK(dst.Is64Bits() && src.Is64Bits());
Lsl(dst, src, kSmiShift);
}
void MacroAssembler::SmiUntag(Register dst, Register src) {
- ASSERT(dst.Is64Bits() && src.Is64Bits());
+ STATIC_ASSERT(kXRegSizeInBits ==
+ static_cast<unsigned>(kSmiShift + kSmiValueSize));
+ DCHECK(dst.Is64Bits() && src.Is64Bits());
if (FLAG_enable_slow_asserts) {
AssertSmi(src);
}
void MacroAssembler::SmiUntagToDouble(FPRegister dst,
Register src,
UntagMode mode) {
- ASSERT(dst.Is64Bits() && src.Is64Bits());
+ DCHECK(dst.Is64Bits() && src.Is64Bits());
if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) {
AssertSmi(src);
}
void MacroAssembler::SmiUntagToFloat(FPRegister dst,
Register src,
UntagMode mode) {
- ASSERT(dst.Is32Bits() && src.Is64Bits());
+ DCHECK(dst.Is32Bits() && src.Is64Bits());
if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) {
AssertSmi(src);
}
}
+void MacroAssembler::SmiTagAndPush(Register src) {
+ STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) &&
+ (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) &&
+ (kSmiTag == 0));
+ Push(src.W(), wzr);
+}
+
+
+void MacroAssembler::SmiTagAndPush(Register src1, Register src2) {
+ STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) &&
+ (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) &&
+ (kSmiTag == 0));
+ Push(src1.W(), wzr, src2.W(), wzr);
+}
+
+
void MacroAssembler::JumpIfSmi(Register value,
Label* smi_label,
Label* not_smi_label) {
B(not_smi_label);
}
} else {
- ASSERT(not_smi_label);
+ DCHECK(not_smi_label);
Tbnz(value, 0, not_smi_label);
}
}
}
+void MacroAssembler::ObjectTag(Register tagged_obj, Register obj) {
+ STATIC_ASSERT(kHeapObjectTag == 1);
+ if (emit_debug_code()) {
+ Label ok;
+ Tbz(obj, 0, &ok);
+ Abort(kObjectTagged);
+ Bind(&ok);
+ }
+ Orr(tagged_obj, obj, kHeapObjectTag);
+}
+
+
+void MacroAssembler::ObjectUntag(Register untagged_obj, Register obj) {
+ STATIC_ASSERT(kHeapObjectTag == 1);
+ if (emit_debug_code()) {
+ Label ok;
+ Tbnz(obj, 0, &ok);
+ Abort(kObjectNotTagged);
+ Bind(&ok);
+ }
+ Bic(untagged_obj, obj, kHeapObjectTag);
+}
+
+
void MacroAssembler::IsObjectNameType(Register object,
Register type,
Label* fail) {
Ldrb(type.W(), FieldMemOperand(type, Map::kInstanceTypeOffset));
STATIC_ASSERT(kStringTag == 0);
- ASSERT((string != NULL) || (not_string != NULL));
+ DCHECK((string != NULL) || (not_string != NULL));
if (string == NULL) {
TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string);
} else if (not_string == NULL) {
}
if (csp.Is(StackPointer())) {
- ASSERT(size % 16 == 0);
+ DCHECK(size % 16 == 0);
} else {
BumpSystemStackPointer(size);
}
void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
-
- if (unit_size == 0) {
- return;
- }
+ if (unit_size == 0) return;
+ DCHECK(base::bits::IsPowerOfTwo64(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
const Operand size(count, LSL, shift);
void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
+ DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
const Operand size(count_smi,
(shift >= 0) ? (LSL) : (LSR),
Add(StackPointer(), StackPointer(), size);
if (csp.Is(StackPointer())) {
- ASSERT(size % 16 == 0);
+ DCHECK(size % 16 == 0);
} else if (emit_debug_code()) {
// It is safe to leave csp where it is when unwinding the JavaScript stack,
// but if we keep it matching StackPointer, the simulator can detect memory
// accesses in the now-free part of the stack.
- Mov(csp, StackPointer());
+ SyncSystemStackPointer();
}
}
void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
-
- if (unit_size == 0) {
- return;
- }
+ if (unit_size == 0) return;
+ DCHECK(base::bits::IsPowerOfTwo64(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
const Operand size(count, LSL, shift);
// It is safe to leave csp where it is when unwinding the JavaScript stack,
// but if we keep it matching StackPointer, the simulator can detect memory
// accesses in the now-free part of the stack.
- Mov(csp, StackPointer());
+ SyncSystemStackPointer();
}
}
void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
+ DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
const Operand size(count_smi,
(shift >= 0) ? (LSL) : (LSR),
// It is safe to leave csp where it is when unwinding the JavaScript stack,
// but if we keep it matching StackPointer, the simulator can detect memory
// accesses in the now-free part of the stack.
- Mov(csp, StackPointer());
+ SyncSystemStackPointer();
}
}
const Operand& rhs,
Condition cond,
Label* label) {
- if (rhs.IsImmediate() && (rhs.immediate() == 0) &&
+ if (rhs.IsImmediate() && (rhs.ImmediateValue() == 0) &&
((cond == eq) || (cond == ne))) {
if (cond == eq) {
Cbz(lhs, label);
const uint64_t bit_pattern,
Label* label) {
int bits = reg.SizeInBits();
- ASSERT(CountSetBits(bit_pattern, bits) > 0);
+ DCHECK(CountSetBits(bit_pattern, bits) > 0);
if (CountSetBits(bit_pattern, bits) == 1) {
Tbnz(reg, MaskToBit(bit_pattern), label);
} else {
const uint64_t bit_pattern,
Label* label) {
int bits = reg.SizeInBits();
- ASSERT(CountSetBits(bit_pattern, bits) > 0);
+ DCHECK(CountSetBits(bit_pattern, bits) > 0);
if (CountSetBits(bit_pattern, bits) == 1) {
Tbz(reg, MaskToBit(bit_pattern), label);
} else {
void MacroAssembler::InlineData(uint64_t data) {
- ASSERT(is_uint16(data));
+ DCHECK(is_uint16(data));
InstructionAccurateScope scope(this, 1);
movz(xzr, data);
}
void MacroAssembler::AnnotateInstrumentation(const char* marker_name) {
- ASSERT(strlen(marker_name) == 2);
+ DCHECK(strlen(marker_name) == 2);
// We allow only printable characters in the marker names. Unprintable
// characters are reserved for controlling features of the instrumentation.
- ASSERT(isprint(marker_name[0]) && isprint(marker_name[1]));
+ DCHECK(isprint(marker_name[0]) && isprint(marker_name[1]));
InstructionAccurateScope scope(this, 1);
movn(xzr, (marker_name[1] << 8) | marker_name[0]);