1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ 18 #define ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ 19 20 #include "utils/assembler_test.h" 21 22 namespace art { 23 24 template<typename Ass, 25 typename Reg, 26 typename FPReg, 27 typename Imm, 28 typename SOp, 29 typename Cond, 30 typename SetCc> 31 class AssemblerArmTest : public AssemblerTest<Ass, Reg, FPReg, Imm> { 32 public: 33 typedef AssemblerTest<Ass, Reg, FPReg, Imm> Base; 34 35 using Base::GetRegisters; 36 using Base::GetRegName; 37 using Base::CreateImmediate; 38 using Base::WarnOnCombinations; 39 40 static constexpr int64_t kFullImmRangeThreshold = 32; 41 FillImmediates(std::vector<Imm> & immediates,int64_t imm_min,int64_t imm_max)42 virtual void FillImmediates(std::vector<Imm>& immediates, int64_t imm_min, int64_t imm_max) { 43 // Small range: do completely. 44 if (imm_max - imm_min <= kFullImmRangeThreshold) { 45 for (int64_t i = imm_min; i <= imm_max; ++i) { 46 immediates.push_back(CreateImmediate(i)); 47 } 48 } else { 49 immediates.push_back(CreateImmediate(imm_min)); 50 immediates.push_back(CreateImmediate(imm_max)); 51 if (imm_min < imm_max - 1) { 52 immediates.push_back(CreateImmediate(imm_min + 1)); 53 } 54 if (imm_min < imm_max - 2) { 55 immediates.push_back(CreateImmediate(imm_min + 2)); 56 } 57 if (imm_min < imm_max - 3) { 58 immediates.push_back(CreateImmediate(imm_max - 1)); 59 } 60 if (imm_min < imm_max - 4) { 61 immediates.push_back(CreateImmediate((imm_min + imm_max) / 2)); 62 } 63 } 64 } 65 RepeatRRIIC(void (Ass::* f)(Reg,Reg,Imm,Imm,Cond),int64_t imm1_min,int64_t imm1_max,int64_t imm2_min,int64_t imm2_max,std::string fmt)66 std::string RepeatRRIIC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond), 67 int64_t imm1_min, int64_t imm1_max, 68 int64_t imm2_min, int64_t imm2_max, 69 std::string fmt) { 70 return RepeatTemplatedRRIIC(f, GetRegisters(), GetRegisters(), 71 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 72 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 73 imm1_min, imm1_max, imm2_min, imm2_max, 74 fmt); 75 } 76 77 template <typename Reg1, typename Reg2> RepeatTemplatedRRIIC(void (Ass::* f)(Reg1,Reg2,Imm,Imm,Cond),const std::vector<Reg1 * > reg1_registers,const std::vector<Reg2 * > reg2_registers,std::string (AssemblerArmTest::* GetName1)(const Reg1 &),std::string (AssemblerArmTest::* GetName2)(const Reg2 &),int64_t imm1_min,int64_t imm1_max,int64_t imm2_min,int64_t imm2_max,std::string fmt)78 std::string RepeatTemplatedRRIIC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond), 79 const std::vector<Reg1*> reg1_registers, 80 const std::vector<Reg2*> reg2_registers, 81 std::string (AssemblerArmTest::*GetName1)(const Reg1&), 82 std::string (AssemblerArmTest::*GetName2)(const Reg2&), 83 int64_t imm1_min, int64_t imm1_max, 84 int64_t imm2_min, int64_t imm2_max, 85 std::string fmt) { 86 std::vector<Imm> immediates1; 87 FillImmediates(immediates1, imm1_min, imm1_max); 88 std::vector<Imm> immediates2; 89 FillImmediates(immediates2, imm2_min, imm2_max); 90 91 std::vector<Cond>& cond = GetConditions(); 92 93 WarnOnCombinations(cond.size() * immediates1.size() * immediates2.size() * 94 reg1_registers.size() * reg2_registers.size()); 95 96 std::ostringstream oss; 97 bool first = true; 98 for (Cond& c : cond) { 99 std::string after_cond = fmt; 100 101 size_t cond_index = after_cond.find(COND_TOKEN); 102 if (cond_index != std::string::npos) { 103 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 104 } 105 106 for (Imm i : immediates1) { 107 std::string base = after_cond; 108 109 size_t imm1_index = base.find(IMM1_TOKEN); 110 if (imm1_index != std::string::npos) { 111 std::ostringstream sreg; 112 sreg << i; 113 std::string imm_string = sreg.str(); 114 base.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string); 115 } 116 117 for (Imm j : immediates2) { 118 std::string base2 = base; 119 120 size_t imm2_index = base2.find(IMM2_TOKEN); 121 if (imm2_index != std::string::npos) { 122 std::ostringstream sreg; 123 sreg << j; 124 std::string imm_string = sreg.str(); 125 base2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string); 126 } 127 128 for (auto reg1 : reg1_registers) { 129 std::string base3 = base2; 130 131 std::string reg1_string = (this->*GetName1)(*reg1); 132 size_t reg1_index; 133 while ((reg1_index = base3.find(Base::REG1_TOKEN)) != std::string::npos) { 134 base3.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); 135 } 136 137 for (auto reg2 : reg2_registers) { 138 std::string base4 = base3; 139 140 std::string reg2_string = (this->*GetName2)(*reg2); 141 size_t reg2_index; 142 while ((reg2_index = base4.find(Base::REG2_TOKEN)) != std::string::npos) { 143 base4.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); 144 } 145 146 if (first) { 147 first = false; 148 } else { 149 oss << "\n"; 150 } 151 oss << base4; 152 153 (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c); 154 } 155 } 156 } 157 } 158 } 159 // Add a newline at the end. 160 oss << "\n"; 161 162 return oss.str(); 163 } 164 RepeatRRiiC(void (Ass::* f)(Reg,Reg,Imm,Imm,Cond),std::vector<std::pair<Imm,Imm>> & immediates,std::string fmt)165 std::string RepeatRRiiC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond), 166 std::vector<std::pair<Imm, Imm>>& immediates, 167 std::string fmt) { 168 return RepeatTemplatedRRiiC<Reg, Reg>(f, GetRegisters(), GetRegisters(), 169 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 170 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 171 immediates, fmt); 172 } 173 174 template <typename Reg1, typename Reg2> RepeatTemplatedRRiiC(void (Ass::* f)(Reg1,Reg2,Imm,Imm,Cond),const std::vector<Reg1 * > reg1_registers,const std::vector<Reg2 * > reg2_registers,std::string (AssemblerArmTest::* GetName1)(const Reg1 &),std::string (AssemblerArmTest::* GetName2)(const Reg2 &),std::vector<std::pair<Imm,Imm>> & immediates,std::string fmt)175 std::string RepeatTemplatedRRiiC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond), 176 const std::vector<Reg1*> reg1_registers, 177 const std::vector<Reg2*> reg2_registers, 178 std::string (AssemblerArmTest::*GetName1)(const Reg1&), 179 std::string (AssemblerArmTest::*GetName2)(const Reg2&), 180 std::vector<std::pair<Imm, Imm>>& immediates, 181 std::string fmt) { 182 std::vector<Cond>& cond = GetConditions(); 183 184 WarnOnCombinations(cond.size() * immediates.size() * reg1_registers.size() * 185 reg2_registers.size()); 186 187 std::ostringstream oss; 188 bool first = true; 189 for (Cond& c : cond) { 190 std::string after_cond = fmt; 191 192 size_t cond_index = after_cond.find(COND_TOKEN); 193 if (cond_index != std::string::npos) { 194 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 195 } 196 197 for (std::pair<Imm, Imm>& pair : immediates) { 198 Imm i = pair.first; 199 Imm j = pair.second; 200 std::string after_imm1 = after_cond; 201 202 size_t imm1_index = after_imm1.find(IMM1_TOKEN); 203 if (imm1_index != std::string::npos) { 204 std::ostringstream sreg; 205 sreg << i; 206 std::string imm_string = sreg.str(); 207 after_imm1.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string); 208 } 209 210 std::string after_imm2 = after_imm1; 211 212 size_t imm2_index = after_imm2.find(IMM2_TOKEN); 213 if (imm2_index != std::string::npos) { 214 std::ostringstream sreg; 215 sreg << j; 216 std::string imm_string = sreg.str(); 217 after_imm2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string); 218 } 219 220 for (auto reg1 : reg1_registers) { 221 std::string after_reg1 = after_imm2; 222 223 std::string reg1_string = (this->*GetName1)(*reg1); 224 size_t reg1_index; 225 while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { 226 after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); 227 } 228 229 for (auto reg2 : reg2_registers) { 230 std::string after_reg2 = after_reg1; 231 232 std::string reg2_string = (this->*GetName2)(*reg2); 233 size_t reg2_index; 234 while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { 235 after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); 236 } 237 238 if (first) { 239 first = false; 240 } else { 241 oss << "\n"; 242 } 243 oss << after_reg2; 244 245 (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c); 246 } 247 } 248 } 249 } 250 // Add a newline at the end. 251 oss << "\n"; 252 253 return oss.str(); 254 } 255 RepeatRRC(void (Ass::* f)(Reg,Reg,Cond),std::string fmt)256 std::string RepeatRRC(void (Ass::*f)(Reg, Reg, Cond), std::string fmt) { 257 return RepeatTemplatedRRC(f, GetRegisters(), GetRegisters(), GetConditions(), 258 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 259 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 260 fmt); 261 } 262 263 template <typename Reg1, typename Reg2> RepeatTemplatedRRC(void (Ass::* f)(Reg1,Reg2,Cond),const std::vector<Reg1 * > & reg1_registers,const std::vector<Reg2 * > & reg2_registers,const std::vector<Cond> & cond,std::string (AssemblerArmTest::* GetName1)(const Reg1 &),std::string (AssemblerArmTest::* GetName2)(const Reg2 &),std::string fmt)264 std::string RepeatTemplatedRRC(void (Ass::*f)(Reg1, Reg2, Cond), 265 const std::vector<Reg1*>& reg1_registers, 266 const std::vector<Reg2*>& reg2_registers, 267 const std::vector<Cond>& cond, 268 std::string (AssemblerArmTest::*GetName1)(const Reg1&), 269 std::string (AssemblerArmTest::*GetName2)(const Reg2&), 270 std::string fmt) { 271 WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size()); 272 273 std::ostringstream oss; 274 bool first = true; 275 for (const Cond& c : cond) { 276 std::string after_cond = fmt; 277 278 size_t cond_index = after_cond.find(COND_TOKEN); 279 if (cond_index != std::string::npos) { 280 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 281 } 282 283 for (auto reg1 : reg1_registers) { 284 std::string after_reg1 = after_cond; 285 286 std::string reg1_string = (this->*GetName1)(*reg1); 287 size_t reg1_index; 288 while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { 289 after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); 290 } 291 292 for (auto reg2 : reg2_registers) { 293 std::string after_reg2 = after_reg1; 294 295 std::string reg2_string = (this->*GetName2)(*reg2); 296 size_t reg2_index; 297 while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { 298 after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); 299 } 300 301 if (first) { 302 first = false; 303 } else { 304 oss << "\n"; 305 } 306 oss << after_reg2; 307 308 (Base::GetAssembler()->*f)(*reg1, *reg2, c); 309 } 310 } 311 } 312 // Add a newline at the end. 313 oss << "\n"; 314 315 return oss.str(); 316 } 317 RepeatRRRC(void (Ass::* f)(Reg,Reg,Reg,Cond),std::string fmt)318 std::string RepeatRRRC(void (Ass::*f)(Reg, Reg, Reg, Cond), std::string fmt) { 319 return RepeatTemplatedRRRC(f, GetRegisters(), GetRegisters(), GetRegisters(), GetConditions(), 320 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 321 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 322 &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, 323 fmt); 324 } 325 326 template <typename Reg1, typename Reg2, typename Reg3> RepeatTemplatedRRRC(void (Ass::* f)(Reg1,Reg2,Reg3,Cond),const std::vector<Reg1 * > & reg1_registers,const std::vector<Reg2 * > & reg2_registers,const std::vector<Reg3 * > & reg3_registers,const std::vector<Cond> & cond,std::string (AssemblerArmTest::* GetName1)(const Reg1 &),std::string (AssemblerArmTest::* GetName2)(const Reg2 &),std::string (AssemblerArmTest::* GetName3)(const Reg3 &),std::string fmt)327 std::string RepeatTemplatedRRRC(void (Ass::*f)(Reg1, Reg2, Reg3, Cond), 328 const std::vector<Reg1*>& reg1_registers, 329 const std::vector<Reg2*>& reg2_registers, 330 const std::vector<Reg3*>& reg3_registers, 331 const std::vector<Cond>& cond, 332 std::string (AssemblerArmTest::*GetName1)(const Reg1&), 333 std::string (AssemblerArmTest::*GetName2)(const Reg2&), 334 std::string (AssemblerArmTest::*GetName3)(const Reg3&), 335 std::string fmt) { 336 WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() * 337 reg3_registers.size()); 338 339 std::ostringstream oss; 340 bool first = true; 341 for (const Cond& c : cond) { 342 std::string after_cond = fmt; 343 344 size_t cond_index = after_cond.find(COND_TOKEN); 345 if (cond_index != std::string::npos) { 346 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 347 } 348 349 for (auto reg1 : reg1_registers) { 350 std::string after_reg1 = after_cond; 351 352 std::string reg1_string = (this->*GetName1)(*reg1); 353 size_t reg1_index; 354 while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { 355 after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); 356 } 357 358 for (auto reg2 : reg2_registers) { 359 std::string after_reg2 = after_reg1; 360 361 std::string reg2_string = (this->*GetName2)(*reg2); 362 size_t reg2_index; 363 while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { 364 after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); 365 } 366 367 for (auto reg3 : reg3_registers) { 368 std::string after_reg3 = after_reg2; 369 370 std::string reg3_string = (this->*GetName3)(*reg3); 371 size_t reg3_index; 372 while ((reg3_index = after_reg3.find(REG3_TOKEN)) != std::string::npos) { 373 after_reg3.replace(reg3_index, ConstexprStrLen(REG3_TOKEN), reg3_string); 374 } 375 376 if (first) { 377 first = false; 378 } else { 379 oss << "\n"; 380 } 381 oss << after_reg3; 382 383 (Base::GetAssembler()->*f)(*reg1, *reg2, *reg3, c); 384 } 385 } 386 } 387 } 388 // Add a newline at the end. 389 oss << "\n"; 390 391 return oss.str(); 392 } 393 394 template <typename RegT> RepeatTemplatedRSC(void (Ass::* f)(RegT,SOp,Cond),const std::vector<RegT * > & registers,const std::vector<SOp> & shifts,const std::vector<Cond> & cond,std::string (AssemblerArmTest::* GetName)(const RegT &),std::string fmt)395 std::string RepeatTemplatedRSC(void (Ass::*f)(RegT, SOp, Cond), 396 const std::vector<RegT*>& registers, 397 const std::vector<SOp>& shifts, 398 const std::vector<Cond>& cond, 399 std::string (AssemblerArmTest::*GetName)(const RegT&), 400 std::string fmt) { 401 WarnOnCombinations(cond.size() * registers.size() * shifts.size()); 402 403 std::ostringstream oss; 404 bool first = true; 405 for (const Cond& c : cond) { 406 std::string after_cond = fmt; 407 408 size_t cond_index = after_cond.find(COND_TOKEN); 409 if (cond_index != std::string::npos) { 410 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 411 } 412 413 for (const SOp& shift : shifts) { 414 std::string after_shift = after_cond; 415 416 std::string shift_string = GetShiftString(shift); 417 size_t shift_index; 418 while ((shift_index = after_shift.find(Base::SHIFT_TOKEN)) != std::string::npos) { 419 after_shift.replace(shift_index, ConstexprStrLen(Base::SHIFT_TOKEN), shift_string); 420 } 421 422 for (auto reg : registers) { 423 std::string after_reg = after_shift; 424 425 std::string reg_string = (this->*GetName)(*reg); 426 size_t reg_index; 427 while ((reg_index = after_reg.find(Base::REG_TOKEN)) != std::string::npos) { 428 after_reg.replace(reg_index, ConstexprStrLen(Base::REG_TOKEN), reg_string); 429 } 430 431 if (first) { 432 first = false; 433 } else { 434 oss << "\n"; 435 } 436 oss << after_reg; 437 438 (Base::GetAssembler()->*f)(*reg, shift, c); 439 } 440 } 441 } 442 // Add a newline at the end. 443 oss << "\n"; 444 445 return oss.str(); 446 } 447 448 template <typename Reg1, typename Reg2> RepeatTemplatedRRSC(void (Ass::* f)(Reg1,Reg2,const SOp &,Cond),const std::vector<Reg1 * > & reg1_registers,const std::vector<Reg2 * > & reg2_registers,const std::vector<SOp> & shifts,const std::vector<Cond> & cond,std::string (AssemblerArmTest::* GetName1)(const Reg1 &),std::string (AssemblerArmTest::* GetName2)(const Reg2 &),std::string fmt)449 std::string RepeatTemplatedRRSC(void (Ass::*f)(Reg1, Reg2, const SOp&, Cond), 450 const std::vector<Reg1*>& reg1_registers, 451 const std::vector<Reg2*>& reg2_registers, 452 const std::vector<SOp>& shifts, 453 const std::vector<Cond>& cond, 454 std::string (AssemblerArmTest::*GetName1)(const Reg1&), 455 std::string (AssemblerArmTest::*GetName2)(const Reg2&), 456 std::string fmt) { 457 WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() * shifts.size()); 458 459 std::ostringstream oss; 460 bool first = true; 461 for (const Cond& c : cond) { 462 std::string after_cond = fmt; 463 464 size_t cond_index = after_cond.find(COND_TOKEN); 465 if (cond_index != std::string::npos) { 466 after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); 467 } 468 469 for (const SOp& shift : shifts) { 470 std::string after_shift = after_cond; 471 472 std::string shift_string = GetShiftString(shift); 473 size_t shift_index; 474 while ((shift_index = after_shift.find(SHIFT_TOKEN)) != std::string::npos) { 475 after_shift.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string); 476 } 477 478 for (auto reg1 : reg1_registers) { 479 std::string after_reg1 = after_shift; 480 481 std::string reg1_string = (this->*GetName1)(*reg1); 482 size_t reg1_index; 483 while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { 484 after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); 485 } 486 487 for (auto reg2 : reg2_registers) { 488 std::string after_reg2 = after_reg1; 489 490 std::string reg2_string = (this->*GetName2)(*reg2); 491 size_t reg2_index; 492 while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { 493 after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); 494 } 495 496 if (first) { 497 first = false; 498 } else { 499 oss << "\n"; 500 } 501 oss << after_reg2; 502 503 (Base::GetAssembler()->*f)(*reg1, *reg2, shift, c); 504 } 505 } 506 } 507 } 508 // Add a newline at the end. 509 oss << "\n"; 510 511 return oss.str(); 512 } 513 514 protected: AssemblerArmTest()515 explicit AssemblerArmTest() {} 516 517 virtual std::vector<Cond>& GetConditions() = 0; 518 virtual std::string GetConditionString(Cond c) = 0; 519 520 virtual std::vector<SetCc>& GetSetCcs() = 0; 521 virtual std::string GetSetCcString(SetCc s) = 0; 522 523 virtual std::vector<SOp>& GetShiftOperands() = 0; 524 virtual std::string GetShiftString(SOp sop) = 0; 525 526 virtual Reg GetPCRegister() = 0; GetRegistersWithoutPC()527 virtual std::vector<Reg*> GetRegistersWithoutPC() { 528 std::vector<Reg*> without_pc = GetRegisters(); 529 Reg pc_reg = GetPCRegister(); 530 531 for (auto it = without_pc.begin(); it != without_pc.end(); ++it) { 532 if (**it == pc_reg) { 533 without_pc.erase(it); 534 break; 535 } 536 } 537 538 return without_pc; 539 } 540 541 static constexpr const char* IMM1_TOKEN = "{imm1}"; 542 static constexpr const char* IMM2_TOKEN = "{imm2}"; 543 static constexpr const char* REG3_TOKEN = "{reg3}"; 544 static constexpr const char* REG4_TOKEN = "{reg4}"; 545 static constexpr const char* COND_TOKEN = "{cond}"; 546 static constexpr const char* SET_CC_TOKEN = "{s}"; 547 static constexpr const char* SHIFT_TOKEN = "{shift}"; 548 549 private: 550 DISALLOW_COPY_AND_ASSIGN(AssemblerArmTest); 551 }; 552 553 } // namespace art 554 555 #endif // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ 556