1 #pragma once 2 3 #include <deque> 4 #include "Jitter_CodeGen.h" 5 #include "AArch64Assembler.h" 6 7 namespace Jitter 8 { 9 class CCodeGen_AArch64 : public CCodeGen 10 { 11 public: 12 CCodeGen_AArch64(); 13 virtual ~CCodeGen_AArch64(); 14 15 void SetGenerateRelocatableCalls(bool); 16 17 void GenerateCode(const StatementList&, unsigned int) override; 18 void SetStream(Framework::CStream*) override; 19 void RegisterExternalSymbols(CObjectFile*) const override; 20 unsigned int GetAvailableRegisterCount() const override; 21 unsigned int GetAvailableMdRegisterCount() const override; 22 bool CanHold128BitsReturnValueInRegisters() const override; 23 24 private: 25 typedef std::map<uint32, CAArch64Assembler::LABEL> LabelMapType; 26 typedef void (CCodeGen_AArch64::*ConstCodeEmitterType)(const STATEMENT&); 27 28 struct ADDSUB_IMM_PARAMS 29 { 30 uint16 imm = 0; 31 CAArch64Assembler::ADDSUB_IMM_SHIFT_TYPE shiftType = CAArch64Assembler::ADDSUB_IMM_SHIFT_LSL0; 32 }; 33 34 struct LOGICAL_IMM_PARAMS 35 { 36 uint8 n; 37 uint8 immr; 38 uint8 imms; 39 }; 40 41 struct PARAM_STATE 42 { 43 bool prepared = false; 44 unsigned int index = 0; 45 uint32 spillOffset = 0; 46 }; 47 48 typedef std::function<void (PARAM_STATE&)> ParamEmitterFunction; 49 typedef std::deque<ParamEmitterFunction> ParamStack; 50 51 enum 52 { 53 MAX_REGISTERS = 9, 54 }; 55 56 enum 57 { 58 MAX_MDREGISTERS = 28, 59 }; 60 61 enum MAX_PARAM_REGS 62 { 63 MAX_PARAM_REGS = 8, 64 }; 65 66 enum MAX_TEMP_REGS 67 { 68 MAX_TEMP_REGS = 7, 69 }; 70 71 enum MAX_TEMP_MD_REGS 72 { 73 MAX_TEMP_MD_REGS = 4, 74 }; 75 76 struct CONSTMATCHER 77 { 78 OPERATION op; 79 MATCHTYPE dstType; 80 MATCHTYPE src1Type; 81 MATCHTYPE src2Type; 82 ConstCodeEmitterType emitter; 83 }; 84 85 static uint32 GetMaxParamSpillSize(const StatementList&); 86 87 CAArch64Assembler::REGISTER32 GetNextTempRegister(); 88 CAArch64Assembler::REGISTER64 GetNextTempRegister64(); 89 CAArch64Assembler::REGISTERMD GetNextTempRegisterMd(); 90 91 uint32 GetMemory64Offset(CSymbol*) const; 92 93 void LoadMemoryInRegister(CAArch64Assembler::REGISTER32, CSymbol*); 94 void StoreRegisterInMemory(CSymbol*, CAArch64Assembler::REGISTER32); 95 96 void LoadMemory64InRegister(CAArch64Assembler::REGISTER64, CSymbol*); 97 void StoreRegisterInMemory64(CSymbol*, CAArch64Assembler::REGISTER64); 98 99 void LoadConstantInRegister(CAArch64Assembler::REGISTER32, uint32); 100 void LoadConstant64InRegister(CAArch64Assembler::REGISTER64, uint64); 101 102 void LoadMemory64LowInRegister(CAArch64Assembler::REGISTER32, CSymbol*); 103 void LoadMemory64HighInRegister(CAArch64Assembler::REGISTER32, CSymbol*); 104 105 void LoadSymbol64InRegister(CAArch64Assembler::REGISTER64, CSymbol*); 106 107 void StoreRegistersInMemory64(CSymbol*, CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32); 108 109 void LoadMemoryReferenceInRegister(CAArch64Assembler::REGISTER64, CSymbol*); 110 void StoreRegisterInTemporaryReference(CSymbol*, CAArch64Assembler::REGISTER64); 111 112 void LoadMemoryFpSingleInRegister(CAArch64Assembler::REGISTERMD, CSymbol*); 113 void StoreRegisterInMemoryFpSingle(CSymbol*, CAArch64Assembler::REGISTERMD); 114 115 void LoadMemory128InRegister(CAArch64Assembler::REGISTERMD, CSymbol*); 116 void StoreRegisterInMemory128(CSymbol*, CAArch64Assembler::REGISTERMD); 117 118 void LoadMemory128AddressInRegister(CAArch64Assembler::REGISTER64, CSymbol*, uint32 = 0); 119 void LoadRelative128AddressInRegister(CAArch64Assembler::REGISTER64, CSymbol*, uint32); 120 void LoadTemporary128AddressInRegister(CAArch64Assembler::REGISTER64, CSymbol*, uint32); 121 122 void LoadTemporary256ElementAddressInRegister(CAArch64Assembler::REGISTER64, CSymbol*, uint32); 123 124 CAArch64Assembler::REGISTER32 PrepareSymbolRegisterDef(CSymbol*, CAArch64Assembler::REGISTER32); 125 CAArch64Assembler::REGISTER32 PrepareSymbolRegisterUse(CSymbol*, CAArch64Assembler::REGISTER32); 126 void CommitSymbolRegister(CSymbol*, CAArch64Assembler::REGISTER32); 127 128 CAArch64Assembler::REGISTERMD PrepareSymbolRegisterDefMd(CSymbol*, CAArch64Assembler::REGISTERMD); 129 CAArch64Assembler::REGISTERMD PrepareSymbolRegisterUseMd(CSymbol*, CAArch64Assembler::REGISTERMD); 130 void CommitSymbolRegisterMd(CSymbol*, CAArch64Assembler::REGISTERMD); 131 132 CAArch64Assembler::REGISTER32 PrepareParam(PARAM_STATE&); 133 CAArch64Assembler::REGISTER64 PrepareParam64(PARAM_STATE&); 134 void CommitParam(PARAM_STATE&); 135 void CommitParam64(PARAM_STATE&); 136 137 bool TryGetAddSubImmParams(uint32, ADDSUB_IMM_PARAMS&); 138 bool TryGetAddSub64ImmParams(uint64, ADDSUB_IMM_PARAMS&); 139 bool TryGetLogicalImmParams(uint32, LOGICAL_IMM_PARAMS&); 140 141 //SHIFTOP ---------------------------------------------------------- 142 struct SHIFTOP_BASE 143 { 144 typedef void (CAArch64Assembler::*OpImmType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, uint8); 145 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32); 146 }; 147 148 struct SHIFTOP_ASR : public SHIFTOP_BASE 149 { OpImmSHIFTOP_ASR150 static OpImmType OpImm() { return &CAArch64Assembler::Asr; } OpRegSHIFTOP_ASR151 static OpRegType OpReg() { return &CAArch64Assembler::Asrv; } 152 }; 153 154 struct SHIFTOP_LSL : public SHIFTOP_BASE 155 { OpImmSHIFTOP_LSL156 static OpImmType OpImm() { return &CAArch64Assembler::Lsl; } OpRegSHIFTOP_LSL157 static OpRegType OpReg() { return &CAArch64Assembler::Lslv; } 158 }; 159 160 struct SHIFTOP_LSR : public SHIFTOP_BASE 161 { OpImmSHIFTOP_LSR162 static OpImmType OpImm() { return &CAArch64Assembler::Lsr; } OpRegSHIFTOP_LSR163 static OpRegType OpReg() { return &CAArch64Assembler::Lsrv; } 164 }; 165 166 //LOGICOP ---------------------------------------------------------- 167 struct LOGICOP_BASE 168 { 169 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32); 170 typedef void (CAArch64Assembler::*OpImmType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, uint8, uint8, uint8); 171 }; 172 173 struct LOGICOP_AND : public LOGICOP_BASE 174 { OpRegLOGICOP_AND175 static OpRegType OpReg() { return &CAArch64Assembler::And; } OpImmLOGICOP_AND176 static OpImmType OpImm() { return &CAArch64Assembler::And; } 177 }; 178 179 struct LOGICOP_OR : public LOGICOP_BASE 180 { OpRegLOGICOP_OR181 static OpRegType OpReg() { return &CAArch64Assembler::Orr; } OpImmLOGICOP_OR182 static OpImmType OpImm() { return &CAArch64Assembler::Orr; } 183 }; 184 185 struct LOGICOP_XOR : public LOGICOP_BASE 186 { OpRegLOGICOP_XOR187 static OpRegType OpReg() { return &CAArch64Assembler::Eor; } OpImmLOGICOP_XOR188 static OpImmType OpImm() { return &CAArch64Assembler::Eor; } 189 }; 190 191 //ADDSUBOP ---------------------------------------------------------- 192 struct ADDSUBOP_BASE 193 { 194 typedef void (CAArch64Assembler::*OpImmType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, uint16 imm, CAArch64Assembler::ADDSUB_IMM_SHIFT_TYPE); 195 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32, CAArch64Assembler::REGISTER32); 196 }; 197 198 struct ADDSUBOP_ADD : public ADDSUBOP_BASE 199 { OpImmADDSUBOP_ADD200 static OpImmType OpImm() { return &CAArch64Assembler::Add; } OpRegADDSUBOP_ADD201 static OpRegType OpReg() { return &CAArch64Assembler::Add; } OpImmRevADDSUBOP_ADD202 static OpImmType OpImmRev() { return &CAArch64Assembler::Sub; } 203 }; 204 205 struct ADDSUBOP_SUB : public ADDSUBOP_BASE 206 { OpImmADDSUBOP_SUB207 static OpImmType OpImm() { return &CAArch64Assembler::Sub; } OpRegADDSUBOP_SUB208 static OpRegType OpReg() { return &CAArch64Assembler::Sub; } OpImmRevADDSUBOP_SUB209 static OpImmType OpImmRev() { return &CAArch64Assembler::Add; } 210 }; 211 212 //SHIFT64OP ---------------------------------------------------------- 213 struct SHIFT64OP_BASE 214 { 215 typedef void (CAArch64Assembler::*OpImmType)(CAArch64Assembler::REGISTER64, CAArch64Assembler::REGISTER64, uint8); 216 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTER64, CAArch64Assembler::REGISTER64, CAArch64Assembler::REGISTER64); 217 }; 218 219 struct SHIFT64OP_ASR : public SHIFT64OP_BASE 220 { OpImmSHIFT64OP_ASR221 static OpImmType OpImm() { return &CAArch64Assembler::Asr; } OpRegSHIFT64OP_ASR222 static OpRegType OpReg() { return &CAArch64Assembler::Asrv; } 223 }; 224 225 struct SHIFT64OP_LSL : public SHIFT64OP_BASE 226 { OpImmSHIFT64OP_LSL227 static OpImmType OpImm() { return &CAArch64Assembler::Lsl; } OpRegSHIFT64OP_LSL228 static OpRegType OpReg() { return &CAArch64Assembler::Lslv; } 229 }; 230 231 struct SHIFT64OP_LSR : public SHIFT64OP_BASE 232 { OpImmSHIFT64OP_LSR233 static OpImmType OpImm() { return &CAArch64Assembler::Lsr; } OpRegSHIFT64OP_LSR234 static OpRegType OpReg() { return &CAArch64Assembler::Lsrv; } 235 }; 236 237 //FPUOP ---------------------------------------------------------- 238 struct FPUOP_BASE2 239 { 240 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD); 241 }; 242 243 struct FPUOP_BASE3 244 { 245 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD); 246 }; 247 248 struct FPUOP_ADD : public FPUOP_BASE3 249 { OpRegFPUOP_ADD250 static OpRegType OpReg() { return &CAArch64Assembler::Fadd_1s; } 251 }; 252 253 struct FPUOP_SUB : public FPUOP_BASE3 254 { OpRegFPUOP_SUB255 static OpRegType OpReg() { return &CAArch64Assembler::Fsub_1s; } 256 }; 257 258 struct FPUOP_MUL : public FPUOP_BASE3 259 { OpRegFPUOP_MUL260 static OpRegType OpReg() { return &CAArch64Assembler::Fmul_1s; } 261 }; 262 263 struct FPUOP_DIV : public FPUOP_BASE3 264 { OpRegFPUOP_DIV265 static OpRegType OpReg() { return &CAArch64Assembler::Fdiv_1s; } 266 }; 267 268 struct FPUOP_MIN : public FPUOP_BASE3 269 { OpRegFPUOP_MIN270 static OpRegType OpReg() { return &CAArch64Assembler::Fmin_1s; } 271 }; 272 273 struct FPUOP_MAX : public FPUOP_BASE3 274 { OpRegFPUOP_MAX275 static OpRegType OpReg() { return &CAArch64Assembler::Fmax_1s; } 276 }; 277 278 struct FPUOP_ABS : public FPUOP_BASE2 279 { OpRegFPUOP_ABS280 static OpRegType OpReg() { return &CAArch64Assembler::Fabs_1s; } 281 }; 282 283 struct FPUOP_NEG : public FPUOP_BASE2 284 { OpRegFPUOP_NEG285 static OpRegType OpReg() { return &CAArch64Assembler::Fneg_1s; } 286 }; 287 288 struct FPUOP_SQRT : public FPUOP_BASE2 289 { OpRegFPUOP_SQRT290 static OpRegType OpReg() { return &CAArch64Assembler::Fsqrt_1s; } 291 }; 292 293 //MDOP ----------------------------------------------------------- 294 struct MDOP_BASE2 295 { 296 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD); 297 }; 298 299 struct MDOP_BASE3 300 { 301 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD); 302 }; 303 304 struct MDOP_SHIFT 305 { 306 typedef void (CAArch64Assembler::*OpRegType)(CAArch64Assembler::REGISTERMD, CAArch64Assembler::REGISTERMD, uint8); 307 }; 308 309 struct MDOP_ADDB : public MDOP_BASE3 310 { OpRegMDOP_ADDB311 static OpRegType OpReg() { return &CAArch64Assembler::Add_16b; } 312 }; 313 314 struct MDOP_ADDH : public MDOP_BASE3 315 { OpRegMDOP_ADDH316 static OpRegType OpReg() { return &CAArch64Assembler::Add_8h; } 317 }; 318 319 struct MDOP_ADDW : public MDOP_BASE3 320 { OpRegMDOP_ADDW321 static OpRegType OpReg() { return &CAArch64Assembler::Add_4s; } 322 }; 323 324 struct MDOP_ADDBUS : public MDOP_BASE3 325 { OpRegMDOP_ADDBUS326 static OpRegType OpReg() { return &CAArch64Assembler::Uqadd_16b; } 327 }; 328 329 struct MDOP_ADDHUS : public MDOP_BASE3 330 { OpRegMDOP_ADDHUS331 static OpRegType OpReg() { return &CAArch64Assembler::Uqadd_8h; } 332 }; 333 334 struct MDOP_ADDWUS : public MDOP_BASE3 335 { OpRegMDOP_ADDWUS336 static OpRegType OpReg() { return &CAArch64Assembler::Uqadd_4s; } 337 }; 338 339 struct MDOP_ADDHSS : public MDOP_BASE3 340 { OpRegMDOP_ADDHSS341 static OpRegType OpReg() { return &CAArch64Assembler::Sqadd_8h; } 342 }; 343 344 struct MDOP_ADDWSS : public MDOP_BASE3 345 { OpRegMDOP_ADDWSS346 static OpRegType OpReg() { return &CAArch64Assembler::Sqadd_4s; } 347 }; 348 349 struct MDOP_SUBB : public MDOP_BASE3 350 { OpRegMDOP_SUBB351 static OpRegType OpReg() { return &CAArch64Assembler::Sub_16b; } 352 }; 353 354 struct MDOP_SUBH : public MDOP_BASE3 355 { OpRegMDOP_SUBH356 static OpRegType OpReg() { return &CAArch64Assembler::Sub_8h; } 357 }; 358 359 struct MDOP_SUBW : public MDOP_BASE3 360 { OpRegMDOP_SUBW361 static OpRegType OpReg() { return &CAArch64Assembler::Sub_4s; } 362 }; 363 364 struct MDOP_SUBBUS : public MDOP_BASE3 365 { OpRegMDOP_SUBBUS366 static OpRegType OpReg() { return &CAArch64Assembler::Uqsub_16b; } 367 }; 368 369 struct MDOP_SUBHUS : public MDOP_BASE3 370 { OpRegMDOP_SUBHUS371 static OpRegType OpReg() { return &CAArch64Assembler::Uqsub_8h; } 372 }; 373 374 struct MDOP_SUBHSS : public MDOP_BASE3 375 { OpRegMDOP_SUBHSS376 static OpRegType OpReg() { return &CAArch64Assembler::Sqsub_8h; } 377 }; 378 379 struct MDOP_SUBWSS : public MDOP_BASE3 380 { OpRegMDOP_SUBWSS381 static OpRegType OpReg() { return &CAArch64Assembler::Sqsub_4s; } 382 }; 383 384 struct MDOP_CMPEQW : public MDOP_BASE3 385 { OpRegMDOP_CMPEQW386 static OpRegType OpReg() { return &CAArch64Assembler::Cmeq_4s; } 387 }; 388 389 struct MDOP_CMPGTH : public MDOP_BASE3 390 { OpRegMDOP_CMPGTH391 static OpRegType OpReg() { return &CAArch64Assembler::Cmgt_4s; } 392 }; 393 394 struct MDOP_MINH : public MDOP_BASE3 395 { OpRegMDOP_MINH396 static OpRegType OpReg() { return &CAArch64Assembler::Smin_8h; } 397 }; 398 399 struct MDOP_MINW : public MDOP_BASE3 400 { OpRegMDOP_MINW401 static OpRegType OpReg() { return &CAArch64Assembler::Smin_4s; } 402 }; 403 404 struct MDOP_MAXH : public MDOP_BASE3 405 { OpRegMDOP_MAXH406 static OpRegType OpReg() { return &CAArch64Assembler::Smax_8h; } 407 }; 408 409 struct MDOP_MAXW : public MDOP_BASE3 410 { OpRegMDOP_MAXW411 static OpRegType OpReg() { return &CAArch64Assembler::Smax_4s; } 412 }; 413 414 struct MDOP_ADDS : public MDOP_BASE3 415 { OpRegMDOP_ADDS416 static OpRegType OpReg() { return &CAArch64Assembler::Fadd_4s; } 417 }; 418 419 struct MDOP_SUBS : public MDOP_BASE3 420 { OpRegMDOP_SUBS421 static OpRegType OpReg() { return &CAArch64Assembler::Fsub_4s; } 422 }; 423 424 struct MDOP_MULS : public MDOP_BASE3 425 { OpRegMDOP_MULS426 static OpRegType OpReg() { return &CAArch64Assembler::Fmul_4s; } 427 }; 428 429 struct MDOP_DIVS : public MDOP_BASE3 430 { OpRegMDOP_DIVS431 static OpRegType OpReg() { return &CAArch64Assembler::Fdiv_4s; } 432 }; 433 434 struct MDOP_ABSS : public MDOP_BASE2 435 { OpRegMDOP_ABSS436 static OpRegType OpReg() { return &CAArch64Assembler::Fabs_4s; } 437 }; 438 439 struct MDOP_MINS : public MDOP_BASE3 440 { OpRegMDOP_MINS441 static OpRegType OpReg() { return &CAArch64Assembler::Fmin_4s; } 442 }; 443 444 struct MDOP_MAXS : public MDOP_BASE3 445 { OpRegMDOP_MAXS446 static OpRegType OpReg() { return &CAArch64Assembler::Fmax_4s; } 447 }; 448 449 struct MDOP_TOSINGLE : public MDOP_BASE2 450 { OpRegMDOP_TOSINGLE451 static OpRegType OpReg() { return &CAArch64Assembler::Scvtf_4s; } 452 }; 453 454 struct MDOP_TOWORD : public MDOP_BASE2 455 { OpRegMDOP_TOWORD456 static OpRegType OpReg() { return &CAArch64Assembler::Fcvtzs_4s; } 457 }; 458 459 struct MDOP_AND : public MDOP_BASE3 460 { OpRegMDOP_AND461 static OpRegType OpReg() { return &CAArch64Assembler::And_16b; } 462 }; 463 464 struct MDOP_OR : public MDOP_BASE3 465 { OpRegMDOP_OR466 static OpRegType OpReg() { return &CAArch64Assembler::Orr_16b; } 467 }; 468 469 struct MDOP_XOR : public MDOP_BASE3 470 { OpRegMDOP_XOR471 static OpRegType OpReg() { return &CAArch64Assembler::Eor_16b; } 472 }; 473 474 struct MDOP_UNPACK_LOWER_BH : public MDOP_BASE3 475 { OpRegMDOP_UNPACK_LOWER_BH476 static OpRegType OpReg() { return &CAArch64Assembler::Zip1_16b; } 477 }; 478 479 struct MDOP_UNPACK_LOWER_HW : public MDOP_BASE3 480 { OpRegMDOP_UNPACK_LOWER_HW481 static OpRegType OpReg() { return &CAArch64Assembler::Zip1_8h; } 482 }; 483 484 struct MDOP_UNPACK_LOWER_WD : public MDOP_BASE3 485 { OpRegMDOP_UNPACK_LOWER_WD486 static OpRegType OpReg() { return &CAArch64Assembler::Zip1_4s; } 487 }; 488 489 struct MDOP_UNPACK_UPPER_BH : public MDOP_BASE3 490 { OpRegMDOP_UNPACK_UPPER_BH491 static OpRegType OpReg() { return &CAArch64Assembler::Zip2_16b; } 492 }; 493 494 struct MDOP_UNPACK_UPPER_HW : public MDOP_BASE3 495 { OpRegMDOP_UNPACK_UPPER_HW496 static OpRegType OpReg() { return &CAArch64Assembler::Zip2_8h; } 497 }; 498 499 struct MDOP_UNPACK_UPPER_WD : public MDOP_BASE3 500 { OpRegMDOP_UNPACK_UPPER_WD501 static OpRegType OpReg() { return &CAArch64Assembler::Zip2_4s; } 502 }; 503 504 struct MDOP_CMPEQZS : public MDOP_BASE2 505 { OpRegMDOP_CMPEQZS506 static OpRegType OpReg() { return &CAArch64Assembler::Fcmeq_4s; } 507 }; 508 509 struct MDOP_CMPLTZS : public MDOP_BASE2 510 { OpRegMDOP_CMPLTZS511 static OpRegType OpReg() { return &CAArch64Assembler::Fcmlt_4s; } 512 }; 513 514 struct MDOP_SLLH : public MDOP_SHIFT 515 { OpRegMDOP_SLLH516 static OpRegType OpReg() { return &CAArch64Assembler::Shl_8h; } 517 }; 518 519 struct MDOP_SLLW : public MDOP_SHIFT 520 { OpRegMDOP_SLLW521 static OpRegType OpReg() { return &CAArch64Assembler::Shl_4s; } 522 }; 523 524 struct MDOP_SRLH : public MDOP_SHIFT 525 { OpRegMDOP_SRLH526 static OpRegType OpReg() { return &CAArch64Assembler::Ushr_8h; } 527 }; 528 529 struct MDOP_SRLW : public MDOP_SHIFT 530 { OpRegMDOP_SRLW531 static OpRegType OpReg() { return &CAArch64Assembler::Ushr_4s; } 532 }; 533 534 struct MDOP_SRAH : public MDOP_SHIFT 535 { OpRegMDOP_SRAH536 static OpRegType OpReg() { return &CAArch64Assembler::Sshr_8h; } 537 }; 538 539 struct MDOP_SRAW : public MDOP_SHIFT 540 { OpRegMDOP_SRAW541 static OpRegType OpReg() { return &CAArch64Assembler::Sshr_4s; } 542 }; 543 544 uint16 GetSavedRegisterList(uint32); 545 void Emit_Prolog(const StatementList&, uint32, uint16); 546 void Emit_Epilog(uint32, uint16); 547 548 CAArch64Assembler::LABEL GetLabel(uint32); 549 void MarkLabel(const STATEMENT&); 550 551 void Emit_Nop(const STATEMENT&); 552 553 void Emit_Mov_RegReg(const STATEMENT&); 554 void Emit_Mov_RegMem(const STATEMENT&); 555 void Emit_Mov_RegCst(const STATEMENT&); 556 void Emit_Mov_MemReg(const STATEMENT&); 557 void Emit_Mov_MemMem(const STATEMENT&); 558 void Emit_Mov_MemCst(const STATEMENT&); 559 560 void Emit_Not_VarVar(const STATEMENT&); 561 void Emit_Lzc_VarVar(const STATEMENT&); 562 563 void Emit_Mov_Mem64Mem64(const STATEMENT&); 564 void Emit_Mov_Mem64Cst64(const STATEMENT&); 565 566 void Emit_ExtLow64VarMem64(const STATEMENT&); 567 void Emit_ExtHigh64VarMem64(const STATEMENT&); 568 void Emit_MergeTo64_Mem64AnyAny(const STATEMENT&); 569 570 void Emit_RelToRef_TmpCst(const STATEMENT&); 571 void Emit_AddRef_TmpMemAny(const STATEMENT&); 572 void Emit_LoadFromRef_VarMem(const STATEMENT&); 573 void Emit_StoreAtRef_MemAny(const STATEMENT&); 574 575 void Emit_Param_Ctx(const STATEMENT&); 576 void Emit_Param_Reg(const STATEMENT&); 577 void Emit_Param_Mem(const STATEMENT&); 578 void Emit_Param_Cst(const STATEMENT&); 579 void Emit_Param_Mem64(const STATEMENT&); 580 void Emit_Param_Cst64(const STATEMENT&); 581 void Emit_Param_Reg128(const STATEMENT&); 582 void Emit_Param_Mem128(const STATEMENT&); 583 584 void Emit_Call(const STATEMENT&); 585 void Emit_RetVal_Reg(const STATEMENT&); 586 void Emit_RetVal_Tmp(const STATEMENT&); 587 void Emit_RetVal_Mem64(const STATEMENT&); 588 void Emit_RetVal_Reg128(const STATEMENT&); 589 void Emit_RetVal_Mem128(const STATEMENT&); 590 591 void Emit_Jmp(const STATEMENT&); 592 593 void Emit_CondJmp(const STATEMENT&); 594 void Emit_CondJmp_AnyVar(const STATEMENT&); 595 void Emit_CondJmp_VarCst(const STATEMENT&); 596 597 void Cmp_GetFlag(CAArch64Assembler::REGISTER32, Jitter::CONDITION); 598 void Emit_Cmp_VarAnyVar(const STATEMENT&); 599 void Emit_Cmp_VarVarCst(const STATEMENT&); 600 601 void Emit_Add64_MemMemMem(const STATEMENT&); 602 void Emit_Add64_MemMemCst(const STATEMENT&); 603 604 void Emit_Sub64_MemAnyMem(const STATEMENT&); 605 void Emit_Sub64_MemMemCst(const STATEMENT&); 606 607 void Emit_Cmp64_VarAnyMem(const STATEMENT&); 608 void Emit_Cmp64_VarMemCst(const STATEMENT&); 609 610 void Emit_And64_MemMemMem(const STATEMENT&); 611 612 //ADDSUB 613 template <typename> void Emit_AddSub_VarAnyVar(const STATEMENT&); 614 template <typename> void Emit_AddSub_VarVarCst(const STATEMENT&); 615 616 //SHIFT 617 template <typename> void Emit_Shift_VarAnyVar(const STATEMENT&); 618 template <typename> void Emit_Shift_VarVarCst(const STATEMENT&); 619 620 //LOGIC 621 template <typename> void Emit_Logic_VarAnyVar(const STATEMENT&); 622 template <typename> void Emit_Logic_VarVarCst(const STATEMENT&); 623 624 //MUL 625 template <bool> void Emit_Mul_Tmp64AnyAny(const STATEMENT&); 626 627 //DIV 628 template <bool> void Emit_Div_Tmp64AnyAny(const STATEMENT&); 629 630 //SHIFT64 631 template <typename> void Emit_Shift64_MemMemVar(const STATEMENT&); 632 template <typename> void Emit_Shift64_MemMemCst(const STATEMENT&); 633 634 //FPU 635 template <typename> void Emit_Fpu_MemMem(const STATEMENT&); 636 template <typename> void Emit_Fpu_MemMemMem(const STATEMENT&); 637 638 void Emit_Fp_Cmp_AnyMemMem(const STATEMENT&); 639 void Emit_Fp_Rcpl_MemMem(const STATEMENT&); 640 void Emit_Fp_Rsqrt_MemMem(const STATEMENT&); 641 void Emit_Fp_Mov_MemSRelI32(const STATEMENT&); 642 void Emit_Fp_ToIntTrunc_MemMem(const STATEMENT&); 643 void Emit_Fp_LdCst_TmpCst(const STATEMENT&); 644 645 //MD 646 template <typename> void Emit_Md_VarVar(const STATEMENT&); 647 template <typename> void Emit_Md_VarVarVar(const STATEMENT&); 648 template <typename> void Emit_Md_VarVarVarRev(const STATEMENT&); 649 template <typename> void Emit_Md_Shift_VarVarCst(const STATEMENT&); 650 template <typename> void Emit_Md_Test_VarVar(const STATEMENT&); 651 652 void Emit_Md_Mov_RegReg(const STATEMENT&); 653 void Emit_Md_Mov_RegMem(const STATEMENT&); 654 void Emit_Md_Mov_MemReg(const STATEMENT&); 655 void Emit_Md_Mov_MemMem(const STATEMENT&); 656 657 void Emit_Md_Not_VarVar(const STATEMENT&); 658 659 void Emit_Md_LoadFromRef_VarMem(const STATEMENT&); 660 void Emit_Md_StoreAtRef_MemVar(const STATEMENT&); 661 662 void Emit_Md_MovMasked_VarVarVar(const STATEMENT&); 663 void Emit_Md_Expand_VarReg(const STATEMENT&); 664 void Emit_Md_Expand_VarMem(const STATEMENT&); 665 void Emit_Md_Expand_VarCst(const STATEMENT&); 666 667 void Emit_Md_PackHB_VarVarVar(const STATEMENT&); 668 void Emit_Md_PackWH_VarVarVar(const STATEMENT&); 669 670 void Emit_MergeTo256_MemVarVar(const STATEMENT&); 671 void Emit_Md_Srl256_VarMemVar(const STATEMENT&); 672 void Emit_Md_Srl256_VarMemCst(const STATEMENT&); 673 674 static CONSTMATCHER g_constMatchers[]; 675 static CONSTMATCHER g_64ConstMatchers[]; 676 static CONSTMATCHER g_fpuConstMatchers[]; 677 static CONSTMATCHER g_mdConstMatchers[]; 678 679 static CAArch64Assembler::REGISTER32 g_registers[MAX_REGISTERS]; 680 static CAArch64Assembler::REGISTERMD g_registersMd[MAX_MDREGISTERS]; 681 static CAArch64Assembler::REGISTER32 g_tempRegisters[MAX_TEMP_REGS]; 682 static CAArch64Assembler::REGISTER64 g_tempRegisters64[MAX_TEMP_REGS]; 683 static CAArch64Assembler::REGISTERMD g_tempRegistersMd[MAX_TEMP_MD_REGS]; 684 static CAArch64Assembler::REGISTER32 g_paramRegisters[MAX_PARAM_REGS]; 685 static CAArch64Assembler::REGISTER64 g_paramRegisters64[MAX_PARAM_REGS]; 686 static CAArch64Assembler::REGISTER64 g_baseRegister; 687 688 Framework::CStream* m_stream = nullptr; 689 CAArch64Assembler m_assembler; 690 LabelMapType m_labels; 691 ParamStack m_params; 692 uint32 m_nextTempRegister = 0; 693 uint32 m_nextTempRegisterMd = 0; 694 uint32 m_paramSpillBase = 0; 695 696 bool m_generateRelocatableCalls = false; 697 }; 698 }; 699