comparison lib/Target/Hexagon/HexagonPseudo.td @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
comparison
equal deleted inserted replaced
146:3fc4d5c3e21e 148:63bd29f05246
1 //===--- HexagonPseudo.td -------------------------------------------------===// 1 //===--- HexagonPseudo.td -------------------------------------------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // 4 // See https://llvm.org/LICENSE.txt for license information.
5 // This file is distributed under the University of Illinois Open Source 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // License. See LICENSE.TXT for details.
7 // 6 //
8 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
9 8
10 // The pat frags in the definitions below need to have a named register, 9 // The pat frags in the definitions below need to have a named register,
11 // otherwise i32 will be assumed regardless of the register class. The 10 // otherwise i32 will be assumed regardless of the register class. The
22 } 21 }
23 22
24 let isPseudo = 1 in { 23 let isPseudo = 1 in {
25 let isCodeGenOnly = 0 in 24 let isCodeGenOnly = 0 in
26 def A2_iconst : Pseudo<(outs IntRegs:$Rd32), 25 def A2_iconst : Pseudo<(outs IntRegs:$Rd32),
27 (ins s27_2Imm:$Ii), "${Rd32}=iconst(#${Ii})">; 26 (ins s27_2Imm:$Ii), "${Rd32} = iconst(#${Ii})">;
28 27
29 def DUPLEX_Pseudo : InstHexagon<(outs), 28 def DUPLEX_Pseudo : InstHexagon<(outs),
30 (ins s32_0Imm:$offset), "DUPLEX", [], "", DUPLEX, TypePSEUDO>; 29 (ins s32_0Imm:$offset), "DUPLEX", [], "", DUPLEX, TypePSEUDO>;
31 } 30 }
32 31
33 let isExtendable = 1, opExtendable = 1, opExtentBits = 6, 32 let isExtendable = 1, opExtendable = 1, opExtentBits = 6,
34 isAsmParserOnly = 1 in 33 isAsmParserOnly = 1 in
35 def TFRI64_V2_ext : InstHexagon<(outs DoubleRegs:$dst), 34 def TFRI64_V2_ext : InstHexagon<(outs DoubleRegs:$dst),
36 (ins s32_0Imm:$src1, s8_0Imm:$src2), 35 (ins s32_0Imm:$src1, s8_0Imm:$src2),
37 "$dst=combine(#$src1,#$src2)", [], "", 36 "$dst = combine(#$src1,#$src2)", [], "",
38 A2_combineii.Itinerary, TypeALU32_2op>, OpcodeHexagon; 37 A2_combineii.Itinerary, TypeALU32_2op>, OpcodeHexagon;
39 38
40 // HI/LO Instructions 39 // HI/LO Instructions
41 let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0, 40 let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0,
42 hasNewValue = 1, opNewValue = 0 in 41 hasNewValue = 1, opNewValue = 0 in
43 class REG_IMMED<string RegHalf, bit Rs, bits<3> MajOp, bit MinOp, 42 class REG_IMMED<string RegHalf, bit Rs, bits<3> MajOp, bit MinOp,
44 InstHexagon rootInst> 43 InstHexagon rootInst>
45 : InstHexagon<(outs IntRegs:$dst), 44 : InstHexagon<(outs IntRegs:$dst),
46 (ins u16_0Imm:$imm_value), 45 (ins u16_0Imm:$imm_value),
47 "$dst"#RegHalf#"=#$imm_value", [], "", 46 "$dst"#RegHalf#" = #$imm_value", [], "",
48 rootInst.Itinerary, rootInst.Type>, OpcodeHexagon { 47 rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
49 bits<5> dst; 48 bits<5> dst;
50 bits<32> imm_value; 49 bits<32> imm_value;
51 50
52 let Inst{27} = Rs; 51 let Inst{27} = Rs;
98 let isBranch = 1, isTerminator = 1, hasSideEffects = 0, 97 let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
99 Defs = [PC, LC1], Uses = [SA1, LC1] in { 98 Defs = [PC, LC1], Uses = [SA1, LC1] in {
100 def ENDLOOP1 : Endloop<(outs), (ins b30_2Imm:$offset), 99 def ENDLOOP1 : Endloop<(outs), (ins b30_2Imm:$offset),
101 ":endloop1", 100 ":endloop1",
102 []>; 101 []>;
102 }
103
104 let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
105 Defs = [PC, LC0, LC1], Uses = [SA0, SA1, LC0, LC1] in {
106 def ENDLOOP01 : Endloop<(outs), (ins b30_2Imm:$offset),
107 ":endloop01",
108 []>;
103 } 109 }
104 110
105 let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2, 111 let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
106 opExtendable = 0, hasSideEffects = 0 in 112 opExtendable = 0, hasSideEffects = 0 in
107 class LOOP_iBase<string mnemonic, InstHexagon rootInst> 113 class LOOP_iBase<string mnemonic, InstHexagon rootInst>
199 bits<17> dst; 205 bits<17> dst;
200 let opExtentBits = nbits; 206 let opExtentBits = nbits;
201 let isPredicable = 0; // !if(isPred, 0, 1); 207 let isPredicable = 0; // !if(isPred, 0, 1);
202 let isPredicated = 0; // isPred; 208 let isPredicated = 0; // isPred;
203 let isPredicatedFalse = isFalse; 209 let isPredicatedFalse = isFalse;
210 let Itinerary = itin;
204 } 211 }
205 212
206 def PS_call_nr : Call_nr<24, 0, 0, (ins s32_0Imm:$Ii), J2_call.Itinerary>; 213 def PS_call_nr : Call_nr<24, 0, 0, (ins s32_0Imm:$Ii), J2_call.Itinerary>;
207 //def PS_call_nrt: Call_nr<17, 1, 0, (ins PredRegs:$Pu, s32_0Imm:$dst), 214 //def PS_call_nrt: Call_nr<17, 1, 0, (ins PredRegs:$Pu, s32_0Imm:$dst),
208 // J2_callt.Itinerary>; 215 // J2_callt.Itinerary>;
314 ".error \"should not emit\"", []>; 321 ".error \"should not emit\"", []>;
315 322
316 // Load modifier. 323 // Load modifier.
317 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13, 324 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
318 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in 325 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
319 def LDriw_mod : LDInst<(outs ModRegs:$dst), 326 def LDriw_ctr : LDInst<(outs CtrRegs:$dst),
320 (ins IntRegs:$addr, s32_0Imm:$off), 327 (ins IntRegs:$addr, s32_0Imm:$off),
321 ".error \"should not emit\"", []>; 328 ".error \"should not emit\"", []>;
322 329
323 330
324 let isCodeGenOnly = 1, isPseudo = 1 in 331 let isCodeGenOnly = 1, isPseudo = 1 in
397 let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in 404 let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in
398 def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<"">, PredRel; 405 def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<"">, PredRel;
399 } 406 }
400 407
401 // Vector store pseudos 408 // Vector store pseudos
402 let Predicates = [HasV60T, UseHVX], isPseudo = 1, isCodeGenOnly = 1, 409 let Predicates = [HasV60,UseHVX], isPseudo = 1, isCodeGenOnly = 1,
403 mayStore = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in 410 mayStore = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
404 class STrivv_template<RegisterClass RC, InstHexagon rootInst> 411 class STrivv_template<RegisterClass RC, InstHexagon rootInst>
405 : InstHexagon<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src), 412 : InstHexagon<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src),
406 "", [], "", rootInst.Itinerary, rootInst.Type>; 413 "", [], "", rootInst.Itinerary, rootInst.Type>;
407 414
408 def PS_vstorerw_ai: STrivv_template<HvxWR, V6_vS32b_ai>, 415 def PS_vstorerw_ai: STrivv_template<HvxWR, V6_vS32b_ai>,
409 Requires<[HasV60T,UseHVX]>; 416 Requires<[HasV60,UseHVX]>;
410 def PS_vstorerw_nt_ai: STrivv_template<HvxWR, V6_vS32b_nt_ai>, 417 def PS_vstorerw_nt_ai: STrivv_template<HvxWR, V6_vS32b_nt_ai>,
411 Requires<[HasV60T,UseHVX]>; 418 Requires<[HasV60,UseHVX]>;
412 def PS_vstorerwu_ai: STrivv_template<HvxWR, V6_vS32Ub_ai>, 419 def PS_vstorerwu_ai: STrivv_template<HvxWR, V6_vS32Ub_ai>,
413 Requires<[HasV60T,UseHVX]>; 420 Requires<[HasV60,UseHVX]>;
414 421
415 let isPseudo = 1, isCodeGenOnly = 1, mayStore = 1, hasSideEffects = 0 in 422 let isPseudo = 1, isCodeGenOnly = 1, mayStore = 1, hasSideEffects = 0 in
416 def PS_vstorerq_ai: Pseudo<(outs), 423 def PS_vstorerq_ai: Pseudo<(outs),
417 (ins IntRegs:$Rs, s32_0Imm:$Off, HvxQR:$Qt), "", []>, 424 (ins IntRegs:$Rs, s32_0Imm:$Off, HvxQR:$Qt), "", []>,
418 Requires<[HasV60T,UseHVX]>; 425 Requires<[HasV60,UseHVX]>;
419 426
420 // Vector load pseudos 427 // Vector load pseudos
421 let Predicates = [HasV60T, UseHVX], isPseudo = 1, isCodeGenOnly = 1, 428 let Predicates = [HasV60, UseHVX], isPseudo = 1, isCodeGenOnly = 1,
422 mayLoad = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in 429 mayLoad = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
423 class LDrivv_template<RegisterClass RC, InstHexagon rootInst> 430 class LDrivv_template<RegisterClass RC, InstHexagon rootInst>
424 : InstHexagon<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off), 431 : InstHexagon<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off),
425 "", [], "", rootInst.Itinerary, rootInst.Type>; 432 "", [], "", rootInst.Itinerary, rootInst.Type>;
426 433
427 def PS_vloadrw_ai: LDrivv_template<HvxWR, V6_vL32b_ai>, 434 def PS_vloadrw_ai: LDrivv_template<HvxWR, V6_vL32b_ai>,
428 Requires<[HasV60T,UseHVX]>; 435 Requires<[HasV60,UseHVX]>;
429 def PS_vloadrw_nt_ai: LDrivv_template<HvxWR, V6_vL32b_nt_ai>, 436 def PS_vloadrw_nt_ai: LDrivv_template<HvxWR, V6_vL32b_nt_ai>,
430 Requires<[HasV60T,UseHVX]>; 437 Requires<[HasV60,UseHVX]>;
431 def PS_vloadrwu_ai: LDrivv_template<HvxWR, V6_vL32Ub_ai>, 438 def PS_vloadrwu_ai: LDrivv_template<HvxWR, V6_vL32Ub_ai>,
432 Requires<[HasV60T,UseHVX]>; 439 Requires<[HasV60,UseHVX]>;
433 440
434 let isPseudo = 1, isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in 441 let isPseudo = 1, isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in
435 def PS_vloadrq_ai: Pseudo<(outs HvxQR:$Qd), 442 def PS_vloadrq_ai: Pseudo<(outs HvxQR:$Qd),
436 (ins IntRegs:$Rs, s32_0Imm:$Off), "", []>, 443 (ins IntRegs:$Rs, s32_0Imm:$Off), "", []>,
437 Requires<[HasV60T,UseHVX]>; 444 Requires<[HasV60,UseHVX]>;
438 445
439 446
440 let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in 447 let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
441 class VSELInst<dag outs, dag ins, InstHexagon rootInst> 448 class VSELInst<dag outs, dag ins, InstHexagon rootInst>
442 : InstHexagon<outs, ins, "", [], "", rootInst.Itinerary, rootInst.Type>; 449 : InstHexagon<outs, ins, "", [], "", rootInst.Itinerary, rootInst.Type>;
443 450
444 def PS_vselect: VSELInst<(outs HvxVR:$dst), 451 def PS_vselect: VSELInst<(outs HvxVR:$dst),
445 (ins PredRegs:$src1, HvxVR:$src2, HvxVR:$src3), V6_vcmov>, 452 (ins PredRegs:$src1, HvxVR:$src2, HvxVR:$src3), V6_vcmov>,
446 Requires<[HasV60T,UseHVX]>; 453 Requires<[HasV60,UseHVX]>;
447 def PS_wselect: VSELInst<(outs HvxWR:$dst), 454 def PS_wselect: VSELInst<(outs HvxWR:$dst),
448 (ins PredRegs:$src1, HvxWR:$src2, HvxWR:$src3), V6_vccombine>, 455 (ins PredRegs:$src1, HvxWR:$src2, HvxWR:$src3), V6_vccombine>,
449 Requires<[HasV60T,UseHVX]>; 456 Requires<[HasV60,UseHVX]>;
450 457
451 let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1, 458 let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
452 isCodeGenOnly = 1 in { 459 isCodeGenOnly = 1 in {
453 def PS_qtrue: InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "", 460 def PS_qtrue: InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "",
454 V6_veqw.Itinerary, TypeCVI_VA>; 461 V6_veqw.Itinerary, TypeCVI_VA>;
455 def PS_qfalse: InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "", 462 def PS_qfalse: InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "",
456 V6_vgtw.Itinerary, TypeCVI_VA>; 463 V6_vgtw.Itinerary, TypeCVI_VA>;
464 def PS_vdd0: InstHexagon<(outs HvxWR:$Vd), (ins), "", [], "",
465 V6_vsubw_dv.Itinerary, TypeCVI_VA_DV>;
457 } 466 }
458 467
459 // Store predicate. 468 // Store predicate.
460 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13, 469 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
461 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in 470 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
463 (ins IntRegs:$addr, s32_0Imm:$off, PredRegs:$src1), 472 (ins IntRegs:$addr, s32_0Imm:$off, PredRegs:$src1),
464 ".error \"should not emit\"", []>; 473 ".error \"should not emit\"", []>;
465 // Store modifier. 474 // Store modifier.
466 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13, 475 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
467 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in 476 isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
468 def STriw_mod : STInst<(outs), 477 def STriw_ctr : STInst<(outs),
469 (ins IntRegs:$addr, s32_0Imm:$off, ModRegs:$src1), 478 (ins IntRegs:$addr, s32_0Imm:$off, CtrRegs:$src1),
470 ".error \"should not emit\"", []>; 479 ".error \"should not emit\"", []>;
471 480
472 let isExtendable = 1, opExtendable = 1, opExtentBits = 6, 481 let isExtendable = 1, opExtendable = 1, opExtentBits = 6,
473 isAsmParserOnly = 1 in 482 isAsmParserOnly = 1 in
474 def TFRI64_V4 : InstHexagon<(outs DoubleRegs:$dst), 483 def TFRI64_V4 : InstHexagon<(outs DoubleRegs:$dst),
505 def DuplexIClassB: InstDuplex < 0xB >; 514 def DuplexIClassB: InstDuplex < 0xB >;
506 def DuplexIClassC: InstDuplex < 0xC >; 515 def DuplexIClassC: InstDuplex < 0xC >;
507 def DuplexIClassD: InstDuplex < 0xD >; 516 def DuplexIClassD: InstDuplex < 0xD >;
508 def DuplexIClassE: InstDuplex < 0xE >; 517 def DuplexIClassE: InstDuplex < 0xE >;
509 def DuplexIClassF: InstDuplex < 0xF >; 518 def DuplexIClassF: InstDuplex < 0xF >;
519
520 // Pseudos for circular buffer instructions. These are needed in order to
521 // allocate the correct pair of CSx and Mx registers.
522 multiclass NewCircularLoad<RegisterClass RC, MemAccessSize MS> {
523
524 let isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
525 addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
526 def NAME#_pci : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
527 (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, IntRegs:$Cs),
528 ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_e93a3d71>;
529
530 def NAME#_pcr : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
531 (ins IntRegs:$Rx32in, ModRegs:$Mu2, IntRegs:$Cs),
532 ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_44d3da28>;
533 }
534 }
535
536 defm PS_loadrub : NewCircularLoad<IntRegs, ByteAccess>;
537 defm PS_loadrb : NewCircularLoad<IntRegs, ByteAccess>;
538 defm PS_loadruh : NewCircularLoad<IntRegs, HalfWordAccess>;
539 defm PS_loadrh : NewCircularLoad<IntRegs, HalfWordAccess>;
540 defm PS_loadri : NewCircularLoad<IntRegs, WordAccess>;
541 defm PS_loadrd : NewCircularLoad<DoubleRegs, DoubleWordAccess>;
542
543 multiclass NewCircularStore<RegisterClass RC, MemAccessSize MS> {
544
545 let isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
546 addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
547 def NAME#_pci : STInst<(outs IntRegs:$Rx32),
548 (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, RC:$Rt32, IntRegs:$Cs),
549 ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_e86aa961>;
550
551 def NAME#_pcr : STInst<(outs IntRegs:$Rx32),
552 (ins IntRegs:$Rx32in, ModRegs:$Mu2, RC:$Rt32, IntRegs:$Cs),
553 ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_da97ee82>;
554 }
555 }
556
557 defm PS_storerb : NewCircularStore<IntRegs, ByteAccess>;
558 defm PS_storerh : NewCircularStore<IntRegs, HalfWordAccess>;
559 defm PS_storerf : NewCircularStore<IntRegs, HalfWordAccess>;
560 defm PS_storeri : NewCircularStore<IntRegs, WordAccess>;
561 defm PS_storerd : NewCircularStore<DoubleRegs, WordAccess>;
562
563 // A pseudo that generates a runtime crash. This is used to implement
564 // __builtin_trap.
565 let hasSideEffects = 1, isPseudo = 1, isCodeGenOnly = 1, isSolo = 1 in
566 def PS_crash: InstHexagon<(outs), (ins), "", [], "", PSEUDO, TypePSEUDO>;