1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited 2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved. 3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without 5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met: 6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions of source code must retain the above copyright notice, 8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer. 9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions in binary form must reproduce the above copyright notice, 10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer in the documentation 11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and/or other materials provided with the distribution. 12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Neither the name of ARM Limited nor the names of its contributors may be 13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// used to endorse or promote products derived from this software without 14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// specific prior written permission. 15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef VIXL_A64_MACRO_ASSEMBLER_A64_H_ 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define VIXL_A64_MACRO_ASSEMBLER_A64_H_ 29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 30bc4afbd2754e20d14114e4ba83f9035b26ab701dSerban Constantinescu#include "globals-vixl.h" 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/assembler-a64.h" 32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/debugger-a64.h" 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LS_MACRO_LIST(V) \ 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldrb, Register&, rt, LDRB_w) \ 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Strb, Register&, rt, STRB_w) \ 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldrsb, Register&, rt, rt.Is64Bits() ? LDRSB_x : LDRSB_w) \ 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldrh, Register&, rt, LDRH_w) \ 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Strh, Register&, rt, STRH_w) \ 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldrsh, Register&, rt, rt.Is64Bits() ? LDRSH_x : LDRSH_w) \ 42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldr, CPURegister&, rt, LoadOpFor(rt)) \ 43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Str, CPURegister&, rt, StoreOpFor(rt)) \ 44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(Ldrsw, Register&, rt, LDRSW_x) 45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlenum BranchType { 491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Copies of architectural conditions. 501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // The associated conditions can be used in place of those, the code will 511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // take care of reinterpreting them with the correct type. 521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_eq = eq, 531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_ne = ne, 541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_hs = hs, 551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_lo = lo, 561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_mi = mi, 571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_pl = pl, 581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_vs = vs, 591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_vc = vc, 601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_hi = hi, 611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_ls = ls, 621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_ge = ge, 631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_lt = lt, 641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_gt = gt, 651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_le = le, 661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_al = al, 671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl integer_nv = nv, 681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // These two are *different* from the architectural codes al and nv. 701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // 'always' is used to generate unconditional branches. 711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // 'never' is used to not generate a branch (generally as the inverse 721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // branch type of 'always). 731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl always, never, 741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // cbz and cbnz 751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl reg_zero, reg_not_zero, 761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // tbz and tbnz 771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl reg_bit_clear, reg_bit_set, 781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Aliases. 801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl kBranchTypeFirstCondition = eq, 811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl kBranchTypeLastCondition = nv, 821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl kBranchTypeFirstUsingReg = reg_zero, 831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl kBranchTypeFirstUsingBit = reg_bit_clear 841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl}; 851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 87f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlenum DiscardMoveMode { kDontDiscardForSameWReg, kDiscardForSameWReg }; 88f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass MacroAssembler : public Assembler { 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MacroAssembler(byte * buffer, unsigned buffer_size) 92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : Assembler(buffer, buffer_size), 93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG 94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl allow_macro_instructions_(true), 95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl sp_(sp), tmp_list_(ip0, ip1), fptmp_list_(d31) {} 97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Logical macros. 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void And(const Register& rd, 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 101f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 102f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Ands(const Register& rd, 103f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 104f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Bic(const Register& rd, 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 107f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 108f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Bics(const Register& rd, 109f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 110f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Orr(const Register& rd, 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand); 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Orn(const Register& rd, 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand); 117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Eor(const Register& rd, 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand); 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Eon(const Register& rd, 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand); 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Tst(const Register& rn, const Operand& operand); 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void LogicalMacro(const Register& rd, 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LogicalOp op); 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Add and sub macros. 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Add(const Register& rd, 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 132f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 133f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Adds(const Register& rd, 134f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 135f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sub(const Register& rd, 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 138f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 139f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Subs(const Register& rd, 140f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 141f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cmn(const Register& rn, const Operand& operand); 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cmp(const Register& rn, const Operand& operand); 144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Neg(const Register& rd, 145f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 146f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Negs(const Register& rd, 147f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 148f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void AddSubMacro(const Register& rd, 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FlagsUpdate S, 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AddSubOp op); 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Add/sub with carry macros. 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Adc(const Register& rd, 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 158f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 159f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Adcs(const Register& rd, 160f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 161f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sbc(const Register& rd, 163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 164f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 165f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Sbcs(const Register& rd, 166f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 167f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ngc(const Register& rd, 169f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 170f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Ngcs(const Register& rd, 171f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand); 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void AddSubWithCarryMacro(const Register& rd, 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FlagsUpdate S, 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AddSubWithCarryOp op); 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Move macros. 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mov(const Register& rd, uint64_t imm); 180f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Mov(const Register& rd, 181f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand, 182f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl DiscardMoveMode discard_mode = kDontDiscardForSameWReg); 183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mvn(const Register& rd, uint64_t imm) { 184f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Mov(rd, (rd.size() == kXRegSize) ? ~imm : (~imm & kWRegMask)); 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl }; 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mvn(const Register& rd, const Operand& operand); 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool IsImmMovz(uint64_t imm, unsigned reg_size); 188f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl bool IsImmMovn(uint64_t imm, unsigned reg_size); 189f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size); 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 191f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Conditional macros. 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ccmp(const Register& rn, 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl StatusFlags nzcv, 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond); 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ccmn(const Register& rn, 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl StatusFlags nzcv, 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond); 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void ConditionalCompareMacro(const Register& rn, 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Operand& operand, 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl StatusFlags nzcv, 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond, 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ConditionalCompareOp op); 205f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Csel(const Register& rd, 206f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Register& rn, 207f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const Operand& operand, 208f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Condition cond); 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Load/store macros. 211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define DECLARE_FUNCTION(FN, REGTYPE, REG, OP) \ 212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void FN(const REGTYPE REG, const MemOperand& addr); 213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LS_MACRO_LIST(DECLARE_FUNCTION) 214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef DECLARE_FUNCTION 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void LoadStoreMacro(const CPURegister& rt, 217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const MemOperand& addr, 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LoadStoreOp op); 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Push or pop up to 4 registers of the same width to or from the stack, 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // using the current stack pointer as set by SetStackPointer. 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If an argument register is 'NoReg', all further arguments are also assumed 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // to be 'NoReg', and are thus not pushed or popped. 225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Arguments are ordered such that "Push(a, b);" is functionally equivalent 227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // to "Push(a); Push(b);". 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // It is valid to push the same register more than once, and there is no 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // restriction on the order in which registers are specified. 231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // It is not valid to pop into the same register more than once in one 233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // operation, not even into the zero register. 234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If the current stack pointer (as set by SetStackPointer) is sp, then it 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // must be aligned to 16 bytes on entry and the total size of the specified 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers must also be a multiple of 16 bytes. 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Even if the current stack pointer is not the system stack pointer (sp), 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Push (and derived methods) will still modify the system stack pointer in 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // order to comply with ABI rules about accessing memory below the system 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // stack pointer. 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Other than the registers passed into Pop, the stack pointer and (possibly) 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // the system stack pointer, these methods do not modify any other registers. 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Push(const CPURegister& src0, const CPURegister& src1 = NoReg, 247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg); 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg, 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg); 250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Alternative forms of Push and Pop, taking a RegList or CPURegList that 252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // specifies the registers that are to be pushed or popped. Higher-numbered 253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers are associated with higher memory addresses (as in the A32 push 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // and pop instructions). 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // (Push|Pop)SizeRegList allow you to specify the register size as a 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // parameter. Only kXRegSize, kWRegSize, kDRegSize and kSRegSize are 258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // supported. 259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Otherwise, (Push|Pop)(CPU|X|W|D|S)RegList is preferred. 261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushCPURegList(CPURegList registers); 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopCPURegList(CPURegList registers); 263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushSizeRegList(RegList registers, unsigned reg_size, 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CPURegister::RegisterType type = CPURegister::kRegister) { 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PushCPURegList(CPURegList(type, reg_size, registers)); 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopSizeRegList(RegList registers, unsigned reg_size, 269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CPURegister::RegisterType type = CPURegister::kRegister) { 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PopCPURegList(CPURegList(type, reg_size, registers)); 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushXRegList(RegList regs) { 273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PushSizeRegList(regs, kXRegSize); 274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopXRegList(RegList regs) { 276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PopSizeRegList(regs, kXRegSize); 277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushWRegList(RegList regs) { 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PushSizeRegList(regs, kWRegSize); 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopWRegList(RegList regs) { 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PopSizeRegList(regs, kWRegSize); 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void PushDRegList(RegList regs) { 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PushSizeRegList(regs, kDRegSize, CPURegister::kFPRegister); 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void PopDRegList(RegList regs) { 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PopSizeRegList(regs, kDRegSize, CPURegister::kFPRegister); 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void PushSRegList(RegList regs) { 291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PushSizeRegList(regs, kSRegSize, CPURegister::kFPRegister); 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void PopSRegList(RegList regs) { 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PopSizeRegList(regs, kSRegSize, CPURegister::kFPRegister); 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Push the specified register 'count' times. 298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushMultipleTimes(int count, Register src); 299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Poke 'src' onto the stack. The offset is in bytes. 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If the current stack pointer (as set by SetStackPointer) is sp, then sp 303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // must be aligned to 16 bytes. 304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Poke(const Register& src, const Operand& offset); 305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Peek at a value on the stack, and put it in 'dst'. The offset is in bytes. 307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If the current stack pointer (as set by SetStackPointer) is sp, then sp 309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // must be aligned to 16 bytes. 310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Peek(const Register& dst, const Operand& offset); 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Claim or drop stack space without actually accessing memory. 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If the current stack pointer (as set by SetStackPointer) is sp, then it 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // must be aligned to 16 bytes and the size claimed or dropped must be a 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // multiple of 16 bytes. 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Claim(const Operand& size); 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Drop(const Operand& size); 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Preserve the callee-saved registers (as defined by AAPCS64). 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Higher-numbered registers are pushed before lower-numbered registers, and 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // thus get higher addresses. 324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating-point registers are pushed before general-purpose registers, and 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // thus get higher addresses. 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This method must not be called unless StackPointer() is sp, and it is 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // aligned to 16 bytes. 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushCalleeSavedRegisters(); 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Restore the callee-saved registers (as defined by AAPCS64). 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Higher-numbered registers are popped after lower-numbered registers, and 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // thus come from higher addresses. 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating-point registers are popped after general-purpose registers, and 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // thus come from higher addresses. 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This method must not be called unless StackPointer() is sp, and it is 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // aligned to 16 bytes. 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopCalleeSavedRegisters(); 341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Remaining instructions are simple pass-through calls to the assembler. 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Adr(const Register& rd, Label* label) { 3441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 3451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl adr(rd, label); 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Asr(const Register& rd, const Register& rn, unsigned shift) { 3491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 3501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 3511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl asr(rd, rn, shift); 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Asr(const Register& rd, const Register& rn, const Register& rm) { 3551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 3561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 3571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 3581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl asrv(rd, rn, rm); 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 3611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Branch type inversion relies on these relations. 3631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_STATIC_ASSERT((reg_zero == (reg_not_zero ^ 1)) && 3641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl (reg_bit_clear == (reg_bit_set ^ 1)) && 3651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl (always == (never ^ 1))); 3661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl BranchType InvertBranchType(BranchType type) { 3681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) { 3691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl return static_cast<BranchType>( 3701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl InvertCondition(static_cast<Condition>(type))); 3711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 3721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl return static_cast<BranchType>(type ^ 1); 3731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1); 3771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 378578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void B(Label* label) { 379578645f14e122d2b87d907e298cda7e7d0babf1farmvixl b(label); 380578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 381578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void B(Label* label, Condition cond) { 3821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 3831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl b(label, cond); 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 3861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void B(Condition cond, Label* label) { 3871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl B(label, cond); 3881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Bfi(const Register& rd, 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 3931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 3941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 3951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bfi(rd, rn, lsb, width); 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Bfxil(const Register& rd, 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 4021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bfxil(rd, rn, lsb, width); 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Bind(Label* label) { 4081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bind(label); 410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Bl(Label* label) { 4121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bl(label); 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Blr(const Register& xn) { 4161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xn.IsZero()); 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl blr(xn); 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Br(const Register& xn) { 4211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xn.IsZero()); 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl br(xn); 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Brk(int code = 0) { 4261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl brk(code); 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cbnz(const Register& rt, Label* label) { 4301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cbnz(rt, label); 433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cbz(const Register& rt, Label* label) { 4351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cbz(rt, label); 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cinc(const Register& rd, const Register& rn, Condition cond) { 4401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cinc(rd, rn, cond); 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cinv(const Register& rd, const Register& rn, Condition cond) { 4461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cinv(rd, rn, cond); 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cls(const Register& rd, const Register& rn) { 4521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cls(rd, rn); 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Clz(const Register& rd, const Register& rn) { 4581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl clz(rd, rn); 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cneg(const Register& rd, const Register& rn, Condition cond) { 4641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cneg(rd, rn, cond); 468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Cset(const Register& rd, Condition cond) { 4701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cset(rd, cond); 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Csetm(const Register& rd, Condition cond) { 4751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl csetm(rd, cond); 478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Csinc(const Register& rd, 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond) { 4831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 4861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 4871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl csinc(rd, rn, rm, cond); 489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Csinv(const Register& rd, 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond) { 4941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 4951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 4961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 4971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 4981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl csinv(rd, rn, rm, cond); 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Csneg(const Register& rd, 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond) { 5051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 5071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 5081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 5091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl csneg(rd, rn, rm, cond); 511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 512f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Dmb(BarrierDomain domain, BarrierType type) { 5131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 514f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl dmb(domain, type); 515f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 516f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Dsb(BarrierDomain domain, BarrierType type) { 5171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 518f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl dsb(domain, type); 519f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Extr(const Register& rd, 521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb) { 5241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 5261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 5271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl extr(rd, rn, rm, lsb); 529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fabs(const FPRegister& fd, const FPRegister& fn) { 5311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fabs(fd, fn); 533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 5351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fadd(fd, fn, fm); 537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fccmp(const FPRegister& fn, 539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fm, 540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl StatusFlags nzcv, 541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond) { 5421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fccmp(fn, fm, nzcv, cond); 545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcmp(const FPRegister& fn, const FPRegister& fm) { 5471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcmp(fn, fm); 549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 5501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Fcmp(const FPRegister& fn, double value); 551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcsel(const FPRegister& fd, 552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fn, 553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fm, 554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Condition cond) { 5551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((cond != al) && (cond != nv)); 557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcsel(fd, fn, fm, cond); 558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 559578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void Fcvt(const FPRegister& fd, const FPRegister& fn) { 5601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 561578645f14e122d2b87d907e298cda7e7d0babf1farmvixl fcvt(fd, fn); 562578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 563f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fcvtas(const Register& rd, const FPRegister& fn) { 5641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 566f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fcvtas(rd, fn); 567f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 568f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fcvtau(const Register& rd, const FPRegister& fn) { 5691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 571f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fcvtau(rd, fn); 572f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtms(const Register& rd, const FPRegister& fn) { 5741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtms(rd, fn); 577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtmu(const Register& rd, const FPRegister& fn) { 5791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtmu(rd, fn); 582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtns(const Register& rd, const FPRegister& fn) { 5841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtns(rd, fn); 587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtnu(const Register& rd, const FPRegister& fn) { 5891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtnu(rd, fn); 592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtzs(const Register& rd, const FPRegister& fn) { 5941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 5951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtzs(rd, fn); 597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fcvtzu(const Register& rd, const FPRegister& fn) { 5991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 6001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fcvtzu(rd, fn); 602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 6041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fdiv(fd, fn, fm); 606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 6081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmax(fd, fn, fm); 610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 611f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fmaxnm(const FPRegister& fd, 612f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fn, 613f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fm) { 6141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 615f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fmaxnm(fd, fn, fm); 616f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 6181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmin(fd, fn, fm); 620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 621f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fminnm(const FPRegister& fd, 622f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fn, 623f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fm) { 6241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 625f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fminnm(fd, fn, fm); 626f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmov(FPRegister fd, FPRegister fn) { 6281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only emit an instruction if fd and fn are different, and they are both D 630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers. fmov(s0, s0) is not a no-op because it clears the top word of 631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // d0. Technically, fmov(d0, d0) is not a no-op either because it clears 632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // the top of q0, but FPRegister does not currently support Q registers. 633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!fd.Is(fn) || !fd.Is64Bits()) { 634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmov(fd, fn); 635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmov(FPRegister fd, Register rn) { 6381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 6391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmov(fd, rn); 641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 6421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Provide explicit double and float interfaces for FP immediate moves, rather 6431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // than relying on implicit C++ casts. This allows signalling NaNs to be 6441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // preserved when the immediate matches the format of fd. Most systems convert 6451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // signalling NaNs to quiet NaNs when converting between float and double. 6461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Fmov(FPRegister fd, double imm); 6471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Fmov(FPRegister fd, float imm); 6481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Provide a template to allow other types to be converted automatically. 6491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template<typename T> 6501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Fmov(FPRegister fd, T imm) { 6511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 6521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Fmov(fd, static_cast<double>(imm)); 653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmov(Register rd, FPRegister fn) { 6551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 6561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmov(rd, fn); 658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 6601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmul(fd, fn, fm); 662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 663f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fmadd(const FPRegister& fd, 664f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fn, 665f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fm, 666f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fa) { 6671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 668f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fmadd(fd, fn, fm, fa); 669f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fmsub(const FPRegister& fd, 671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fn, 672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fm, 673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fa) { 6741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fmsub(fd, fn, fm, fa); 676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 677f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fnmadd(const FPRegister& fd, 678f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fn, 679f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fm, 680f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fa) { 6811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 682f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fnmadd(fd, fn, fm, fa); 683f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 684f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Fnmsub(const FPRegister& fd, 685f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fn, 686f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fm, 687f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FPRegister& fa) { 6881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 689f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fnmsub(fd, fn, fm, fa); 690f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fneg(const FPRegister& fd, const FPRegister& fn) { 6921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 693ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fneg(fd, fn); 694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 695f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Frinta(const FPRegister& fd, const FPRegister& fn) { 6961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 697f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl frinta(fd, fn); 698f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 699ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl void Frintm(const FPRegister& fd, const FPRegister& fn) { 700ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(allow_macro_instructions_); 701ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl frintm(fd, fn); 702ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Frintn(const FPRegister& fd, const FPRegister& fn) { 7041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl frintn(fd, fn); 706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Frintz(const FPRegister& fd, const FPRegister& fn) { 7081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl frintz(fd, fn); 710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fsqrt(const FPRegister& fd, const FPRegister& fn) { 7121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fsqrt(fd, fn); 714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm) { 7161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fsub(fd, fn, fm); 718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Hint(SystemHint code) { 7201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl hint(code); 722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Hlt(int code) { 7241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl hlt(code); 726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 727f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Isb() { 7281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 729f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl isb(); 730f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ldnp(const CPURegister& rt, 732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& rt2, 733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const MemOperand& src) { 7341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ldnp(rt, rt2, src); 736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ldp(const CPURegister& rt, 738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& rt2, 739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const MemOperand& src) { 7401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ldp(rt, rt2, src); 742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ldpsw(const Register& rt, const Register& rt2, const MemOperand& src) { 7441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ldpsw(rt, rt2, src); 746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 7471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Provide both double and float interfaces for FP immediate loads, rather 7481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // than relying on implicit C++ casts. This allows signalling NaNs to be 7491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // preserved when the immediate matches the format of fd. Most systems convert 7501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // signalling NaNs to quiet NaNs when converting between float and double. 751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ldr(const FPRegister& ft, double imm) { 7521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (ft.Is64Bits()) { 7541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ldr(ft, imm); 7551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 7561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ldr(ft, static_cast<float>(imm)); 7571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 7581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 7591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Ldr(const FPRegister& ft, float imm) { 7601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (ft.Is32Bits()) { 7621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ldr(ft, imm); 7631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 7641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ldr(ft, static_cast<double>(imm)); 7651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ldr(const Register& rt, uint64_t imm) { 7681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ldr(rt, imm); 771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Lsl(const Register& rd, const Register& rn, unsigned shift) { 7731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 7751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl lsl(rd, rn, shift); 777ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Lsl(const Register& rd, const Register& rn, const Register& rm) { 7791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 7811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 7821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl lslv(rd, rn, rm); 784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Lsr(const Register& rd, const Register& rn, unsigned shift) { 7861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 7881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl lsr(rd, rn, shift); 790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Lsr(const Register& rd, const Register& rn, const Register& rm) { 7921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 7931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 7941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 7951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl lsrv(rd, rn, rm); 797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Madd(const Register& rd, 799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 8021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 8051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 8061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl madd(rd, rn, rm, ra); 808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mneg(const Register& rd, const Register& rn, const Register& rm) { 8101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 8131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 814ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mneg(rd, rn, rm); 815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mov(const Register& rd, const Register& rn) { 8171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mov(rd, rn); 819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 820f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Movk(const Register& rd, uint64_t imm, int shift = -1) { 8211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 823f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl movk(rd, imm, shift); 824f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mrs(const Register& rt, SystemRegister sysreg) { 8261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mrs(rt, sysreg); 829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Msr(SystemRegister sysreg, const Register& rt) { 8311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl msr(sysreg, rt); 834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Msub(const Register& rd, 836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 8391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 8421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 8431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl msub(rd, rn, rm, ra); 845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Mul(const Register& rd, const Register& rn, const Register& rm) { 8471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 8501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mul(rd, rn, rm); 852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Nop() { 8541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl nop(); 856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Rbit(const Register& rd, const Register& rn) { 8581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl rbit(rd, rn); 862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ret(const Register& xn = lr) { 8641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xn.IsZero()); 866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ret(xn); 867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Rev(const Register& rd, const Register& rn) { 8691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl rev(rd, rn); 873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Rev16(const Register& rd, const Register& rn) { 8751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl rev16(rd, rn); 879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Rev32(const Register& rd, const Register& rn) { 8811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl rev32(rd, rn); 885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 886ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ror(const Register& rd, const Register& rs, unsigned shift) { 8871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rs.IsZero()); 890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ror(rd, rs, shift); 891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ror(const Register& rd, const Register& rn, const Register& rm) { 8931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 8941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 8951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 8961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl rorv(rd, rn, rm); 898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sbfiz(const Register& rd, 900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 9031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sbfiz(rd, rn, lsb, width); 907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sbfx(const Register& rd, 909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 9121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sbfx(rd, rn, lsb, width); 916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 917ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) { 9181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl scvtf(fd, rn, fbits); 921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sdiv(const Register& rd, const Register& rn, const Register& rm) { 9231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 9261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sdiv(rd, rn, rm); 928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Smaddl(const Register& rd, 930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 9331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 9361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 9371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl smaddl(rd, rn, rm, ra); 939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Smsubl(const Register& rd, 941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 9441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 9471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 9481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl smsubl(rd, rn, rm, ra); 950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Smull(const Register& rd, const Register& rn, const Register& rm) { 9521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 9551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl smull(rd, rn, rm); 957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Smulh(const Register& xd, const Register& xn, const Register& xm) { 9591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xd.IsZero()); 9611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xn.IsZero()); 9621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!xm.IsZero()); 963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl smulh(xd, xn, xm); 964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Stnp(const CPURegister& rt, 966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& rt2, 967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const MemOperand& dst) { 9681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl stnp(rt, rt2, dst); 970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Stp(const CPURegister& rt, 972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& rt2, 973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const MemOperand& dst) { 9741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl stp(rt, rt2, dst); 976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sxtb(const Register& rd, const Register& rn) { 9781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sxtb(rd, rn); 982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sxth(const Register& rd, const Register& rn) { 9841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sxth(rd, rn); 988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Sxtw(const Register& rd, const Register& rn) { 9901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 9921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sxtw(rd, rn); 994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Tbnz(const Register& rt, unsigned bit_pos, Label* label) { 9961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 9971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl tbnz(rt, bit_pos, label); 999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Tbz(const Register& rt, unsigned bit_pos, Label* label) { 10011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rt.IsZero()); 1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl tbz(rt, bit_pos, label); 1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ubfiz(const Register& rd, 1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 10091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ubfiz(rd, rn, lsb, width); 1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ubfx(const Register& rd, 1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned lsb, 1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned width) { 10181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ubfx(rd, rn, lsb, width); 1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0) { 10241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ucvtf(fd, rn, fbits); 1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Udiv(const Register& rd, const Register& rn, const Register& rm) { 10291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 10321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 1033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl udiv(rd, rn, rm); 1034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Umaddl(const Register& rd, 1036ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 1037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 1038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 10391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 10421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 10431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl umaddl(rd, rn, rm, ra); 1045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Umsubl(const Register& rd, 1047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rn, 1048ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& rm, 1049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& ra) { 10501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 10531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rm.IsZero()); 10541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!ra.IsZero()); 1055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl umsubl(rd, rn, rm, ra); 1056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Unreachable() { 10581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef USE_SIMULATOR 1060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl hlt(kUnreachableOpcode); 1061ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#else 1062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Branch to 0 to generate a segfault. 1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // lr - kInstructionSize is the address of the offending instruction. 1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl blr(xzr); 1065ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Uxtb(const Register& rd, const Register& rn) { 10681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uxtb(rd, rn); 1072ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Uxth(const Register& rd, const Register& rn) { 10741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uxth(rd, rn); 1078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Uxtw(const Register& rd, const Register& rn) { 10801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(allow_macro_instructions_); 10811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rd.IsZero()); 10821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!rn.IsZero()); 1083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uxtw(rd, rn); 1084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1085ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1086ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Push the system stack pointer (sp) down to allow the same to be done to 1087ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // the current stack pointer (according to StackPointer()). This must be 1088ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // called _before_ accessing the memory. 1089ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1090ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This is necessary when pushing or otherwise adding things to the stack, to 1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // satisfy the AAPCS64 constraint that the memory below the system stack 1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // pointer is not accessed. 1093ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1094ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This method asserts that StackPointer() is not sp, since the call does 1095ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // not make sense in that context. 1096ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // TODO: This method can only accept values of 'space' that can be encoded in 1098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // one instruction. Refer to the implementation for details. 1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void BumpSystemStackPointer(const Operand& space); 1100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#if DEBUG 1102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void SetAllowMacroInstructions(bool value) { 1103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl allow_macro_instructions_ = value; 1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool AllowMacroInstructions() const { 1107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return allow_macro_instructions_; 1108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Set the current stack pointer, but don't generate any code. 1112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void SetStackPointer(const Register& stack_pointer) { 11131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(!TmpList()->IncludesAliasOf(stack_pointer)); 1114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sp_ = stack_pointer; 1115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Return the current stack pointer, as set by SetStackPointer. 1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& StackPointer() const { 1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return sp_; 1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 11221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList* TmpList() { return &tmp_list_; } 11231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList* FPTmpList() { return &fptmp_list_; } 1124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Like printf, but print at run-time from generated code. 1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The caller must ensure that arguments for floating-point placeholders 1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // (such as %e, %f or %g) are FPRegisters, and that arguments for integer 1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // placeholders are Registers. 1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1131ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // At the moment it is only possible to print the value of sp if it is the 1132ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // current stack pointer. Otherwise, the MacroAssembler will automatically 1133ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // update sp on every push (using BumpSystemStackPointer), so determining its 1134ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // value is difficult. 11351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // 1136ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Format placeholders that refer to more than one argument, or to a specific 1137ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // argument, are not supported. This includes formats like "%1$d" or "%.*d". 1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This function automatically preserves caller-saved registers so that 1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // calling code can use Printf at any point without having to worry about 1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // corruption. The preservation mechanism generates a lot of code. If this is 1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // a problem, preserve the important registers manually and then call 1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are 1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // implicitly preserved. 1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Printf(const char * format, 1146ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CPURegister arg0 = NoCPUReg, 1147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CPURegister arg1 = NoCPUReg, 1148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CPURegister arg2 = NoCPUReg, 1149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CPURegister arg3 = NoCPUReg); 1150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Like Printf, but don't preserve any caller-saved registers, not even 'lr'. 1152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The return code from the system printf call will be returned in x0. 1154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrintfNoPreserve(const char * format, 1155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& arg0 = NoCPUReg, 1156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& arg1 = NoCPUReg, 1157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& arg2 = NoCPUReg, 1158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& arg3 = NoCPUReg); 1159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Trace control when running the debug simulator. 1161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // For example: 1163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // __ Trace(LOG_REGS, TRACE_ENABLE); 1165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Will add registers to the trace if it wasn't already the case. 1166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // __ Trace(LOG_DISASM, TRACE_DISABLE); 1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Will stop logging disassembly. It has no effect if the disassembly wasn't 1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // already being logged. 1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Trace(TraceParameters parameters, TraceCommand command); 1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Log the requested data independently of what is being traced. 1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // For example: 1175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // __ Log(LOG_FLAGS) 1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Will output the flags. 1178578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void Log(TraceParameters parameters); 1179578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 1180578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Enable or disable instrumentation when an Instrument visitor is attached to 1181578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // the simulator. 1182578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void EnableInstrumentation(); 1183578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void DisableInstrumentation(); 1184578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 1185578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Add a marker to the instrumentation data produced by an Instrument visitor. 1186578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // The name is a two character string that will be attached to the marker in 1187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // the output data. 1188578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void AnnotateInstrumentation(const char* marker_name); 1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The actual Push and Pop implementations. These don't generate any code 1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // other than that required for the push or pop. This allows 1193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // (Push|Pop)CPURegList to bundle together setup code for a large block of 1194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers. 1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Note that size is per register, and is specified in bytes. 1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PushHelper(int count, int size, 1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& src0, const CPURegister& src1, 1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& src2, const CPURegister& src3); 1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PopHelper(int count, int size, 1201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& dst0, const CPURegister& dst1, 1202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const CPURegister& dst2, const CPURegister& dst3); 1203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Perform necessary maintenance operations before a push or pop. 1205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 1206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Note that size is per register, and is specified in bytes. 1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrepareForPush(int count, int size); 1208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrepareForPop(int count, int size); 1209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#if DEBUG 1211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Tell whether any of the macro instruction can be used. When false the 1212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // MacroAssembler will assert if a method which can emit a variable number 1213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // of instructions is called. 1214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool allow_macro_instructions_; 1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The register to use as a stack pointer for stack operations. 1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register sp_; 1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 12201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Scratch registers available for use by the MacroAssembler. 12211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList tmp_list_; 12221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList fptmp_list_; 1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 1224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Use this scope when you need a one-to-one mapping between methods and 1227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// instructions. This scope prevents the MacroAssembler from being called and 1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// literal pools from being emitted. It also asserts the number of instructions 1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// emitted is what you specified when creating the scope. 1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass InstructionAccurateScope { 1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 1232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit InstructionAccurateScope(MacroAssembler* masm) 12338fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu : masm_(masm) { 1234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->BlockLiteralPool(); 1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG 12368fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu size_ = 0; 1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl old_allow_macro_instructions_ = masm_->AllowMacroInstructions(); 1238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->SetAllowMacroInstructions(false); 1239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl InstructionAccurateScope(MacroAssembler* masm, int count) 12438fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu : masm_(masm) { 12448fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu USE(count); 1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->BlockLiteralPool(); 1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG 12478fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu size_ = count * kInstructionSize; 1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->bind(&start_); 1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl old_allow_macro_instructions_ = masm_->AllowMacroInstructions(); 1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->SetAllowMacroInstructions(false); 1251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ~InstructionAccurateScope() { 1255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->ReleaseLiteralPool(); 1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG 1257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (start_.IsBound()) { 12581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(masm_->SizeOfCodeGeneratedSince(&start_) == size_); 1259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm_->SetAllowMacroInstructions(old_allow_macro_instructions_); 1261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 1265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MacroAssembler* masm_; 12669b9674a6dd7b5f23d73a5432b74affe4bc380c31Serban Constantinescu#ifdef DEBUG 12678fcae179b1449176c5780eb0ba57f75654ec4c80Serban Constantinescu uint64_t size_; 1268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label start_; 1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool old_allow_macro_instructions_; 1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif 1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 12741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// This scope utility allows scratch registers to be managed safely. The 12751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch 12761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// registers. These registers can be allocated on demand, and will be returned 12771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// at the end of the scope. 12781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 12791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// When the scope ends, the MacroAssembler's lists will be restored to their 12801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// original state, even if the lists were modified by some other means. 12811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlclass UseScratchRegisterScope { 12821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl public: 12831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl explicit UseScratchRegisterScope(MacroAssembler* masm) 12841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl : available_(masm->TmpList()), 12851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl availablefp_(masm->FPTmpList()), 12861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl old_available_(available_->list()), 12871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl old_availablefp_(availablefp_->list()) { 12881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(available_->type() == CPURegister::kRegister); 12891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(availablefp_->type() == CPURegister::kFPRegister); 12901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 12911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 12921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 12931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ~UseScratchRegisterScope(); 12941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 12951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1296ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bool IsAvailable(const CPURegister& reg) const; 1297ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 1298ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 12991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Take a register from the appropriate temps list. It will be returned 13001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // automatically when the scope ends. 13011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register AcquireW() { return AcquireNextAvailable(available_).W(); } 13021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register AcquireX() { return AcquireNextAvailable(available_).X(); } 13031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); } 13041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); } 13051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register AcquireSameSizeAs(const Register& reg); 13081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister AcquireSameSizeAs(const FPRegister& reg); 13091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Explicitly release an acquired (or excluded) register, putting it back in 13121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // the appropriate temps list. 13131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Release(const CPURegister& reg); 13141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Make the specified registers available as scratch registers for the 13171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // duration of this scope. 1318ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl void Include(const CPURegList& list); 13191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Include(const Register& reg1, 13201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg2 = NoReg, 13211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg3 = NoReg, 13221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg4 = NoReg); 13231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Include(const FPRegister& reg1, 13241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg2 = NoFPReg, 13251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg3 = NoFPReg, 13261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg4 = NoFPReg); 13271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Make sure that the specified registers are not available in this scope. 13301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // This can be used to prevent helper functions from using sensitive 13311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // registers, for example. 1332ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl void Exclude(const CPURegList& list); 13331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Exclude(const Register& reg1, 13341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg2 = NoReg, 13351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg3 = NoReg, 13361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const Register& reg4 = NoReg); 13371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Exclude(const FPRegister& reg1, 13381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg2 = NoFPReg, 13391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg3 = NoFPReg, 13401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& reg4 = NoFPReg); 13411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void Exclude(const CPURegister& reg1, 13421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const CPURegister& reg2 = NoCPUReg, 13431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const CPURegister& reg3 = NoCPUReg, 13441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const CPURegister& reg4 = NoCPUReg); 13451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Prevent any scratch registers from being used in this scope. 13481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void ExcludeAll(); 13491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl private: 13521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl static CPURegister AcquireNextAvailable(CPURegList* available); 13531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl static void ReleaseByCode(CPURegList* available, int code); 13551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl static void ReleaseByRegList(CPURegList* available, 13571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RegList regs); 13581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl static void IncludeByRegList(CPURegList* available, 13601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RegList exclude); 13611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl static void ExcludeByRegList(CPURegList* available, 13631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RegList exclude); 13641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Available scratch registers. 13661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList* available_; // kRegister 13671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPURegList* availablefp_; // kFPRegister 13681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // The state of the available lists at the start of this scope. 13701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RegList old_available_; // kRegister 13711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RegList old_availablefp_; // kFPRegister 13721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl}; 13731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 13741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif // VIXL_A64_MACRO_ASSEMBLER_A64_H_ 1378