xref: /aosp_15_r20/art/compiler/utils/assembler_test.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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