1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_UTILS_ASSEMBLER_TEST_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_UTILS_ASSEMBLER_TEST_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "assembler.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include <sys/stat.h> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include <cstdio> 25*795d594fSAndroid Build Coastguard Worker #include <cstdlib> 26*795d594fSAndroid Build Coastguard Worker #include <fstream> 27*795d594fSAndroid Build Coastguard Worker #include <iterator> 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h" 30*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 31*795d594fSAndroid Build Coastguard Worker #include "base/malloc_arena_pool.h" 32*795d594fSAndroid Build Coastguard Worker #include "assembler_test_base.h" 33*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h" // For ScratchFile 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // Helper for a constexpr string length. 38*795d594fSAndroid Build Coastguard Worker constexpr size_t ConstexprStrLen(char const* str, size_t count = 0) { 39*795d594fSAndroid Build Coastguard Worker return ('\0' == str[0]) ? count : ConstexprStrLen(str+1, count+1); 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker enum class RegisterView { // private 43*795d594fSAndroid Build Coastguard Worker kUsePrimaryName, 44*795d594fSAndroid Build Coastguard Worker kUseSecondaryName, 45*795d594fSAndroid Build Coastguard Worker kUseTertiaryName, 46*795d594fSAndroid Build Coastguard Worker kUseQuaternaryName, 47*795d594fSAndroid Build Coastguard Worker }; 48*795d594fSAndroid Build Coastguard Worker 49*795d594fSAndroid Build Coastguard Worker // For use in the template as the default type to get a nonvector registers version. 50*795d594fSAndroid Build Coastguard Worker struct NoVectorRegs {}; 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker template<typename Ass, 53*795d594fSAndroid Build Coastguard Worker typename Addr, 54*795d594fSAndroid Build Coastguard Worker typename Reg, 55*795d594fSAndroid Build Coastguard Worker typename FPReg, 56*795d594fSAndroid Build Coastguard Worker typename Imm, 57*795d594fSAndroid Build Coastguard Worker typename VecReg = NoVectorRegs> 58*795d594fSAndroid Build Coastguard Worker class AssemblerTest : public AssemblerTestBase { 59*795d594fSAndroid Build Coastguard Worker public: GetAssembler()60*795d594fSAndroid Build Coastguard Worker Ass* GetAssembler() { 61*795d594fSAndroid Build Coastguard Worker return assembler_.get(); 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker using TestFn = std::string (*)(AssemblerTest *, Ass *); 65*795d594fSAndroid Build Coastguard Worker DriverFn(TestFn f,const std::string & test_name)66*795d594fSAndroid Build Coastguard Worker void DriverFn(TestFn f, const std::string& test_name) { 67*795d594fSAndroid Build Coastguard Worker DriverWrapper(f(this, assembler_.get()), test_name); 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker // This driver assumes the assembler has already been called. DriverStr(const std::string & assembly_string,const std::string & test_name)71*795d594fSAndroid Build Coastguard Worker void DriverStr(const std::string& assembly_string, const std::string& test_name) { 72*795d594fSAndroid Build Coastguard Worker DriverWrapper(assembly_string, test_name); 73*795d594fSAndroid Build Coastguard Worker } 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker // 76*795d594fSAndroid Build Coastguard Worker // Register repeats. 77*795d594fSAndroid Build Coastguard Worker // 78*795d594fSAndroid Build Coastguard Worker RepeatR(void (Ass::* f)(Reg),const std::string & fmt)79*795d594fSAndroid Build Coastguard Worker std::string RepeatR(void (Ass::*f)(Reg), const std::string& fmt) { 80*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegister<Reg>(f, 81*795d594fSAndroid Build Coastguard Worker GetRegisters(), 82*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 83*795d594fSAndroid Build Coastguard Worker fmt); 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker Repeatr(void (Ass::* f)(Reg),const std::string & fmt)86*795d594fSAndroid Build Coastguard Worker std::string Repeatr(void (Ass::*f)(Reg), const std::string& fmt) { 87*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegister<Reg>(f, 88*795d594fSAndroid Build Coastguard Worker GetRegisters(), 89*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 90*795d594fSAndroid Build Coastguard Worker fmt); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker std::string RepeatRR(void (Ass::*f)(Reg, Reg), 94*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 95*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 96*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 97*795d594fSAndroid Build Coastguard Worker GetRegisters(), 98*795d594fSAndroid Build Coastguard Worker GetRegisters(), 99*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 100*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 101*795d594fSAndroid Build Coastguard Worker fmt, 102*795d594fSAndroid Build Coastguard Worker except); 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker RepeatRRNoDupes(void (Ass::* f)(Reg,Reg),const std::string & fmt)105*795d594fSAndroid Build Coastguard Worker std::string RepeatRRNoDupes(void (Ass::*f)(Reg, Reg), const std::string& fmt) { 106*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersNoDupes<Reg, Reg>(f, 107*795d594fSAndroid Build Coastguard Worker GetRegisters(), 108*795d594fSAndroid Build Coastguard Worker GetRegisters(), 109*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 110*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 111*795d594fSAndroid Build Coastguard Worker fmt); 112*795d594fSAndroid Build Coastguard Worker } 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker std::string Repeatrr(void (Ass::*f)(Reg, Reg), 115*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 116*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 117*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 118*795d594fSAndroid Build Coastguard Worker GetRegisters(), 119*795d594fSAndroid Build Coastguard Worker GetRegisters(), 120*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 121*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 122*795d594fSAndroid Build Coastguard Worker fmt, 123*795d594fSAndroid Build Coastguard Worker except); 124*795d594fSAndroid Build Coastguard Worker } 125*795d594fSAndroid Build Coastguard Worker 126*795d594fSAndroid Build Coastguard Worker std::string Repeatww(void (Ass::*f)(Reg, Reg), 127*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 128*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 129*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 130*795d594fSAndroid Build Coastguard Worker GetRegisters(), 131*795d594fSAndroid Build Coastguard Worker GetRegisters(), 132*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseTertiaryName>, 133*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseTertiaryName>, 134*795d594fSAndroid Build Coastguard Worker fmt, 135*795d594fSAndroid Build Coastguard Worker except); 136*795d594fSAndroid Build Coastguard Worker } 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker std::string Repeatbb(void (Ass::*f)(Reg, Reg), 139*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 140*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 141*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 142*795d594fSAndroid Build Coastguard Worker GetRegisters(), 143*795d594fSAndroid Build Coastguard Worker GetRegisters(), 144*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseQuaternaryName>, 145*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseQuaternaryName>, 146*795d594fSAndroid Build Coastguard Worker fmt, 147*795d594fSAndroid Build Coastguard Worker except); 148*795d594fSAndroid Build Coastguard Worker } 149*795d594fSAndroid Build Coastguard Worker RepeatRRR(void (Ass::* f)(Reg,Reg,Reg),const std::string & fmt)150*795d594fSAndroid Build Coastguard Worker std::string RepeatRRR(void (Ass::*f)(Reg, Reg, Reg), const std::string& fmt) { 151*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg, Reg>(f, 152*795d594fSAndroid Build Coastguard Worker GetRegisters(), 153*795d594fSAndroid Build Coastguard Worker GetRegisters(), 154*795d594fSAndroid Build Coastguard Worker GetRegisters(), 155*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 156*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 157*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 158*795d594fSAndroid Build Coastguard Worker fmt); 159*795d594fSAndroid Build Coastguard Worker } 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker std::string Repeatrb(void (Ass::*f)(Reg, Reg), 162*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 163*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 164*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 165*795d594fSAndroid Build Coastguard Worker GetRegisters(), 166*795d594fSAndroid Build Coastguard Worker GetRegisters(), 167*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 168*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseQuaternaryName>, 169*795d594fSAndroid Build Coastguard Worker fmt, 170*795d594fSAndroid Build Coastguard Worker except); 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker 173*795d594fSAndroid Build Coastguard Worker std::string RepeatRr(void (Ass::*f)(Reg, Reg), 174*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 175*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg, Reg>>* except = nullptr) { 176*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, Reg>(f, 177*795d594fSAndroid Build Coastguard Worker GetRegisters(), 178*795d594fSAndroid Build Coastguard Worker GetRegisters(), 179*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 180*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 181*795d594fSAndroid Build Coastguard Worker fmt, 182*795d594fSAndroid Build Coastguard Worker except); 183*795d594fSAndroid Build Coastguard Worker } 184*795d594fSAndroid Build Coastguard Worker RepeatRI(void (Ass::* f)(Reg,const Imm &),size_t imm_bytes,const std::string & fmt)185*795d594fSAndroid Build Coastguard Worker std::string RepeatRI(void (Ass::*f)(Reg, const Imm&), size_t imm_bytes, const std::string& fmt) { 186*795d594fSAndroid Build Coastguard Worker return RepeatRegisterImm<RegisterView::kUsePrimaryName>(f, imm_bytes, fmt); 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker RepeatrI(void (Ass::* f)(Reg,const Imm &),size_t imm_bytes,const std::string & fmt)189*795d594fSAndroid Build Coastguard Worker std::string RepeatrI(void (Ass::*f)(Reg, const Imm&), size_t imm_bytes, const std::string& fmt) { 190*795d594fSAndroid Build Coastguard Worker return RepeatRegisterImm<RegisterView::kUseSecondaryName>(f, imm_bytes, fmt); 191*795d594fSAndroid Build Coastguard Worker } 192*795d594fSAndroid Build Coastguard Worker RepeatwI(void (Ass::* f)(Reg,const Imm &),size_t imm_bytes,const std::string & fmt)193*795d594fSAndroid Build Coastguard Worker std::string RepeatwI(void (Ass::*f)(Reg, const Imm&), size_t imm_bytes, const std::string& fmt) { 194*795d594fSAndroid Build Coastguard Worker return RepeatRegisterImm<RegisterView::kUseTertiaryName>(f, imm_bytes, fmt); 195*795d594fSAndroid Build Coastguard Worker } 196*795d594fSAndroid Build Coastguard Worker RepeatbI(void (Ass::* f)(Reg,const Imm &),size_t imm_bytes,const std::string & fmt)197*795d594fSAndroid Build Coastguard Worker std::string RepeatbI(void (Ass::*f)(Reg, const Imm&), size_t imm_bytes, const std::string& fmt) { 198*795d594fSAndroid Build Coastguard Worker return RepeatRegisterImm<RegisterView::kUseQuaternaryName>(f, imm_bytes, fmt); 199*795d594fSAndroid Build Coastguard Worker } 200*795d594fSAndroid Build Coastguard Worker 201*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2, typename ImmType> 202*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegistersImmBits(void (Ass::*f)(Reg1, Reg2, ImmType), 203*795d594fSAndroid Build Coastguard Worker int imm_bits, 204*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 205*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 206*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 207*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 208*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 209*795d594fSAndroid Build Coastguard Worker int bias = 0, 210*795d594fSAndroid Build Coastguard Worker int multiplier = 1) { 211*795d594fSAndroid Build Coastguard Worker std::string str; 212*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0)); 213*795d594fSAndroid Build Coastguard Worker 214*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 215*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 216*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 217*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 218*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 219*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, new_imm * multiplier + bias); 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 222*795d594fSAndroid Build Coastguard Worker 223*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 224*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 225*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, multiplier, &base); 226*795d594fSAndroid Build Coastguard Worker 227*795d594fSAndroid Build Coastguard Worker str += base; 228*795d594fSAndroid Build Coastguard Worker str += "\n"; 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker } 231*795d594fSAndroid Build Coastguard Worker } 232*795d594fSAndroid Build Coastguard Worker return str; 233*795d594fSAndroid Build Coastguard Worker } 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2, typename Reg3, typename ImmType> RepeatTemplatedRegistersImmBits(void (Ass::* f)(Reg1,Reg2,Reg3,ImmType),int imm_bits,ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,ArrayRef<const Reg3> reg3_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),std::string (AssemblerTest::* GetName3)(const Reg3 &),const std::string & fmt,int bias)236*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegistersImmBits(void (Ass::*f)(Reg1, Reg2, Reg3, ImmType), 237*795d594fSAndroid Build Coastguard Worker int imm_bits, 238*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 239*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 240*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg3> reg3_registers, 241*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 242*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 243*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName3)(const Reg3&), 244*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 245*795d594fSAndroid Build Coastguard Worker int bias) { 246*795d594fSAndroid Build Coastguard Worker std::string str; 247*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0)); 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 250*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 251*795d594fSAndroid Build Coastguard Worker for (auto reg3 : reg3_registers) { 252*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 253*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 254*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 255*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, reg3, new_imm + bias); 256*795d594fSAndroid Build Coastguard Worker } 257*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 258*795d594fSAndroid Build Coastguard Worker 259*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 260*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 261*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG3_TOKEN, (this->*GetName3)(reg3), &base); 262*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, /*multiplier=*/ 1, &base); 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker str += base; 265*795d594fSAndroid Build Coastguard Worker str += "\n"; 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker } 268*795d594fSAndroid Build Coastguard Worker } 269*795d594fSAndroid Build Coastguard Worker } 270*795d594fSAndroid Build Coastguard Worker return str; 271*795d594fSAndroid Build Coastguard Worker } 272*795d594fSAndroid Build Coastguard Worker 273*795d594fSAndroid Build Coastguard Worker template <typename ImmType, typename Reg1, typename Reg2> RepeatTemplatedImmBitsRegisters(void (Ass::* f)(ImmType,Reg1,Reg2),ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),int imm_bits,const std::string & fmt)274*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedImmBitsRegisters(void (Ass::*f)(ImmType, Reg1, Reg2), 275*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 276*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 277*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 278*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 279*795d594fSAndroid Build Coastguard Worker int imm_bits, 280*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 281*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0)); 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * imms.size()); 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker std::string str; 286*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 287*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 288*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 289*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 290*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 291*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(new_imm, reg1, reg2); 292*795d594fSAndroid Build Coastguard Worker } 293*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 296*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 297*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, /*bias=*/ 0, /*multiplier=*/ 1, &base); 298*795d594fSAndroid Build Coastguard Worker 299*795d594fSAndroid Build Coastguard Worker str += base; 300*795d594fSAndroid Build Coastguard Worker str += "\n"; 301*795d594fSAndroid Build Coastguard Worker } 302*795d594fSAndroid Build Coastguard Worker } 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker return str; 305*795d594fSAndroid Build Coastguard Worker } 306*795d594fSAndroid Build Coastguard Worker 307*795d594fSAndroid Build Coastguard Worker template <typename RegType, typename ImmType> RepeatTemplatedRegisterImmBits(void (Ass::* f)(RegType,ImmType),int imm_bits,ArrayRef<const RegType> registers,std::string (AssemblerTest::* GetName)(const RegType &),const std::string & fmt,int bias)308*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegisterImmBits(void (Ass::*f)(RegType, ImmType), 309*795d594fSAndroid Build Coastguard Worker int imm_bits, 310*795d594fSAndroid Build Coastguard Worker ArrayRef<const RegType> registers, 311*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName)(const RegType&), 312*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 313*795d594fSAndroid Build Coastguard Worker int bias) { 314*795d594fSAndroid Build Coastguard Worker std::string str; 315*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0)); 316*795d594fSAndroid Build Coastguard Worker 317*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 318*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 319*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 320*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 321*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg, new_imm + bias); 322*795d594fSAndroid Build Coastguard Worker } 323*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, (this->*GetName)(reg), &base); 326*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, /*multiplier=*/ 1, &base); 327*795d594fSAndroid Build Coastguard Worker 328*795d594fSAndroid Build Coastguard Worker str += base; 329*795d594fSAndroid Build Coastguard Worker str += "\n"; 330*795d594fSAndroid Build Coastguard Worker } 331*795d594fSAndroid Build Coastguard Worker } 332*795d594fSAndroid Build Coastguard Worker return str; 333*795d594fSAndroid Build Coastguard Worker } 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker template <typename RegType, typename ImmType> RepeatTemplatedRegisterImmBitsShift(void (Ass::* f)(RegType,ImmType),int imm_bits,int shift,ArrayRef<const RegType> registers,std::string (AssemblerTest::* GetName)(const RegType &),const std::string & fmt,int bias)336*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegisterImmBitsShift( 337*795d594fSAndroid Build Coastguard Worker void (Ass::*f)(RegType, ImmType), 338*795d594fSAndroid Build Coastguard Worker int imm_bits, 339*795d594fSAndroid Build Coastguard Worker int shift, 340*795d594fSAndroid Build Coastguard Worker ArrayRef<const RegType> registers, 341*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName)(const RegType&), 342*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 343*795d594fSAndroid Build Coastguard Worker int bias) { 344*795d594fSAndroid Build Coastguard Worker std::string str; 345*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); 346*795d594fSAndroid Build Coastguard Worker 347*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 348*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 349*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 350*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 351*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg, new_imm + bias); 352*795d594fSAndroid Build Coastguard Worker } 353*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 354*795d594fSAndroid Build Coastguard Worker 355*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, (this->*GetName)(reg), &base); 356*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, /*multiplier=*/ 1, &base); 357*795d594fSAndroid Build Coastguard Worker 358*795d594fSAndroid Build Coastguard Worker str += base; 359*795d594fSAndroid Build Coastguard Worker str += "\n"; 360*795d594fSAndroid Build Coastguard Worker } 361*795d594fSAndroid Build Coastguard Worker } 362*795d594fSAndroid Build Coastguard Worker return str; 363*795d594fSAndroid Build Coastguard Worker } 364*795d594fSAndroid Build Coastguard Worker 365*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 366*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedImmBitsShift( 367*795d594fSAndroid Build Coastguard Worker void (Ass::*f)(ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { 368*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); 369*795d594fSAndroid Build Coastguard Worker 370*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(imms.size()); 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker std::string str; 373*795d594fSAndroid Build Coastguard Worker 374*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 375*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 376*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 377*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(new_imm + bias); 378*795d594fSAndroid Build Coastguard Worker } 379*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 380*795d594fSAndroid Build Coastguard Worker 381*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, /*multiplier=*/ 1, &base); 382*795d594fSAndroid Build Coastguard Worker 383*795d594fSAndroid Build Coastguard Worker str += base; 384*795d594fSAndroid Build Coastguard Worker str += "\n"; 385*795d594fSAndroid Build Coastguard Worker } 386*795d594fSAndroid Build Coastguard Worker return str; 387*795d594fSAndroid Build Coastguard Worker } 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2, typename ImmType> 390*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegistersImmBitsShift( 391*795d594fSAndroid Build Coastguard Worker void (Ass::*f)(Reg1, Reg2, ImmType), 392*795d594fSAndroid Build Coastguard Worker int imm_bits, 393*795d594fSAndroid Build Coastguard Worker int shift, 394*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 395*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 396*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 397*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 398*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 399*795d594fSAndroid Build Coastguard Worker int bias = 0, 400*795d594fSAndroid Build Coastguard Worker int multiplier = 1) { 401*795d594fSAndroid Build Coastguard Worker std::string str; 402*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); 403*795d594fSAndroid Build Coastguard Worker 404*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 405*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 406*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 407*795d594fSAndroid Build Coastguard Worker ImmType new_imm = CreateImmediate(imm); 408*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 409*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, new_imm * multiplier + bias); 410*795d594fSAndroid Build Coastguard Worker } 411*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 412*795d594fSAndroid Build Coastguard Worker 413*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 414*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 415*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, bias, multiplier, &base); 416*795d594fSAndroid Build Coastguard Worker 417*795d594fSAndroid Build Coastguard Worker str += base; 418*795d594fSAndroid Build Coastguard Worker str += "\n"; 419*795d594fSAndroid Build Coastguard Worker } 420*795d594fSAndroid Build Coastguard Worker } 421*795d594fSAndroid Build Coastguard Worker } 422*795d594fSAndroid Build Coastguard Worker return str; 423*795d594fSAndroid Build Coastguard Worker } 424*795d594fSAndroid Build Coastguard Worker 425*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 426*795d594fSAndroid Build Coastguard Worker std::string RepeatIbS( 427*795d594fSAndroid Build Coastguard Worker void (Ass::*f)(ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { 428*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedImmBitsShift<ImmType>(f, imm_bits, shift, fmt, bias); 429*795d594fSAndroid Build Coastguard Worker } 430*795d594fSAndroid Build Coastguard Worker 431*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 432*795d594fSAndroid Build Coastguard Worker std::string RepeatRIbS( 433*795d594fSAndroid Build Coastguard Worker void (Ass::*f)(Reg, ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { 434*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisterImmBitsShift<Reg, ImmType>( 435*795d594fSAndroid Build Coastguard Worker f, 436*795d594fSAndroid Build Coastguard Worker imm_bits, 437*795d594fSAndroid Build Coastguard Worker shift, 438*795d594fSAndroid Build Coastguard Worker GetRegisters(), 439*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 440*795d594fSAndroid Build Coastguard Worker fmt, 441*795d594fSAndroid Build Coastguard Worker bias); 442*795d594fSAndroid Build Coastguard Worker } 443*795d594fSAndroid Build Coastguard Worker 444*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 445*795d594fSAndroid Build Coastguard Worker std::string RepeatRRIbS(void (Ass::*f)(Reg, Reg, ImmType), 446*795d594fSAndroid Build Coastguard Worker int imm_bits, 447*795d594fSAndroid Build Coastguard Worker int shift, 448*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 449*795d594fSAndroid Build Coastguard Worker int bias = 0) { 450*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBitsShift<Reg, Reg, ImmType>( 451*795d594fSAndroid Build Coastguard Worker f, 452*795d594fSAndroid Build Coastguard Worker imm_bits, 453*795d594fSAndroid Build Coastguard Worker shift, 454*795d594fSAndroid Build Coastguard Worker GetRegisters(), 455*795d594fSAndroid Build Coastguard Worker GetRegisters(), 456*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 457*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 458*795d594fSAndroid Build Coastguard Worker fmt, 459*795d594fSAndroid Build Coastguard Worker bias); 460*795d594fSAndroid Build Coastguard Worker } 461*795d594fSAndroid Build Coastguard Worker 462*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 463*795d594fSAndroid Build Coastguard Worker std::string RepeatRRIb(void (Ass::*f)(Reg, Reg, ImmType), 464*795d594fSAndroid Build Coastguard Worker int imm_bits, 465*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 466*795d594fSAndroid Build Coastguard Worker int bias = 0) { 467*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<Reg, Reg, ImmType>(f, 468*795d594fSAndroid Build Coastguard Worker imm_bits, 469*795d594fSAndroid Build Coastguard Worker GetRegisters(), 470*795d594fSAndroid Build Coastguard Worker GetRegisters(), 471*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 472*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 473*795d594fSAndroid Build Coastguard Worker fmt, 474*795d594fSAndroid Build Coastguard Worker bias); 475*795d594fSAndroid Build Coastguard Worker } 476*795d594fSAndroid Build Coastguard Worker 477*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 478*795d594fSAndroid Build Coastguard Worker std::string RepeatRRRIb(void (Ass::*f)(Reg, Reg, Reg, ImmType), 479*795d594fSAndroid Build Coastguard Worker int imm_bits, 480*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 481*795d594fSAndroid Build Coastguard Worker int bias = 0) { 482*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<Reg, Reg, Reg, ImmType>(f, 483*795d594fSAndroid Build Coastguard Worker imm_bits, 484*795d594fSAndroid Build Coastguard Worker GetRegisters(), 485*795d594fSAndroid Build Coastguard Worker GetRegisters(), 486*795d594fSAndroid Build Coastguard Worker GetRegisters(), 487*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 488*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 489*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 490*795d594fSAndroid Build Coastguard Worker fmt, 491*795d594fSAndroid Build Coastguard Worker bias); 492*795d594fSAndroid Build Coastguard Worker } 493*795d594fSAndroid Build Coastguard Worker 494*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 495*795d594fSAndroid Build Coastguard Worker std::string RepeatRIb(void (Ass::*f)(Reg, ImmType), int imm_bits, std::string fmt, int bias = 0) { 496*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisterImmBits<Reg, ImmType>(f, 497*795d594fSAndroid Build Coastguard Worker imm_bits, 498*795d594fSAndroid Build Coastguard Worker GetRegisters(), 499*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 500*795d594fSAndroid Build Coastguard Worker fmt, 501*795d594fSAndroid Build Coastguard Worker bias); 502*795d594fSAndroid Build Coastguard Worker } 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 505*795d594fSAndroid Build Coastguard Worker std::string RepeatFRIb(void (Ass::*f)(FPReg, Reg, ImmType), 506*795d594fSAndroid Build Coastguard Worker int imm_bits, 507*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 508*795d594fSAndroid Build Coastguard Worker int bias = 0) { 509*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<FPReg, Reg, ImmType>(f, 510*795d594fSAndroid Build Coastguard Worker imm_bits, 511*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 512*795d594fSAndroid Build Coastguard Worker GetRegisters(), 513*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 514*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 515*795d594fSAndroid Build Coastguard Worker fmt, 516*795d594fSAndroid Build Coastguard Worker bias); 517*795d594fSAndroid Build Coastguard Worker } 518*795d594fSAndroid Build Coastguard Worker RepeatFF(void (Ass::* f)(FPReg,FPReg),const std::string & fmt)519*795d594fSAndroid Build Coastguard Worker std::string RepeatFF(void (Ass::*f)(FPReg, FPReg), const std::string& fmt) { 520*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, FPReg>(f, 521*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 522*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 523*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 524*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 525*795d594fSAndroid Build Coastguard Worker fmt); 526*795d594fSAndroid Build Coastguard Worker } 527*795d594fSAndroid Build Coastguard Worker RepeatFFF(void (Ass::* f)(FPReg,FPReg,FPReg),const std::string & fmt)528*795d594fSAndroid Build Coastguard Worker std::string RepeatFFF(void (Ass::*f)(FPReg, FPReg, FPReg), const std::string& fmt) { 529*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, FPReg, FPReg>(f, 530*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 531*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 532*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 533*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 534*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 535*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 536*795d594fSAndroid Build Coastguard Worker fmt); 537*795d594fSAndroid Build Coastguard Worker } 538*795d594fSAndroid Build Coastguard Worker RepeatFFFF(void (Ass::* f)(FPReg,FPReg,FPReg,FPReg),const std::string & fmt)539*795d594fSAndroid Build Coastguard Worker std::string RepeatFFFF(void (Ass::*f)(FPReg, FPReg, FPReg, FPReg), const std::string& fmt) { 540*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, FPReg, FPReg, FPReg>(f, 541*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 542*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 543*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 544*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 545*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 546*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 547*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 548*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 549*795d594fSAndroid Build Coastguard Worker fmt); 550*795d594fSAndroid Build Coastguard Worker } 551*795d594fSAndroid Build Coastguard Worker RepeatFFR(void (Ass::* f)(FPReg,FPReg,Reg),const std::string & fmt)552*795d594fSAndroid Build Coastguard Worker std::string RepeatFFR(void (Ass::*f)(FPReg, FPReg, Reg), const std::string& fmt) { 553*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, FPReg, Reg>( 554*795d594fSAndroid Build Coastguard Worker f, 555*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 556*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 557*795d594fSAndroid Build Coastguard Worker GetRegisters(), 558*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 559*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 560*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 561*795d594fSAndroid Build Coastguard Worker fmt); 562*795d594fSAndroid Build Coastguard Worker } 563*795d594fSAndroid Build Coastguard Worker RepeatFFI(void (Ass::* f)(FPReg,FPReg,const Imm &),size_t imm_bytes,const std::string & fmt)564*795d594fSAndroid Build Coastguard Worker std::string RepeatFFI(void (Ass::*f)(FPReg, FPReg, const Imm&), 565*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 566*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 567*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImm<FPReg, FPReg>(f, 568*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 569*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 570*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 571*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 572*795d594fSAndroid Build Coastguard Worker imm_bytes, 573*795d594fSAndroid Build Coastguard Worker fmt); 574*795d594fSAndroid Build Coastguard Worker } 575*795d594fSAndroid Build Coastguard Worker 576*795d594fSAndroid Build Coastguard Worker template <typename ImmType> RepeatFFIb(void (Ass::* f)(FPReg,FPReg,ImmType),int imm_bits,const std::string & fmt)577*795d594fSAndroid Build Coastguard Worker std::string RepeatFFIb(void (Ass::*f)(FPReg, FPReg, ImmType), 578*795d594fSAndroid Build Coastguard Worker int imm_bits, 579*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 580*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<FPReg, FPReg, ImmType>(f, 581*795d594fSAndroid Build Coastguard Worker imm_bits, 582*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 583*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 584*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 585*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 586*795d594fSAndroid Build Coastguard Worker fmt); 587*795d594fSAndroid Build Coastguard Worker } 588*795d594fSAndroid Build Coastguard Worker 589*795d594fSAndroid Build Coastguard Worker template <typename ImmType> RepeatIbFF(void (Ass::* f)(ImmType,FPReg,FPReg),int imm_bits,const std::string & fmt)590*795d594fSAndroid Build Coastguard Worker std::string RepeatIbFF(void (Ass::*f)(ImmType, FPReg, FPReg), 591*795d594fSAndroid Build Coastguard Worker int imm_bits, 592*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 593*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedImmBitsRegisters<ImmType, FPReg, FPReg>(f, 594*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 595*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 596*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 597*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 598*795d594fSAndroid Build Coastguard Worker imm_bits, 599*795d594fSAndroid Build Coastguard Worker fmt); 600*795d594fSAndroid Build Coastguard Worker } 601*795d594fSAndroid Build Coastguard Worker RepeatRFF(void (Ass::* f)(Reg,FPReg,FPReg),const std::string & fmt)602*795d594fSAndroid Build Coastguard Worker std::string RepeatRFF(void (Ass::*f)(Reg, FPReg, FPReg), const std::string& fmt) { 603*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, FPReg, FPReg>( 604*795d594fSAndroid Build Coastguard Worker f, 605*795d594fSAndroid Build Coastguard Worker GetRegisters(), 606*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 607*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 608*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 609*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 610*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 611*795d594fSAndroid Build Coastguard Worker fmt); 612*795d594fSAndroid Build Coastguard Worker } 613*795d594fSAndroid Build Coastguard Worker 614*795d594fSAndroid Build Coastguard Worker template <typename ImmType> RepeatRFIb(void (Ass::* f)(Reg,FPReg,ImmType),int imm_bits,const std::string & fmt)615*795d594fSAndroid Build Coastguard Worker std::string RepeatRFIb(void (Ass::*f)(Reg, FPReg, ImmType), 616*795d594fSAndroid Build Coastguard Worker int imm_bits, 617*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 618*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<Reg, FPReg, ImmType>( 619*795d594fSAndroid Build Coastguard Worker f, 620*795d594fSAndroid Build Coastguard Worker imm_bits, 621*795d594fSAndroid Build Coastguard Worker GetRegisters(), 622*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 623*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 624*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 625*795d594fSAndroid Build Coastguard Worker fmt); 626*795d594fSAndroid Build Coastguard Worker } 627*795d594fSAndroid Build Coastguard Worker RepeatFR(void (Ass::* f)(FPReg,Reg),const std::string & fmt)628*795d594fSAndroid Build Coastguard Worker std::string RepeatFR(void (Ass::*f)(FPReg, Reg), const std::string& fmt) { 629*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, Reg>(f, 630*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 631*795d594fSAndroid Build Coastguard Worker GetRegisters(), 632*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 633*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 634*795d594fSAndroid Build Coastguard Worker fmt); 635*795d594fSAndroid Build Coastguard Worker } 636*795d594fSAndroid Build Coastguard Worker RepeatFr(void (Ass::* f)(FPReg,Reg),const std::string & fmt)637*795d594fSAndroid Build Coastguard Worker std::string RepeatFr(void (Ass::*f)(FPReg, Reg), const std::string& fmt) { 638*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, Reg>(f, 639*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 640*795d594fSAndroid Build Coastguard Worker GetRegisters(), 641*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 642*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 643*795d594fSAndroid Build Coastguard Worker fmt); 644*795d594fSAndroid Build Coastguard Worker } 645*795d594fSAndroid Build Coastguard Worker RepeatRF(void (Ass::* f)(Reg,FPReg),const std::string & fmt)646*795d594fSAndroid Build Coastguard Worker std::string RepeatRF(void (Ass::*f)(Reg, FPReg), const std::string& fmt) { 647*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, FPReg>(f, 648*795d594fSAndroid Build Coastguard Worker GetRegisters(), 649*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 650*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 651*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 652*795d594fSAndroid Build Coastguard Worker fmt); 653*795d594fSAndroid Build Coastguard Worker } 654*795d594fSAndroid Build Coastguard Worker RepeatrF(void (Ass::* f)(Reg,FPReg),const std::string & fmt)655*795d594fSAndroid Build Coastguard Worker std::string RepeatrF(void (Ass::*f)(Reg, FPReg), const std::string& fmt) { 656*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, FPReg>(f, 657*795d594fSAndroid Build Coastguard Worker GetRegisters(), 658*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 659*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 660*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 661*795d594fSAndroid Build Coastguard Worker fmt); 662*795d594fSAndroid Build Coastguard Worker } 663*795d594fSAndroid Build Coastguard Worker 664*795d594fSAndroid Build Coastguard Worker std::string RepeatI(void (Ass::*f)(const Imm&), 665*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 666*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 667*795d594fSAndroid Build Coastguard Worker bool as_uint = false) { 668*795d594fSAndroid Build Coastguard Worker std::string str; 669*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValues(imm_bytes, as_uint); 670*795d594fSAndroid Build Coastguard Worker 671*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(imms.size()); 672*795d594fSAndroid Build Coastguard Worker 673*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 674*795d594fSAndroid Build Coastguard Worker Imm new_imm = CreateImmediate(imm); 675*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 676*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(new_imm); 677*795d594fSAndroid Build Coastguard Worker } 678*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 679*795d594fSAndroid Build Coastguard Worker 680*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, /*bias=*/ 0, /*multiplier=*/ 1, &base); 681*795d594fSAndroid Build Coastguard Worker 682*795d594fSAndroid Build Coastguard Worker str += base; 683*795d594fSAndroid Build Coastguard Worker str += "\n"; 684*795d594fSAndroid Build Coastguard Worker } 685*795d594fSAndroid Build Coastguard Worker return str; 686*795d594fSAndroid Build Coastguard Worker } 687*795d594fSAndroid Build Coastguard Worker RepeatV(void (Ass::* f)(VecReg),const std::string & fmt)688*795d594fSAndroid Build Coastguard Worker std::string RepeatV(void (Ass::*f)(VecReg), const std::string& fmt) { 689*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegister<VecReg>( 690*795d594fSAndroid Build Coastguard Worker f, GetVectorRegisters(), &AssemblerTest::GetVecRegName, fmt); 691*795d594fSAndroid Build Coastguard Worker } 692*795d594fSAndroid Build Coastguard Worker RepeatVV(void (Ass::* f)(VecReg,VecReg),const std::string & fmt)693*795d594fSAndroid Build Coastguard Worker std::string RepeatVV(void (Ass::*f)(VecReg, VecReg), const std::string& fmt) { 694*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<VecReg, VecReg>(f, 695*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 696*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 697*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 698*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 699*795d594fSAndroid Build Coastguard Worker fmt); 700*795d594fSAndroid Build Coastguard Worker } 701*795d594fSAndroid Build Coastguard Worker RepeatVVV(void (Ass::* f)(VecReg,VecReg,VecReg),const std::string & fmt)702*795d594fSAndroid Build Coastguard Worker std::string RepeatVVV(void (Ass::*f)(VecReg, VecReg, VecReg), const std::string& fmt) { 703*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<VecReg, VecReg, VecReg>(f, 704*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 705*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 706*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 707*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 708*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 709*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 710*795d594fSAndroid Build Coastguard Worker fmt); 711*795d594fSAndroid Build Coastguard Worker } 712*795d594fSAndroid Build Coastguard Worker RepeatVVR(void (Ass::* f)(VecReg,VecReg,Reg),const std::string & fmt)713*795d594fSAndroid Build Coastguard Worker std::string RepeatVVR(void (Ass::*f)(VecReg, VecReg, Reg), const std::string& fmt) { 714*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<VecReg, VecReg, Reg>( 715*795d594fSAndroid Build Coastguard Worker f, 716*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 717*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 718*795d594fSAndroid Build Coastguard Worker GetRegisters(), 719*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 720*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 721*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 722*795d594fSAndroid Build Coastguard Worker fmt); 723*795d594fSAndroid Build Coastguard Worker } 724*795d594fSAndroid Build Coastguard Worker RepeatVR(void (Ass::* f)(VecReg,Reg),const std::string & fmt)725*795d594fSAndroid Build Coastguard Worker std::string RepeatVR(void (Ass::*f)(VecReg, Reg), const std::string& fmt) { 726*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<VecReg, Reg>( 727*795d594fSAndroid Build Coastguard Worker f, 728*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 729*795d594fSAndroid Build Coastguard Worker GetRegisters(), 730*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 731*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 732*795d594fSAndroid Build Coastguard Worker fmt); 733*795d594fSAndroid Build Coastguard Worker } 734*795d594fSAndroid Build Coastguard Worker RepeatVF(void (Ass::* f)(VecReg,FPReg),const std::string & fmt)735*795d594fSAndroid Build Coastguard Worker std::string RepeatVF(void (Ass::*f)(VecReg, FPReg), const std::string& fmt) { 736*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<VecReg, FPReg>(f, 737*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 738*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 739*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 740*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 741*795d594fSAndroid Build Coastguard Worker fmt); 742*795d594fSAndroid Build Coastguard Worker } 743*795d594fSAndroid Build Coastguard Worker RepeatFV(void (Ass::* f)(FPReg,VecReg),const std::string & fmt)744*795d594fSAndroid Build Coastguard Worker std::string RepeatFV(void (Ass::*f)(FPReg, VecReg), const std::string& fmt) { 745*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<FPReg, VecReg>(f, 746*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 747*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 748*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 749*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 750*795d594fSAndroid Build Coastguard Worker fmt); 751*795d594fSAndroid Build Coastguard Worker } 752*795d594fSAndroid Build Coastguard Worker RepeatRV(void (Ass::* f)(Reg,VecReg),const std::string & fmt)753*795d594fSAndroid Build Coastguard Worker std::string RepeatRV(void (Ass::*f)(Reg, VecReg), const std::string& fmt) { 754*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisters<Reg, VecReg>( 755*795d594fSAndroid Build Coastguard Worker f, 756*795d594fSAndroid Build Coastguard Worker GetRegisters(), 757*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 758*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 759*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 760*795d594fSAndroid Build Coastguard Worker fmt); 761*795d594fSAndroid Build Coastguard Worker } 762*795d594fSAndroid Build Coastguard Worker 763*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 764*795d594fSAndroid Build Coastguard Worker std::string RepeatVIb(void (Ass::*f)(VecReg, ImmType), 765*795d594fSAndroid Build Coastguard Worker int imm_bits, 766*795d594fSAndroid Build Coastguard Worker std::string fmt, 767*795d594fSAndroid Build Coastguard Worker int bias = 0) { 768*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegisterImmBits<VecReg, ImmType>(f, 769*795d594fSAndroid Build Coastguard Worker imm_bits, 770*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 771*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 772*795d594fSAndroid Build Coastguard Worker fmt, 773*795d594fSAndroid Build Coastguard Worker bias); 774*795d594fSAndroid Build Coastguard Worker } 775*795d594fSAndroid Build Coastguard Worker 776*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 777*795d594fSAndroid Build Coastguard Worker std::string RepeatVRIb(void (Ass::*f)(VecReg, Reg, ImmType), 778*795d594fSAndroid Build Coastguard Worker int imm_bits, 779*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 780*795d594fSAndroid Build Coastguard Worker int bias = 0, 781*795d594fSAndroid Build Coastguard Worker int multiplier = 1) { 782*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<VecReg, Reg, ImmType>( 783*795d594fSAndroid Build Coastguard Worker f, 784*795d594fSAndroid Build Coastguard Worker imm_bits, 785*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 786*795d594fSAndroid Build Coastguard Worker GetRegisters(), 787*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 788*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 789*795d594fSAndroid Build Coastguard Worker fmt, 790*795d594fSAndroid Build Coastguard Worker bias, 791*795d594fSAndroid Build Coastguard Worker multiplier); 792*795d594fSAndroid Build Coastguard Worker } 793*795d594fSAndroid Build Coastguard Worker 794*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 795*795d594fSAndroid Build Coastguard Worker std::string RepeatRVIb(void (Ass::*f)(Reg, VecReg, ImmType), 796*795d594fSAndroid Build Coastguard Worker int imm_bits, 797*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 798*795d594fSAndroid Build Coastguard Worker int bias = 0, 799*795d594fSAndroid Build Coastguard Worker int multiplier = 1) { 800*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<Reg, VecReg, ImmType>( 801*795d594fSAndroid Build Coastguard Worker f, 802*795d594fSAndroid Build Coastguard Worker imm_bits, 803*795d594fSAndroid Build Coastguard Worker GetRegisters(), 804*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 805*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 806*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 807*795d594fSAndroid Build Coastguard Worker fmt, 808*795d594fSAndroid Build Coastguard Worker bias, 809*795d594fSAndroid Build Coastguard Worker multiplier); 810*795d594fSAndroid Build Coastguard Worker } 811*795d594fSAndroid Build Coastguard Worker 812*795d594fSAndroid Build Coastguard Worker template <typename ImmType> 813*795d594fSAndroid Build Coastguard Worker std::string RepeatVVIb(void (Ass::*f)(VecReg, VecReg, ImmType), 814*795d594fSAndroid Build Coastguard Worker int imm_bits, 815*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 816*795d594fSAndroid Build Coastguard Worker int bias = 0) { 817*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegistersImmBits<VecReg, VecReg, ImmType>(f, 818*795d594fSAndroid Build Coastguard Worker imm_bits, 819*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 820*795d594fSAndroid Build Coastguard Worker GetVectorRegisters(), 821*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 822*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetVecRegName, 823*795d594fSAndroid Build Coastguard Worker fmt, 824*795d594fSAndroid Build Coastguard Worker bias); 825*795d594fSAndroid Build Coastguard Worker } 826*795d594fSAndroid Build Coastguard Worker 827*795d594fSAndroid Build Coastguard Worker // The following functions are public so that TestFn can use them... 828*795d594fSAndroid Build Coastguard Worker 829*795d594fSAndroid Build Coastguard Worker // Returns a vector of address used by any of the repeat methods 830*795d594fSAndroid Build Coastguard Worker // involving an "A" (e.g. RepeatA). 831*795d594fSAndroid Build Coastguard Worker virtual std::vector<Addr> GetAddresses() = 0; 832*795d594fSAndroid Build Coastguard Worker 833*795d594fSAndroid Build Coastguard Worker // Returns a vector of registers used by any of the repeat methods 834*795d594fSAndroid Build Coastguard Worker // involving an "R" (e.g. RepeatR). 835*795d594fSAndroid Build Coastguard Worker virtual ArrayRef<const Reg> GetRegisters() = 0; 836*795d594fSAndroid Build Coastguard Worker 837*795d594fSAndroid Build Coastguard Worker // Returns a vector of fp-registers used by any of the repeat methods 838*795d594fSAndroid Build Coastguard Worker // involving an "F" (e.g. RepeatFF). GetFPRegisters()839*795d594fSAndroid Build Coastguard Worker virtual ArrayRef<const FPReg> GetFPRegisters() { 840*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(FATAL) << "Architecture does not support floating-point registers"; 841*795d594fSAndroid Build Coastguard Worker UNREACHABLE(); 842*795d594fSAndroid Build Coastguard Worker } 843*795d594fSAndroid Build Coastguard Worker 844*795d594fSAndroid Build Coastguard Worker // Returns a vector of dedicated simd-registers used by any of the repeat 845*795d594fSAndroid Build Coastguard Worker // methods involving an "V" (e.g. RepeatVV). GetVectorRegisters()846*795d594fSAndroid Build Coastguard Worker virtual ArrayRef<const VecReg> GetVectorRegisters() { 847*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(FATAL) << "Architecture does not support vector registers"; 848*795d594fSAndroid Build Coastguard Worker UNREACHABLE(); 849*795d594fSAndroid Build Coastguard Worker } 850*795d594fSAndroid Build Coastguard Worker 851*795d594fSAndroid Build Coastguard Worker // Secondary register names are the secondary view on registers, e.g., 32b on 64b systems. GetSecondaryRegisterName(const Reg & reg)852*795d594fSAndroid Build Coastguard Worker virtual std::string GetSecondaryRegisterName([[maybe_unused]] const Reg& reg) { 853*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(FATAL) << "Architecture does not support secondary registers"; 854*795d594fSAndroid Build Coastguard Worker UNREACHABLE(); 855*795d594fSAndroid Build Coastguard Worker } 856*795d594fSAndroid Build Coastguard Worker 857*795d594fSAndroid Build Coastguard Worker // Tertiary register names are the tertiary view on registers, e.g., 16b on 64b systems. GetTertiaryRegisterName(const Reg & reg)858*795d594fSAndroid Build Coastguard Worker virtual std::string GetTertiaryRegisterName([[maybe_unused]] const Reg& reg) { 859*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(FATAL) << "Architecture does not support tertiary registers"; 860*795d594fSAndroid Build Coastguard Worker UNREACHABLE(); 861*795d594fSAndroid Build Coastguard Worker } 862*795d594fSAndroid Build Coastguard Worker 863*795d594fSAndroid Build Coastguard Worker // Quaternary register names are the quaternary view on registers, e.g., 8b on 64b systems. GetQuaternaryRegisterName(const Reg & reg)864*795d594fSAndroid Build Coastguard Worker virtual std::string GetQuaternaryRegisterName([[maybe_unused]] const Reg& reg) { 865*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(FATAL) << "Architecture does not support quaternary registers"; 866*795d594fSAndroid Build Coastguard Worker UNREACHABLE(); 867*795d594fSAndroid Build Coastguard Worker } 868*795d594fSAndroid Build Coastguard Worker GetRegisterName(const Reg & reg)869*795d594fSAndroid Build Coastguard Worker std::string GetRegisterName(const Reg& reg) { 870*795d594fSAndroid Build Coastguard Worker return GetRegName<RegisterView::kUsePrimaryName>(reg); 871*795d594fSAndroid Build Coastguard Worker } 872*795d594fSAndroid Build Coastguard Worker 873*795d594fSAndroid Build Coastguard Worker protected: AssemblerTest()874*795d594fSAndroid Build Coastguard Worker AssemblerTest() {} 875*795d594fSAndroid Build Coastguard Worker SetUp()876*795d594fSAndroid Build Coastguard Worker void SetUp() override { 877*795d594fSAndroid Build Coastguard Worker AssemblerTestBase::SetUp(); 878*795d594fSAndroid Build Coastguard Worker allocator_.reset(new ArenaAllocator(&pool_)); 879*795d594fSAndroid Build Coastguard Worker assembler_.reset(CreateAssembler(allocator_.get())); 880*795d594fSAndroid Build Coastguard Worker SetUpHelpers(); 881*795d594fSAndroid Build Coastguard Worker } 882*795d594fSAndroid Build Coastguard Worker TearDown()883*795d594fSAndroid Build Coastguard Worker void TearDown() override { 884*795d594fSAndroid Build Coastguard Worker AssemblerTestBase::TearDown(); 885*795d594fSAndroid Build Coastguard Worker assembler_.reset(); 886*795d594fSAndroid Build Coastguard Worker allocator_.reset(); 887*795d594fSAndroid Build Coastguard Worker } 888*795d594fSAndroid Build Coastguard Worker 889*795d594fSAndroid Build Coastguard Worker // Override this to set up any architecture-specific things, e.g., CPU revision. CreateAssembler(ArenaAllocator * allocator)890*795d594fSAndroid Build Coastguard Worker virtual Ass* CreateAssembler(ArenaAllocator* allocator) { 891*795d594fSAndroid Build Coastguard Worker return new (allocator) Ass(allocator); 892*795d594fSAndroid Build Coastguard Worker } 893*795d594fSAndroid Build Coastguard Worker 894*795d594fSAndroid Build Coastguard Worker // Override this to set up any architecture-specific things, e.g., register vectors. SetUpHelpers()895*795d594fSAndroid Build Coastguard Worker virtual void SetUpHelpers() {} 896*795d594fSAndroid Build Coastguard Worker 897*795d594fSAndroid Build Coastguard Worker // Create a couple of immediate values up to the number of bytes given. 898*795d594fSAndroid Build Coastguard Worker virtual std::vector<int64_t> CreateImmediateValues(size_t imm_bytes, bool as_uint = false) { 899*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> res; 900*795d594fSAndroid Build Coastguard Worker res.push_back(0); 901*795d594fSAndroid Build Coastguard Worker if (!as_uint) { 902*795d594fSAndroid Build Coastguard Worker res.push_back(-1); 903*795d594fSAndroid Build Coastguard Worker } else { 904*795d594fSAndroid Build Coastguard Worker res.push_back(0xFF); 905*795d594fSAndroid Build Coastguard Worker } 906*795d594fSAndroid Build Coastguard Worker res.push_back(0x12); 907*795d594fSAndroid Build Coastguard Worker if (imm_bytes >= 2) { 908*795d594fSAndroid Build Coastguard Worker res.push_back(0x1234); 909*795d594fSAndroid Build Coastguard Worker if (!as_uint) { 910*795d594fSAndroid Build Coastguard Worker res.push_back(-0x1234); 911*795d594fSAndroid Build Coastguard Worker } else { 912*795d594fSAndroid Build Coastguard Worker res.push_back(0xFFFF); 913*795d594fSAndroid Build Coastguard Worker } 914*795d594fSAndroid Build Coastguard Worker if (imm_bytes >= 4) { 915*795d594fSAndroid Build Coastguard Worker res.push_back(0x12345678); 916*795d594fSAndroid Build Coastguard Worker if (!as_uint) { 917*795d594fSAndroid Build Coastguard Worker res.push_back(-0x12345678); 918*795d594fSAndroid Build Coastguard Worker } else { 919*795d594fSAndroid Build Coastguard Worker res.push_back(0xFFFFFFFF); 920*795d594fSAndroid Build Coastguard Worker } 921*795d594fSAndroid Build Coastguard Worker if (imm_bytes >= 6) { 922*795d594fSAndroid Build Coastguard Worker res.push_back(0x123456789ABC); 923*795d594fSAndroid Build Coastguard Worker if (!as_uint) { 924*795d594fSAndroid Build Coastguard Worker res.push_back(-0x123456789ABC); 925*795d594fSAndroid Build Coastguard Worker } 926*795d594fSAndroid Build Coastguard Worker if (imm_bytes >= 8) { 927*795d594fSAndroid Build Coastguard Worker res.push_back(0x123456789ABCDEF0); 928*795d594fSAndroid Build Coastguard Worker if (!as_uint) { 929*795d594fSAndroid Build Coastguard Worker res.push_back(-0x123456789ABCDEF0); 930*795d594fSAndroid Build Coastguard Worker } else { 931*795d594fSAndroid Build Coastguard Worker res.push_back(0xFFFFFFFFFFFFFFFF); 932*795d594fSAndroid Build Coastguard Worker } 933*795d594fSAndroid Build Coastguard Worker } 934*795d594fSAndroid Build Coastguard Worker } 935*795d594fSAndroid Build Coastguard Worker } 936*795d594fSAndroid Build Coastguard Worker } 937*795d594fSAndroid Build Coastguard Worker return res; 938*795d594fSAndroid Build Coastguard Worker } 939*795d594fSAndroid Build Coastguard Worker 940*795d594fSAndroid Build Coastguard Worker const int kMaxBitsExhaustiveTest = 8; 941*795d594fSAndroid Build Coastguard Worker 942*795d594fSAndroid Build Coastguard Worker // Create a couple of immediate values up to the number of bits given. 943*795d594fSAndroid Build Coastguard Worker virtual std::vector<int64_t> CreateImmediateValuesBits(const int imm_bits, 944*795d594fSAndroid Build Coastguard Worker bool as_uint = false, 945*795d594fSAndroid Build Coastguard Worker int shift = 0) { 946*795d594fSAndroid Build Coastguard Worker CHECK_GT(imm_bits, 0); 947*795d594fSAndroid Build Coastguard Worker CHECK_LE(imm_bits, 64); 948*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> res; 949*795d594fSAndroid Build Coastguard Worker 950*795d594fSAndroid Build Coastguard Worker if (imm_bits <= kMaxBitsExhaustiveTest) { 951*795d594fSAndroid Build Coastguard Worker if (as_uint) { 952*795d594fSAndroid Build Coastguard Worker for (uint64_t i = MinInt<uint64_t>(imm_bits); i <= MaxInt<uint64_t>(imm_bits); i++) { 953*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(i << shift)); 954*795d594fSAndroid Build Coastguard Worker } 955*795d594fSAndroid Build Coastguard Worker } else { 956*795d594fSAndroid Build Coastguard Worker for (int64_t i = MinInt<int64_t>(imm_bits); i <= MaxInt<int64_t>(imm_bits); i++) { 957*795d594fSAndroid Build Coastguard Worker res.push_back(i << shift); 958*795d594fSAndroid Build Coastguard Worker } 959*795d594fSAndroid Build Coastguard Worker } 960*795d594fSAndroid Build Coastguard Worker } else { 961*795d594fSAndroid Build Coastguard Worker if (as_uint) { 962*795d594fSAndroid Build Coastguard Worker for (uint64_t i = MinInt<uint64_t>(kMaxBitsExhaustiveTest); 963*795d594fSAndroid Build Coastguard Worker i <= MaxInt<uint64_t>(kMaxBitsExhaustiveTest); 964*795d594fSAndroid Build Coastguard Worker i++) { 965*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(i << shift)); 966*795d594fSAndroid Build Coastguard Worker } 967*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= imm_bits; i++) { 968*795d594fSAndroid Build Coastguard Worker uint64_t j = (MaxInt<uint64_t>(kMaxBitsExhaustiveTest) + 1) + 969*795d594fSAndroid Build Coastguard Worker ((MaxInt<uint64_t>(imm_bits) - 970*795d594fSAndroid Build Coastguard Worker (MaxInt<uint64_t>(kMaxBitsExhaustiveTest) + 1)) 971*795d594fSAndroid Build Coastguard Worker * i / imm_bits); 972*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(j << shift)); 973*795d594fSAndroid Build Coastguard Worker } 974*795d594fSAndroid Build Coastguard Worker } else { 975*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= imm_bits; i++) { 976*795d594fSAndroid Build Coastguard Worker int64_t j = MinInt<int64_t>(imm_bits) + 977*795d594fSAndroid Build Coastguard Worker ((((MinInt<int64_t>(kMaxBitsExhaustiveTest) - 1) - 978*795d594fSAndroid Build Coastguard Worker MinInt<int64_t>(imm_bits)) 979*795d594fSAndroid Build Coastguard Worker * i) / imm_bits); 980*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(j << shift)); 981*795d594fSAndroid Build Coastguard Worker } 982*795d594fSAndroid Build Coastguard Worker for (int64_t i = MinInt<int64_t>(kMaxBitsExhaustiveTest); 983*795d594fSAndroid Build Coastguard Worker i <= MaxInt<int64_t>(kMaxBitsExhaustiveTest); 984*795d594fSAndroid Build Coastguard Worker i++) { 985*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(i << shift)); 986*795d594fSAndroid Build Coastguard Worker } 987*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= imm_bits; i++) { 988*795d594fSAndroid Build Coastguard Worker int64_t j = (MaxInt<int64_t>(kMaxBitsExhaustiveTest) + 1) + 989*795d594fSAndroid Build Coastguard Worker ((MaxInt<int64_t>(imm_bits) - (MaxInt<int64_t>(kMaxBitsExhaustiveTest) + 1)) 990*795d594fSAndroid Build Coastguard Worker * i / imm_bits); 991*795d594fSAndroid Build Coastguard Worker res.push_back(static_cast<int64_t>(j << shift)); 992*795d594fSAndroid Build Coastguard Worker } 993*795d594fSAndroid Build Coastguard Worker } 994*795d594fSAndroid Build Coastguard Worker } 995*795d594fSAndroid Build Coastguard Worker 996*795d594fSAndroid Build Coastguard Worker return res; 997*795d594fSAndroid Build Coastguard Worker } 998*795d594fSAndroid Build Coastguard Worker 999*795d594fSAndroid Build Coastguard Worker // Create an immediate from the specific value. 1000*795d594fSAndroid Build Coastguard Worker virtual Imm CreateImmediate(int64_t imm_value) = 0; 1001*795d594fSAndroid Build Coastguard Worker 1002*795d594fSAndroid Build Coastguard Worker // 1003*795d594fSAndroid Build Coastguard Worker // Addresses repeats. 1004*795d594fSAndroid Build Coastguard Worker // 1005*795d594fSAndroid Build Coastguard Worker 1006*795d594fSAndroid Build Coastguard Worker // Repeats over addresses provided by fixture. RepeatA(void (Ass::* f)(const Addr &),const std::string & fmt)1007*795d594fSAndroid Build Coastguard Worker std::string RepeatA(void (Ass::*f)(const Addr&), const std::string& fmt) { 1008*795d594fSAndroid Build Coastguard Worker return RepeatA(f, GetAddresses(), fmt); 1009*795d594fSAndroid Build Coastguard Worker } 1010*795d594fSAndroid Build Coastguard Worker 1011*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1012*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatA(void (Ass::* f)(const Addr &),const std::vector<Addr> & a,const std::string & fmt)1013*795d594fSAndroid Build Coastguard Worker std::string RepeatA(void (Ass::*f)(const Addr&), 1014*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1015*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1016*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMem<Addr>(f, a, &AssemblerTest::GetAddrName, fmt); 1017*795d594fSAndroid Build Coastguard Worker } 1018*795d594fSAndroid Build Coastguard Worker 1019*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and immediates provided by fixture. RepeatAI(void (Ass::* f)(const Addr &,const Imm &),size_t imm_bytes,const std::string & fmt)1020*795d594fSAndroid Build Coastguard Worker std::string RepeatAI(void (Ass::*f)(const Addr&, const Imm&), 1021*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 1022*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1023*795d594fSAndroid Build Coastguard Worker return RepeatAI(f, imm_bytes, GetAddresses(), fmt); 1024*795d594fSAndroid Build Coastguard Worker } 1025*795d594fSAndroid Build Coastguard Worker 1026*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1027*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAI(void (Ass::* f)(const Addr &,const Imm &),size_t imm_bytes,const std::vector<Addr> & a,const std::string & fmt)1028*795d594fSAndroid Build Coastguard Worker std::string RepeatAI(void (Ass::*f)(const Addr&, const Imm&), 1029*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 1030*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1031*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1032*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemImm<Addr>(f, imm_bytes, a, &AssemblerTest::GetAddrName, fmt); 1033*795d594fSAndroid Build Coastguard Worker } 1034*795d594fSAndroid Build Coastguard Worker 1035*795d594fSAndroid Build Coastguard Worker // Repeats over registers and addresses provided by fixture. RepeatRA(void (Ass::* f)(Reg,const Addr &),const std::string & fmt)1036*795d594fSAndroid Build Coastguard Worker std::string RepeatRA(void (Ass::*f)(Reg, const Addr&), const std::string& fmt) { 1037*795d594fSAndroid Build Coastguard Worker return RepeatRA(f, GetAddresses(), fmt); 1038*795d594fSAndroid Build Coastguard Worker } 1039*795d594fSAndroid Build Coastguard Worker 1040*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1041*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatRA(void (Ass::* f)(Reg,const Addr &),const std::vector<Addr> & a,const std::string & fmt)1042*795d594fSAndroid Build Coastguard Worker std::string RepeatRA(void (Ass::*f)(Reg, const Addr&), 1043*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1044*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1045*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegMem<Reg, Addr>( 1046*795d594fSAndroid Build Coastguard Worker f, 1047*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1048*795d594fSAndroid Build Coastguard Worker a, 1049*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 1050*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1051*795d594fSAndroid Build Coastguard Worker fmt); 1052*795d594fSAndroid Build Coastguard Worker } 1053*795d594fSAndroid Build Coastguard Worker 1054*795d594fSAndroid Build Coastguard Worker // Repeats over secondary registers and addresses provided by fixture. RepeatrA(void (Ass::* f)(Reg,const Addr &),const std::string & fmt)1055*795d594fSAndroid Build Coastguard Worker std::string RepeatrA(void (Ass::*f)(Reg, const Addr&), const std::string& fmt) { 1056*795d594fSAndroid Build Coastguard Worker return RepeatrA(f, GetAddresses(), fmt); 1057*795d594fSAndroid Build Coastguard Worker } 1058*795d594fSAndroid Build Coastguard Worker 1059*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1060*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatrA(void (Ass::* f)(Reg,const Addr &),const std::vector<Addr> & a,const std::string & fmt)1061*795d594fSAndroid Build Coastguard Worker std::string RepeatrA(void (Ass::*f)(Reg, const Addr&), 1062*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1063*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1064*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegMem<Reg, Addr>( 1065*795d594fSAndroid Build Coastguard Worker f, 1066*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1067*795d594fSAndroid Build Coastguard Worker a, 1068*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 1069*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1070*795d594fSAndroid Build Coastguard Worker fmt); 1071*795d594fSAndroid Build Coastguard Worker } 1072*795d594fSAndroid Build Coastguard Worker 1073*795d594fSAndroid Build Coastguard Worker // Repeats over tertiary registers and addresses provided by fixture. RepeatwA(void (Ass::* f)(Reg,const Addr &),const std::string & fmt)1074*795d594fSAndroid Build Coastguard Worker std::string RepeatwA(void (Ass::*f)(Reg, const Addr&), const std::string& fmt) { 1075*795d594fSAndroid Build Coastguard Worker return RepeatwA(f, GetAddresses(), fmt); 1076*795d594fSAndroid Build Coastguard Worker } 1077*795d594fSAndroid Build Coastguard Worker 1078*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1079*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatwA(void (Ass::* f)(Reg,const Addr &),const std::vector<Addr> & a,const std::string & fmt)1080*795d594fSAndroid Build Coastguard Worker std::string RepeatwA(void (Ass::*f)(Reg, const Addr&), 1081*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1082*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1083*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegMem<Reg, Addr>( 1084*795d594fSAndroid Build Coastguard Worker f, 1085*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1086*795d594fSAndroid Build Coastguard Worker a, 1087*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseTertiaryName>, 1088*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1089*795d594fSAndroid Build Coastguard Worker fmt); 1090*795d594fSAndroid Build Coastguard Worker } 1091*795d594fSAndroid Build Coastguard Worker 1092*795d594fSAndroid Build Coastguard Worker // Repeats over quaternary registers and addresses provided by fixture. RepeatbA(void (Ass::* f)(Reg,const Addr &),const std::string & fmt)1093*795d594fSAndroid Build Coastguard Worker std::string RepeatbA(void (Ass::*f)(Reg, const Addr&), const std::string& fmt) { 1094*795d594fSAndroid Build Coastguard Worker return RepeatbA(f, GetAddresses(), fmt); 1095*795d594fSAndroid Build Coastguard Worker } 1096*795d594fSAndroid Build Coastguard Worker 1097*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1098*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatbA(void (Ass::* f)(Reg,const Addr &),const std::vector<Addr> & a,const std::string & fmt)1099*795d594fSAndroid Build Coastguard Worker std::string RepeatbA(void (Ass::*f)(Reg, const Addr&), 1100*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1101*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1102*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegMem<Reg, Addr>( 1103*795d594fSAndroid Build Coastguard Worker f, 1104*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1105*795d594fSAndroid Build Coastguard Worker a, 1106*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseQuaternaryName>, 1107*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1108*795d594fSAndroid Build Coastguard Worker fmt); 1109*795d594fSAndroid Build Coastguard Worker } 1110*795d594fSAndroid Build Coastguard Worker 1111*795d594fSAndroid Build Coastguard Worker // Repeats over fp-registers and addresses provided by fixture. RepeatFA(void (Ass::* f)(FPReg,const Addr &),const std::string & fmt)1112*795d594fSAndroid Build Coastguard Worker std::string RepeatFA(void (Ass::*f)(FPReg, const Addr&), const std::string& fmt) { 1113*795d594fSAndroid Build Coastguard Worker return RepeatFA(f, GetAddresses(), fmt); 1114*795d594fSAndroid Build Coastguard Worker } 1115*795d594fSAndroid Build Coastguard Worker 1116*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1117*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatFA(void (Ass::* f)(FPReg,const Addr &),const std::vector<Addr> & a,const std::string & fmt)1118*795d594fSAndroid Build Coastguard Worker std::string RepeatFA(void (Ass::*f)(FPReg, const Addr&), 1119*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1120*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1121*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedRegMem<FPReg, Addr>( 1122*795d594fSAndroid Build Coastguard Worker f, 1123*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 1124*795d594fSAndroid Build Coastguard Worker a, 1125*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 1126*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1127*795d594fSAndroid Build Coastguard Worker fmt); 1128*795d594fSAndroid Build Coastguard Worker } 1129*795d594fSAndroid Build Coastguard Worker 1130*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and registers provided by fixture. RepeatAR(void (Ass::* f)(const Addr &,Reg),const std::string & fmt)1131*795d594fSAndroid Build Coastguard Worker std::string RepeatAR(void (Ass::*f)(const Addr&, Reg), const std::string& fmt) { 1132*795d594fSAndroid Build Coastguard Worker return RepeatAR(f, GetAddresses(), fmt); 1133*795d594fSAndroid Build Coastguard Worker } 1134*795d594fSAndroid Build Coastguard Worker 1135*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1136*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAR(void (Ass::* f)(const Addr &,Reg),const std::vector<Addr> & a,const std::string & fmt)1137*795d594fSAndroid Build Coastguard Worker std::string RepeatAR(void (Ass::*f)(const Addr&, Reg), 1138*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1139*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1140*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemReg<Addr, Reg>( 1141*795d594fSAndroid Build Coastguard Worker f, 1142*795d594fSAndroid Build Coastguard Worker a, 1143*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1144*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1145*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, 1146*795d594fSAndroid Build Coastguard Worker fmt); 1147*795d594fSAndroid Build Coastguard Worker } 1148*795d594fSAndroid Build Coastguard Worker 1149*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and secondary registers provided by fixture. RepeatAr(void (Ass::* f)(const Addr &,Reg),const std::string & fmt)1150*795d594fSAndroid Build Coastguard Worker std::string RepeatAr(void (Ass::*f)(const Addr&, Reg), const std::string& fmt) { 1151*795d594fSAndroid Build Coastguard Worker return RepeatAr(f, GetAddresses(), fmt); 1152*795d594fSAndroid Build Coastguard Worker } 1153*795d594fSAndroid Build Coastguard Worker 1154*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1155*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAr(void (Ass::* f)(const Addr &,Reg),const std::vector<Addr> & a,const std::string & fmt)1156*795d594fSAndroid Build Coastguard Worker std::string RepeatAr(void (Ass::*f)(const Addr&, Reg), 1157*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1158*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1159*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemReg<Addr, Reg>( 1160*795d594fSAndroid Build Coastguard Worker f, 1161*795d594fSAndroid Build Coastguard Worker a, 1162*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1163*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1164*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseSecondaryName>, 1165*795d594fSAndroid Build Coastguard Worker fmt); 1166*795d594fSAndroid Build Coastguard Worker } 1167*795d594fSAndroid Build Coastguard Worker 1168*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and tertiary registers provided by fixture. RepeatAw(void (Ass::* f)(const Addr &,Reg),const std::string & fmt)1169*795d594fSAndroid Build Coastguard Worker std::string RepeatAw(void (Ass::*f)(const Addr&, Reg), const std::string& fmt) { 1170*795d594fSAndroid Build Coastguard Worker return RepeatAw(f, GetAddresses(), fmt); 1171*795d594fSAndroid Build Coastguard Worker } 1172*795d594fSAndroid Build Coastguard Worker 1173*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1174*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAw(void (Ass::* f)(const Addr &,Reg),const std::vector<Addr> & a,const std::string & fmt)1175*795d594fSAndroid Build Coastguard Worker std::string RepeatAw(void (Ass::*f)(const Addr&, Reg), 1176*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1177*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1178*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemReg<Addr, Reg>( 1179*795d594fSAndroid Build Coastguard Worker f, 1180*795d594fSAndroid Build Coastguard Worker a, 1181*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1182*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1183*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseTertiaryName>, 1184*795d594fSAndroid Build Coastguard Worker fmt); 1185*795d594fSAndroid Build Coastguard Worker } 1186*795d594fSAndroid Build Coastguard Worker 1187*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and quaternary registers provided by fixture. RepeatAb(void (Ass::* f)(const Addr &,Reg),const std::string & fmt)1188*795d594fSAndroid Build Coastguard Worker std::string RepeatAb(void (Ass::*f)(const Addr&, Reg), const std::string& fmt) { 1189*795d594fSAndroid Build Coastguard Worker return RepeatAb(f, GetAddresses(), fmt); 1190*795d594fSAndroid Build Coastguard Worker } 1191*795d594fSAndroid Build Coastguard Worker 1192*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1193*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAb(void (Ass::* f)(const Addr &,Reg),const std::vector<Addr> & a,const std::string & fmt)1194*795d594fSAndroid Build Coastguard Worker std::string RepeatAb(void (Ass::*f)(const Addr&, Reg), 1195*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1196*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1197*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemReg<Addr, Reg>( 1198*795d594fSAndroid Build Coastguard Worker f, 1199*795d594fSAndroid Build Coastguard Worker a, 1200*795d594fSAndroid Build Coastguard Worker GetRegisters(), 1201*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1202*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetRegName<RegisterView::kUseQuaternaryName>, 1203*795d594fSAndroid Build Coastguard Worker fmt); 1204*795d594fSAndroid Build Coastguard Worker } 1205*795d594fSAndroid Build Coastguard Worker 1206*795d594fSAndroid Build Coastguard Worker // Repeats over addresses and fp-registers provided by fixture. RepeatAF(void (Ass::* f)(const Addr &,FPReg),const std::string & fmt)1207*795d594fSAndroid Build Coastguard Worker std::string RepeatAF(void (Ass::*f)(const Addr&, FPReg), const std::string& fmt) { 1208*795d594fSAndroid Build Coastguard Worker return RepeatAF(f, GetAddresses(), fmt); 1209*795d594fSAndroid Build Coastguard Worker } 1210*795d594fSAndroid Build Coastguard Worker 1211*795d594fSAndroid Build Coastguard Worker // Variant that takes explicit vector of addresss 1212*795d594fSAndroid Build Coastguard Worker // (to test restricted addressing modes set). RepeatAF(void (Ass::* f)(const Addr &,FPReg),const std::vector<Addr> & a,const std::string & fmt)1213*795d594fSAndroid Build Coastguard Worker std::string RepeatAF(void (Ass::*f)(const Addr&, FPReg), 1214*795d594fSAndroid Build Coastguard Worker const std::vector<Addr>& a, 1215*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1216*795d594fSAndroid Build Coastguard Worker return RepeatTemplatedMemReg<Addr, FPReg>( 1217*795d594fSAndroid Build Coastguard Worker f, 1218*795d594fSAndroid Build Coastguard Worker a, 1219*795d594fSAndroid Build Coastguard Worker GetFPRegisters(), 1220*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetAddrName, 1221*795d594fSAndroid Build Coastguard Worker &AssemblerTest::GetFPRegName, 1222*795d594fSAndroid Build Coastguard Worker fmt); 1223*795d594fSAndroid Build Coastguard Worker } 1224*795d594fSAndroid Build Coastguard Worker 1225*795d594fSAndroid Build Coastguard Worker template <typename AddrType> RepeatTemplatedMem(void (Ass::* f)(const AddrType &),const std::vector<AddrType> addresses,std::string (AssemblerTest::* GetAName)(const AddrType &),const std::string & fmt)1226*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedMem(void (Ass::*f)(const AddrType&), 1227*795d594fSAndroid Build Coastguard Worker const std::vector<AddrType> addresses, 1228*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetAName)(const AddrType&), 1229*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1230*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(addresses.size()); 1231*795d594fSAndroid Build Coastguard Worker std::string str; 1232*795d594fSAndroid Build Coastguard Worker for (auto addr : addresses) { 1233*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1234*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(addr); 1235*795d594fSAndroid Build Coastguard Worker } 1236*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1237*795d594fSAndroid Build Coastguard Worker 1238*795d594fSAndroid Build Coastguard Worker ReplaceAddr((this->*GetAName)(addr), &base); 1239*795d594fSAndroid Build Coastguard Worker 1240*795d594fSAndroid Build Coastguard Worker str += base; 1241*795d594fSAndroid Build Coastguard Worker str += "\n"; 1242*795d594fSAndroid Build Coastguard Worker } 1243*795d594fSAndroid Build Coastguard Worker return str; 1244*795d594fSAndroid Build Coastguard Worker } 1245*795d594fSAndroid Build Coastguard Worker 1246*795d594fSAndroid Build Coastguard Worker template <typename AddrType> RepeatTemplatedMemImm(void (Ass::* f)(const AddrType &,const Imm &),size_t imm_bytes,const std::vector<AddrType> addresses,std::string (AssemblerTest::* GetAName)(const AddrType &),const std::string & fmt)1247*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedMemImm(void (Ass::*f)(const AddrType&, const Imm&), 1248*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 1249*795d594fSAndroid Build Coastguard Worker const std::vector<AddrType> addresses, 1250*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetAName)(const AddrType&), 1251*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1252*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValues(imm_bytes); 1253*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(addresses.size() * imms.size()); 1254*795d594fSAndroid Build Coastguard Worker std::string str; 1255*795d594fSAndroid Build Coastguard Worker for (auto addr : addresses) { 1256*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 1257*795d594fSAndroid Build Coastguard Worker Imm new_imm = CreateImmediate(imm); 1258*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1259*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(addr, new_imm); 1260*795d594fSAndroid Build Coastguard Worker } 1261*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1262*795d594fSAndroid Build Coastguard Worker 1263*795d594fSAndroid Build Coastguard Worker ReplaceAddr((this->*GetAName)(addr), &base); 1264*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, /*bias=*/ 0, /*multiplier=*/ 1, &base); 1265*795d594fSAndroid Build Coastguard Worker 1266*795d594fSAndroid Build Coastguard Worker str += base; 1267*795d594fSAndroid Build Coastguard Worker str += "\n"; 1268*795d594fSAndroid Build Coastguard Worker } 1269*795d594fSAndroid Build Coastguard Worker } 1270*795d594fSAndroid Build Coastguard Worker return str; 1271*795d594fSAndroid Build Coastguard Worker } 1272*795d594fSAndroid Build Coastguard Worker 1273*795d594fSAndroid Build Coastguard Worker template <typename RegType, typename AddrType> RepeatTemplatedRegMem(void (Ass::* f)(RegType,const AddrType &),ArrayRef<const RegType> registers,const std::vector<AddrType> addresses,std::string (AssemblerTest::* GetRName)(const RegType &),std::string (AssemblerTest::* GetAName)(const AddrType &),const std::string & fmt)1274*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegMem(void (Ass::*f)(RegType, const AddrType&), 1275*795d594fSAndroid Build Coastguard Worker ArrayRef<const RegType> registers, 1276*795d594fSAndroid Build Coastguard Worker const std::vector<AddrType> addresses, 1277*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetRName)(const RegType&), 1278*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetAName)(const AddrType&), 1279*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1280*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(addresses.size() * registers.size()); 1281*795d594fSAndroid Build Coastguard Worker std::string str; 1282*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 1283*795d594fSAndroid Build Coastguard Worker for (auto addr : addresses) { 1284*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1285*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg, addr); 1286*795d594fSAndroid Build Coastguard Worker } 1287*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1288*795d594fSAndroid Build Coastguard Worker 1289*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, (this->*GetRName)(reg), &base); 1290*795d594fSAndroid Build Coastguard Worker ReplaceAddr((this->*GetAName)(addr), &base); 1291*795d594fSAndroid Build Coastguard Worker 1292*795d594fSAndroid Build Coastguard Worker str += base; 1293*795d594fSAndroid Build Coastguard Worker str += "\n"; 1294*795d594fSAndroid Build Coastguard Worker } 1295*795d594fSAndroid Build Coastguard Worker } 1296*795d594fSAndroid Build Coastguard Worker return str; 1297*795d594fSAndroid Build Coastguard Worker } 1298*795d594fSAndroid Build Coastguard Worker 1299*795d594fSAndroid Build Coastguard Worker template <typename AddrType, typename RegType> RepeatTemplatedMemReg(void (Ass::* f)(const AddrType &,RegType),const std::vector<AddrType> addresses,ArrayRef<const RegType> registers,std::string (AssemblerTest::* GetAName)(const AddrType &),std::string (AssemblerTest::* GetRName)(const RegType &),const std::string & fmt)1300*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedMemReg(void (Ass::*f)(const AddrType&, RegType), 1301*795d594fSAndroid Build Coastguard Worker const std::vector<AddrType> addresses, 1302*795d594fSAndroid Build Coastguard Worker ArrayRef<const RegType> registers, 1303*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetAName)(const AddrType&), 1304*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetRName)(const RegType&), 1305*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1306*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(addresses.size() * registers.size()); 1307*795d594fSAndroid Build Coastguard Worker std::string str; 1308*795d594fSAndroid Build Coastguard Worker for (auto addr : addresses) { 1309*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 1310*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1311*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(addr, reg); 1312*795d594fSAndroid Build Coastguard Worker } 1313*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1314*795d594fSAndroid Build Coastguard Worker 1315*795d594fSAndroid Build Coastguard Worker ReplaceAddr((this->*GetAName)(addr), &base); 1316*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, (this->*GetRName)(reg), &base); 1317*795d594fSAndroid Build Coastguard Worker 1318*795d594fSAndroid Build Coastguard Worker str += base; 1319*795d594fSAndroid Build Coastguard Worker str += "\n"; 1320*795d594fSAndroid Build Coastguard Worker } 1321*795d594fSAndroid Build Coastguard Worker } 1322*795d594fSAndroid Build Coastguard Worker return str; 1323*795d594fSAndroid Build Coastguard Worker } 1324*795d594fSAndroid Build Coastguard Worker 1325*795d594fSAndroid Build Coastguard Worker // 1326*795d594fSAndroid Build Coastguard Worker // Register repeats. 1327*795d594fSAndroid Build Coastguard Worker // 1328*795d594fSAndroid Build Coastguard Worker 1329*795d594fSAndroid Build Coastguard Worker template <typename RegType> RepeatTemplatedRegister(void (Ass::* f)(RegType),ArrayRef<const RegType> registers,std::string (AssemblerTest::* GetName)(const RegType &),const std::string & fmt)1330*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegister(void (Ass::*f)(RegType), 1331*795d594fSAndroid Build Coastguard Worker ArrayRef<const RegType> registers, 1332*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName)(const RegType&), 1333*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1334*795d594fSAndroid Build Coastguard Worker std::string str; 1335*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 1336*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1337*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg); 1338*795d594fSAndroid Build Coastguard Worker } 1339*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1340*795d594fSAndroid Build Coastguard Worker 1341*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, (this->*GetName)(reg), &base); 1342*795d594fSAndroid Build Coastguard Worker 1343*795d594fSAndroid Build Coastguard Worker str += base; 1344*795d594fSAndroid Build Coastguard Worker str += "\n"; 1345*795d594fSAndroid Build Coastguard Worker } 1346*795d594fSAndroid Build Coastguard Worker return str; 1347*795d594fSAndroid Build Coastguard Worker } 1348*795d594fSAndroid Build Coastguard Worker 1349*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2> 1350*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegisters(void (Ass::*f)(Reg1, Reg2), 1351*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 1352*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 1353*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 1354*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 1355*795d594fSAndroid Build Coastguard Worker const std::string& fmt, 1356*795d594fSAndroid Build Coastguard Worker const std::vector<std::pair<Reg1, Reg2>>* except = nullptr) { 1357*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(reg1_registers.size() * reg2_registers.size()); 1358*795d594fSAndroid Build Coastguard Worker 1359*795d594fSAndroid Build Coastguard Worker std::string str; 1360*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 1361*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 1362*795d594fSAndroid Build Coastguard Worker // Check if this register pair is on the exception list. If so, skip it. 1363*795d594fSAndroid Build Coastguard Worker if (except != nullptr) { 1364*795d594fSAndroid Build Coastguard Worker const auto& pair = std::make_pair(reg1, reg2); 1365*795d594fSAndroid Build Coastguard Worker if (std::find(except->begin(), except->end(), pair) != except->end()) { 1366*795d594fSAndroid Build Coastguard Worker continue; 1367*795d594fSAndroid Build Coastguard Worker } 1368*795d594fSAndroid Build Coastguard Worker } 1369*795d594fSAndroid Build Coastguard Worker 1370*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1371*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2); 1372*795d594fSAndroid Build Coastguard Worker } 1373*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1374*795d594fSAndroid Build Coastguard Worker 1375*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 1376*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 1377*795d594fSAndroid Build Coastguard Worker 1378*795d594fSAndroid Build Coastguard Worker str += base; 1379*795d594fSAndroid Build Coastguard Worker str += "\n"; 1380*795d594fSAndroid Build Coastguard Worker } 1381*795d594fSAndroid Build Coastguard Worker } 1382*795d594fSAndroid Build Coastguard Worker return str; 1383*795d594fSAndroid Build Coastguard Worker } 1384*795d594fSAndroid Build Coastguard Worker 1385*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2> RepeatTemplatedRegistersNoDupes(void (Ass::* f)(Reg1,Reg2),ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),const std::string & fmt)1386*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegistersNoDupes(void (Ass::*f)(Reg1, Reg2), 1387*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 1388*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 1389*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 1390*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 1391*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1392*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(reg1_registers.size() * reg2_registers.size()); 1393*795d594fSAndroid Build Coastguard Worker 1394*795d594fSAndroid Build Coastguard Worker std::string str; 1395*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 1396*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 1397*795d594fSAndroid Build Coastguard Worker if (reg1 == reg2) continue; 1398*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1399*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2); 1400*795d594fSAndroid Build Coastguard Worker } 1401*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1402*795d594fSAndroid Build Coastguard Worker 1403*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 1404*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 1405*795d594fSAndroid Build Coastguard Worker 1406*795d594fSAndroid Build Coastguard Worker str += base; 1407*795d594fSAndroid Build Coastguard Worker str += "\n"; 1408*795d594fSAndroid Build Coastguard Worker } 1409*795d594fSAndroid Build Coastguard Worker } 1410*795d594fSAndroid Build Coastguard Worker return str; 1411*795d594fSAndroid Build Coastguard Worker } 1412*795d594fSAndroid Build Coastguard Worker 1413*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2, typename Reg3> RepeatTemplatedRegisters(void (Ass::* f)(Reg1,Reg2,Reg3),ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,ArrayRef<const Reg3> reg3_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),std::string (AssemblerTest::* GetName3)(const Reg3 &),const std::string & fmt)1414*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegisters(void (Ass::*f)(Reg1, Reg2, Reg3), 1415*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 1416*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 1417*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg3> reg3_registers, 1418*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 1419*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 1420*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName3)(const Reg3&), 1421*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1422*795d594fSAndroid Build Coastguard Worker std::string str; 1423*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 1424*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 1425*795d594fSAndroid Build Coastguard Worker for (auto reg3 : reg3_registers) { 1426*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1427*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, reg3); 1428*795d594fSAndroid Build Coastguard Worker } 1429*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1430*795d594fSAndroid Build Coastguard Worker 1431*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 1432*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 1433*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG3_TOKEN, (this->*GetName3)(reg3), &base); 1434*795d594fSAndroid Build Coastguard Worker 1435*795d594fSAndroid Build Coastguard Worker str += base; 1436*795d594fSAndroid Build Coastguard Worker str += "\n"; 1437*795d594fSAndroid Build Coastguard Worker } 1438*795d594fSAndroid Build Coastguard Worker } 1439*795d594fSAndroid Build Coastguard Worker } 1440*795d594fSAndroid Build Coastguard Worker return str; 1441*795d594fSAndroid Build Coastguard Worker } 1442*795d594fSAndroid Build Coastguard Worker 1443*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2, typename Reg3, typename Reg4> RepeatTemplatedRegisters(void (Ass::* f)(Reg1,Reg2,Reg3,Reg4),ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,ArrayRef<const Reg3> reg3_registers,ArrayRef<const Reg4> reg4_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),std::string (AssemblerTest::* GetName3)(const Reg3 &),std::string (AssemblerTest::* GetName4)(const Reg4 &),const std::string & fmt)1444*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegisters(void (Ass::*f)(Reg1, Reg2, Reg3, Reg4), 1445*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 1446*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 1447*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg3> reg3_registers, 1448*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg4> reg4_registers, 1449*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 1450*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 1451*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName3)(const Reg3&), 1452*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName4)(const Reg4&), 1453*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1454*795d594fSAndroid Build Coastguard Worker std::string str; 1455*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 1456*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 1457*795d594fSAndroid Build Coastguard Worker for (auto reg3 : reg3_registers) { 1458*795d594fSAndroid Build Coastguard Worker for (auto reg4 : reg4_registers) { 1459*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1460*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, reg3, reg4); 1461*795d594fSAndroid Build Coastguard Worker } 1462*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1463*795d594fSAndroid Build Coastguard Worker 1464*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 1465*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 1466*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG3_TOKEN, (this->*GetName3)(reg3), &base); 1467*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG4_TOKEN, (this->*GetName4)(reg4), &base); 1468*795d594fSAndroid Build Coastguard Worker 1469*795d594fSAndroid Build Coastguard Worker str += base; 1470*795d594fSAndroid Build Coastguard Worker str += "\n"; 1471*795d594fSAndroid Build Coastguard Worker } 1472*795d594fSAndroid Build Coastguard Worker } 1473*795d594fSAndroid Build Coastguard Worker } 1474*795d594fSAndroid Build Coastguard Worker } 1475*795d594fSAndroid Build Coastguard Worker return str; 1476*795d594fSAndroid Build Coastguard Worker } 1477*795d594fSAndroid Build Coastguard Worker 1478*795d594fSAndroid Build Coastguard Worker template <typename Reg1, typename Reg2> RepeatTemplatedRegistersImm(void (Ass::* f)(Reg1,Reg2,const Imm &),ArrayRef<const Reg1> reg1_registers,ArrayRef<const Reg2> reg2_registers,std::string (AssemblerTest::* GetName1)(const Reg1 &),std::string (AssemblerTest::* GetName2)(const Reg2 &),size_t imm_bytes,const std::string & fmt)1479*795d594fSAndroid Build Coastguard Worker std::string RepeatTemplatedRegistersImm(void (Ass::*f)(Reg1, Reg2, const Imm&), 1480*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg1> reg1_registers, 1481*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg2> reg2_registers, 1482*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName1)(const Reg1&), 1483*795d594fSAndroid Build Coastguard Worker std::string (AssemblerTest::*GetName2)(const Reg2&), 1484*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 1485*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1486*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValues(imm_bytes); 1487*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * imms.size()); 1488*795d594fSAndroid Build Coastguard Worker 1489*795d594fSAndroid Build Coastguard Worker std::string str; 1490*795d594fSAndroid Build Coastguard Worker for (auto reg1 : reg1_registers) { 1491*795d594fSAndroid Build Coastguard Worker for (auto reg2 : reg2_registers) { 1492*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 1493*795d594fSAndroid Build Coastguard Worker Imm new_imm = CreateImmediate(imm); 1494*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1495*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg1, reg2, new_imm); 1496*795d594fSAndroid Build Coastguard Worker } 1497*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1498*795d594fSAndroid Build Coastguard Worker 1499*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG1_TOKEN, (this->*GetName1)(reg1), &base); 1500*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG2_TOKEN, (this->*GetName2)(reg2), &base); 1501*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, /*bias=*/ 0, /*multiplier=*/ 1, &base); 1502*795d594fSAndroid Build Coastguard Worker 1503*795d594fSAndroid Build Coastguard Worker str += base; 1504*795d594fSAndroid Build Coastguard Worker str += "\n"; 1505*795d594fSAndroid Build Coastguard Worker } 1506*795d594fSAndroid Build Coastguard Worker } 1507*795d594fSAndroid Build Coastguard Worker } 1508*795d594fSAndroid Build Coastguard Worker return str; 1509*795d594fSAndroid Build Coastguard Worker } 1510*795d594fSAndroid Build Coastguard Worker GetAddrName(const Addr & addr)1511*795d594fSAndroid Build Coastguard Worker std::string GetAddrName(const Addr& addr) { 1512*795d594fSAndroid Build Coastguard Worker std::ostringstream saddr; 1513*795d594fSAndroid Build Coastguard Worker saddr << addr; 1514*795d594fSAndroid Build Coastguard Worker return saddr.str(); 1515*795d594fSAndroid Build Coastguard Worker } 1516*795d594fSAndroid Build Coastguard Worker 1517*795d594fSAndroid Build Coastguard Worker template <RegisterView kRegView> GetRegName(const Reg & reg)1518*795d594fSAndroid Build Coastguard Worker std::string GetRegName(const Reg& reg) { 1519*795d594fSAndroid Build Coastguard Worker std::ostringstream sreg; 1520*795d594fSAndroid Build Coastguard Worker switch (kRegView) { 1521*795d594fSAndroid Build Coastguard Worker case RegisterView::kUsePrimaryName: 1522*795d594fSAndroid Build Coastguard Worker sreg << reg; 1523*795d594fSAndroid Build Coastguard Worker break; 1524*795d594fSAndroid Build Coastguard Worker 1525*795d594fSAndroid Build Coastguard Worker case RegisterView::kUseSecondaryName: 1526*795d594fSAndroid Build Coastguard Worker sreg << GetSecondaryRegisterName(reg); 1527*795d594fSAndroid Build Coastguard Worker break; 1528*795d594fSAndroid Build Coastguard Worker 1529*795d594fSAndroid Build Coastguard Worker case RegisterView::kUseTertiaryName: 1530*795d594fSAndroid Build Coastguard Worker sreg << GetTertiaryRegisterName(reg); 1531*795d594fSAndroid Build Coastguard Worker break; 1532*795d594fSAndroid Build Coastguard Worker 1533*795d594fSAndroid Build Coastguard Worker case RegisterView::kUseQuaternaryName: 1534*795d594fSAndroid Build Coastguard Worker sreg << GetQuaternaryRegisterName(reg); 1535*795d594fSAndroid Build Coastguard Worker break; 1536*795d594fSAndroid Build Coastguard Worker } 1537*795d594fSAndroid Build Coastguard Worker return sreg.str(); 1538*795d594fSAndroid Build Coastguard Worker } 1539*795d594fSAndroid Build Coastguard Worker GetFPRegName(const FPReg & reg)1540*795d594fSAndroid Build Coastguard Worker std::string GetFPRegName(const FPReg& reg) { 1541*795d594fSAndroid Build Coastguard Worker std::ostringstream sreg; 1542*795d594fSAndroid Build Coastguard Worker sreg << reg; 1543*795d594fSAndroid Build Coastguard Worker return sreg.str(); 1544*795d594fSAndroid Build Coastguard Worker } 1545*795d594fSAndroid Build Coastguard Worker GetVecRegName(const VecReg & reg)1546*795d594fSAndroid Build Coastguard Worker std::string GetVecRegName(const VecReg& reg) { 1547*795d594fSAndroid Build Coastguard Worker std::ostringstream sreg; 1548*795d594fSAndroid Build Coastguard Worker sreg << reg; 1549*795d594fSAndroid Build Coastguard Worker return sreg.str(); 1550*795d594fSAndroid Build Coastguard Worker } 1551*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(size_t count)1552*795d594fSAndroid Build Coastguard Worker void WarnOnCombinations(size_t count) { 1553*795d594fSAndroid Build Coastguard Worker if (count > kWarnManyCombinationsThreshold) { 1554*795d594fSAndroid Build Coastguard Worker GTEST_LOG_(WARNING) << "Many combinations (" << count << "), test generation might be slow."; 1555*795d594fSAndroid Build Coastguard Worker } 1556*795d594fSAndroid Build Coastguard Worker } 1557*795d594fSAndroid Build Coastguard Worker ReplaceReg(const std::string & reg_token,const std::string & replacement,std::string * str)1558*795d594fSAndroid Build Coastguard Worker static void ReplaceReg(const std::string& reg_token, 1559*795d594fSAndroid Build Coastguard Worker const std::string& replacement, 1560*795d594fSAndroid Build Coastguard Worker /*inout*/ std::string* str) { 1561*795d594fSAndroid Build Coastguard Worker size_t reg_index; 1562*795d594fSAndroid Build Coastguard Worker while ((reg_index = str->find(reg_token)) != std::string::npos) { 1563*795d594fSAndroid Build Coastguard Worker str->replace(reg_index, reg_token.length(), replacement); 1564*795d594fSAndroid Build Coastguard Worker } 1565*795d594fSAndroid Build Coastguard Worker } 1566*795d594fSAndroid Build Coastguard Worker ReplaceImm(int64_t imm,int64_t bias,int64_t multiplier,std::string * str)1567*795d594fSAndroid Build Coastguard Worker static void ReplaceImm(int64_t imm, 1568*795d594fSAndroid Build Coastguard Worker int64_t bias, 1569*795d594fSAndroid Build Coastguard Worker int64_t multiplier, 1570*795d594fSAndroid Build Coastguard Worker /*inout*/ std::string* str) { 1571*795d594fSAndroid Build Coastguard Worker size_t imm_index = str->find(IMM_TOKEN); 1572*795d594fSAndroid Build Coastguard Worker if (imm_index != std::string::npos) { 1573*795d594fSAndroid Build Coastguard Worker std::ostringstream sreg; 1574*795d594fSAndroid Build Coastguard Worker sreg << imm * multiplier + bias; 1575*795d594fSAndroid Build Coastguard Worker std::string imm_string = sreg.str(); 1576*795d594fSAndroid Build Coastguard Worker str->replace(imm_index, ConstexprStrLen(IMM_TOKEN), imm_string); 1577*795d594fSAndroid Build Coastguard Worker } 1578*795d594fSAndroid Build Coastguard Worker } 1579*795d594fSAndroid Build Coastguard Worker ReplaceAddr(const std::string & replacement,std::string * str)1580*795d594fSAndroid Build Coastguard Worker static void ReplaceAddr(const std::string& replacement, /*inout*/ std::string* str) { 1581*795d594fSAndroid Build Coastguard Worker size_t addr_index; 1582*795d594fSAndroid Build Coastguard Worker if ((addr_index = str->find(ADDRESS_TOKEN)) != std::string::npos) { 1583*795d594fSAndroid Build Coastguard Worker str->replace(addr_index, ConstexprStrLen(ADDRESS_TOKEN), replacement); 1584*795d594fSAndroid Build Coastguard Worker } 1585*795d594fSAndroid Build Coastguard Worker } 1586*795d594fSAndroid Build Coastguard Worker 1587*795d594fSAndroid Build Coastguard Worker static constexpr const char* ADDRESS_TOKEN = "{mem}"; 1588*795d594fSAndroid Build Coastguard Worker static constexpr const char* REG_TOKEN = "{reg}"; 1589*795d594fSAndroid Build Coastguard Worker static constexpr const char* REG1_TOKEN = "{reg1}"; 1590*795d594fSAndroid Build Coastguard Worker static constexpr const char* REG2_TOKEN = "{reg2}"; 1591*795d594fSAndroid Build Coastguard Worker static constexpr const char* REG3_TOKEN = "{reg3}"; 1592*795d594fSAndroid Build Coastguard Worker static constexpr const char* REG4_TOKEN = "{reg4}"; 1593*795d594fSAndroid Build Coastguard Worker static constexpr const char* IMM_TOKEN = "{imm}"; 1594*795d594fSAndroid Build Coastguard Worker 1595*795d594fSAndroid Build Coastguard Worker private: 1596*795d594fSAndroid Build Coastguard Worker template <RegisterView kRegView> RepeatRegisterImm(void (Ass::* f)(Reg,const Imm &),size_t imm_bytes,const std::string & fmt)1597*795d594fSAndroid Build Coastguard Worker std::string RepeatRegisterImm(void (Ass::*f)(Reg, const Imm&), 1598*795d594fSAndroid Build Coastguard Worker size_t imm_bytes, 1599*795d594fSAndroid Build Coastguard Worker const std::string& fmt) { 1600*795d594fSAndroid Build Coastguard Worker ArrayRef<const Reg> registers = GetRegisters(); 1601*795d594fSAndroid Build Coastguard Worker std::string str; 1602*795d594fSAndroid Build Coastguard Worker std::vector<int64_t> imms = CreateImmediateValues(imm_bytes); 1603*795d594fSAndroid Build Coastguard Worker 1604*795d594fSAndroid Build Coastguard Worker WarnOnCombinations(registers.size() * imms.size()); 1605*795d594fSAndroid Build Coastguard Worker 1606*795d594fSAndroid Build Coastguard Worker for (auto reg : registers) { 1607*795d594fSAndroid Build Coastguard Worker for (int64_t imm : imms) { 1608*795d594fSAndroid Build Coastguard Worker Imm new_imm = CreateImmediate(imm); 1609*795d594fSAndroid Build Coastguard Worker if (f != nullptr) { 1610*795d594fSAndroid Build Coastguard Worker (assembler_.get()->*f)(reg, new_imm); 1611*795d594fSAndroid Build Coastguard Worker } 1612*795d594fSAndroid Build Coastguard Worker std::string base = fmt; 1613*795d594fSAndroid Build Coastguard Worker 1614*795d594fSAndroid Build Coastguard Worker ReplaceReg(REG_TOKEN, GetRegName<kRegView>(reg), &base); 1615*795d594fSAndroid Build Coastguard Worker ReplaceImm(imm, /*bias=*/ 0, /*multiplier=*/ 1, &base); 1616*795d594fSAndroid Build Coastguard Worker 1617*795d594fSAndroid Build Coastguard Worker str += base; 1618*795d594fSAndroid Build Coastguard Worker str += "\n"; 1619*795d594fSAndroid Build Coastguard Worker } 1620*795d594fSAndroid Build Coastguard Worker } 1621*795d594fSAndroid Build Coastguard Worker return str; 1622*795d594fSAndroid Build Coastguard Worker } 1623*795d594fSAndroid Build Coastguard Worker 1624*795d594fSAndroid Build Coastguard Worker // Override this to pad the code with NOPs to a certain size if needed. Pad(std::vector<uint8_t> & data)1625*795d594fSAndroid Build Coastguard Worker virtual void Pad([[maybe_unused]] std::vector<uint8_t>& data) {} 1626*795d594fSAndroid Build Coastguard Worker DriverWrapper(const std::string & assembly_text,const std::string & test_name)1627*795d594fSAndroid Build Coastguard Worker void DriverWrapper(const std::string& assembly_text, const std::string& test_name) { 1628*795d594fSAndroid Build Coastguard Worker assembler_->FinalizeCode(); 1629*795d594fSAndroid Build Coastguard Worker size_t cs = assembler_->CodeSize(); 1630*795d594fSAndroid Build Coastguard Worker std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>(cs)); 1631*795d594fSAndroid Build Coastguard Worker MemoryRegion code(&(*data)[0], data->size()); 1632*795d594fSAndroid Build Coastguard Worker assembler_->CopyInstructions(code); 1633*795d594fSAndroid Build Coastguard Worker Pad(*data); 1634*795d594fSAndroid Build Coastguard Worker Driver(*data, assembly_text, test_name); 1635*795d594fSAndroid Build Coastguard Worker } 1636*795d594fSAndroid Build Coastguard Worker 1637*795d594fSAndroid Build Coastguard Worker static constexpr size_t kWarnManyCombinationsThreshold = 500; 1638*795d594fSAndroid Build Coastguard Worker 1639*795d594fSAndroid Build Coastguard Worker MallocArenaPool pool_; 1640*795d594fSAndroid Build Coastguard Worker std::unique_ptr<ArenaAllocator> allocator_; 1641*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Ass> assembler_; 1642*795d594fSAndroid Build Coastguard Worker 1643*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(AssemblerTest); 1644*795d594fSAndroid Build Coastguard Worker }; 1645*795d594fSAndroid Build Coastguard Worker 1646*795d594fSAndroid Build Coastguard Worker } // namespace art 1647*795d594fSAndroid Build Coastguard Worker 1648*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_UTILS_ASSEMBLER_TEST_H_ 1649