Mercurial > hg > CbC > CbC_llvm
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>; |