From 22a21d4c5d16c6acf5ff9b628df15df0e06dbdff Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 1 Mar 2018 17:03:26 +0000 Subject: [PATCH] [Hexagon] Add guest registers llvm-svn: 326450 --- .../Hexagon/Disassembler/HexagonDisassembler.cpp | 58 +++++++++++++++ llvm/lib/Target/Hexagon/HexagonDepIICScalar.td | 46 ++++++++++++ llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td | 38 ++++++++++ llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp | 7 ++ llvm/lib/Target/Hexagon/HexagonRegisterInfo.td | 86 +++++++++++++++++++++- llvm/test/MC/Hexagon/guest.s | 67 +++++++++++++++++ 6 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/Hexagon/guest.s diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 481b692..574a8d4 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -127,12 +127,18 @@ static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, const void *Decoder); @@ -783,3 +789,55 @@ static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); return MCDisassembler::Success; } + +static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + const void *Decoder) { + using namespace Hexagon; + + static const MCPhysReg GuestRegDecoderTable[] = { + /* 0 */ GELR, GSR, GOSP, G3, + /* 4 */ G4, G5, G6, G7, + /* 8 */ G8, G9, G10, G11, + /* 12 */ G12, G13, G14, G15, + /* 16 */ GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7, + /* 20 */ G20, G21, G22, G23, + /* 24 */ GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1, + /* 28 */ GPMUCNT2, GPMUCNT3, G30, G31 + }; + + if (RegNo >= array_lengthof(GuestRegDecoderTable)) + return MCDisassembler::Fail; + if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister) + return MCDisassembler::Fail; + + unsigned Register = GuestRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + const void *Decoder) { + using namespace Hexagon; + + static const MCPhysReg GuestReg64DecoderTable[] = { + /* 0 */ G1_0, 0, G3_2, 0, + /* 4 */ G5_4, 0, G7_6, 0, + /* 8 */ G9_8, 0, G11_10, 0, + /* 12 */ G13_12, 0, G15_14, 0, + /* 16 */ G17_16, 0, G19_18, 0, + /* 20 */ G21_20, 0, G23_22, 0, + /* 24 */ G25_24, 0, G27_26, 0, + /* 28 */ G29_28, 0, G31_30, 0 + }; + + if (RegNo >= array_lengthof(GuestReg64DecoderTable)) + return MCDisassembler::Fail; + if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister) + return MCDisassembler::Fail; + + unsigned Register = GuestReg64DecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Hexagon/HexagonDepIICScalar.td b/llvm/lib/Target/Hexagon/HexagonDepIICScalar.td index 083ec77..75fb68a 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepIICScalar.td +++ b/llvm/lib/Target/Hexagon/HexagonDepIICScalar.td @@ -96,6 +96,7 @@ def tc_6aa5711a : InstrItinClass; def tc_6ac37025 : InstrItinClass; def tc_6ebb4a12 : InstrItinClass; def tc_6efc556e : InstrItinClass; +def tc_6fa4db47 : InstrItinClass; def tc_73043bf4 : InstrItinClass; def tc_746baa8e : InstrItinClass; def tc_74e47fd9 : InstrItinClass; @@ -115,6 +116,7 @@ def tc_8fe6b782 : InstrItinClass; def tc_90f3e30c : InstrItinClass; def tc_976ddc4f : InstrItinClass; def tc_97743097 : InstrItinClass; +def tc_994333cd : InstrItinClass; def tc_999d32db : InstrItinClass; def tc_99be14ca : InstrItinClass; def tc_9c00ce8d : InstrItinClass; @@ -278,6 +280,7 @@ class DepScalarItinV4 { InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, + InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, @@ -297,6 +300,7 @@ class DepScalarItinV4 { InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, + InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, @@ -461,6 +465,7 @@ class DepScalarItinV5 { InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, + InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, @@ -480,6 +485,7 @@ class DepScalarItinV5 { InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, + InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, InstrItinData ]>, @@ -902,6 +908,10 @@ class DepScalarItinV55 { [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>], [], []>, + InstrItinData ], [4, 2], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1, 2], [Hex_FWD, Hex_FWD]>, @@ -978,6 +988,10 @@ class DepScalarItinV55 { [InstrStage<1, [SLOT2]>], [2, 1], [Hex_FWD, Hex_FWD]>, + InstrItinData ], [4, 1], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1], [Hex_FWD]>, @@ -1622,6 +1636,10 @@ class DepScalarItinV60 { [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>], [], []>, + InstrItinData ], [4, 2], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1, 2], [Hex_FWD, Hex_FWD]>, @@ -1698,6 +1716,10 @@ class DepScalarItinV60 { [InstrStage<1, [SLOT2]>], [2, 1], [Hex_FWD, Hex_FWD]>, + InstrItinData ], [4, 1], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1], [Hex_FWD]>, @@ -2359,6 +2381,10 @@ class DepScalarItinV60se { [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>], [], []>, + InstrItinData ], [4, 2], + [Hex_FWD, Hex_FWD]>, + InstrItinData , InstrStage<1, [CVI_ST]>], [1, 2], @@ -2439,6 +2465,10 @@ class DepScalarItinV60se { InstrStage<1, [CVI_ST]>], [2, 1], [Hex_FWD, Hex_FWD]>, + InstrItinData ], [4, 1], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1], [Hex_FWD]>, @@ -3095,6 +3125,10 @@ class DepScalarItinV62 { [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>], [], []>, + InstrItinData ], [4, 2], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1, 2], [Hex_FWD, Hex_FWD]>, @@ -3167,6 +3201,10 @@ class DepScalarItinV62 { [InstrStage<1, [SLOT2, SLOT3]>], [4, 2, 2], [Hex_FWD, Hex_FWD, Hex_FWD]>, + InstrItinData ], [4, 1], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [2, 1], [Hex_FWD, Hex_FWD]>, @@ -3815,6 +3853,10 @@ class DepScalarItinV65 { [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>], [], []>, + InstrItinData ], [4, 2], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [2, 2], [Hex_FWD, Hex_FWD]>, @@ -3891,6 +3933,10 @@ class DepScalarItinV65 { [InstrStage<1, [SLOT2]>], [2, 2], [Hex_FWD, Hex_FWD]>, + InstrItinData ], [4, 1], + [Hex_FWD, Hex_FWD]>, + InstrItinData ], [1], [Hex_FWD]>, diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td index 6e16762..434158b 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonDepInstrInfo.td @@ -4698,6 +4698,44 @@ let opNewValue = 0; let isFP = 1; let Uses = [USR]; } +def G4_tfrgcpp : HInst< +(outs DoubleRegs:$Rdd32), +(ins GuestRegs64:$Gss32), +"$Rdd32 = $Gss32", +tc_6fa4db47, TypeCR>, Enc_0aa344 { +let Inst{13-5} = 0b000000000; +let Inst{31-21} = 0b01101000001; +} +def G4_tfrgcrr : HInst< +(outs IntRegs:$Rd32), +(ins GuestRegs:$Gs32), +"$Rd32 = $Gs32", +tc_6fa4db47, TypeCR>, Enc_44271f { +let Inst{13-5} = 0b000000000; +let Inst{31-21} = 0b01101010001; +let hasNewValue = 1; +let opNewValue = 0; +} +def G4_tfrgpcp : HInst< +(outs GuestRegs64:$Gdd32), +(ins DoubleRegs:$Rss32), +"$Gdd32 = $Rss32", +tc_994333cd, TypeCR>, Enc_ed5027 { +let Inst{13-5} = 0b000000000; +let Inst{31-21} = 0b01100011000; +let hasNewValue = 1; +let opNewValue = 0; +} +def G4_tfrgrcr : HInst< +(outs GuestRegs:$Gd32), +(ins IntRegs:$Rs32), +"$Gd32 = $Rs32", +tc_994333cd, TypeCR>, Enc_621fba { +let Inst{13-5} = 0b000000000; +let Inst{31-21} = 0b01100010000; +let hasNewValue = 1; +let opNewValue = 0; +} def J2_call : HInst< (outs), (ins a30_2Imm:$Ii), diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index 3754a04..ca0c2d7 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -145,6 +145,13 @@ BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) Reserved.set(Hexagon::R30); Reserved.set(Hexagon::R31); Reserved.set(Hexagon::VTMP); + + // Guest registers. + Reserved.set(Hexagon::GELR); // G0 + Reserved.set(Hexagon::GSR); // G1 + Reserved.set(Hexagon::GOSP); // G2 + Reserved.set(Hexagon::G3); // G3 + // Control registers. Reserved.set(Hexagon::SA0); // C0 Reserved.set(Hexagon::LC0); // C1 diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index 2ceed70..adbfd56 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -67,6 +67,17 @@ let Namespace = "Hexagon" in { let HWEncoding{0} = num; } + // Rg - Guest/Hypervisor registers + class Rg num, string n, + list alt = [], list alias = []> : + HexagonReg; + + // Rgg - 64-bit Guest/Hypervisor registers + class Rgg num, string n, list subregs> : + HexagonDoubleReg { + let SubRegs = subregs; + } + def isub_lo : SubRegIndex<32>; def isub_hi : SubRegIndex<32, 32>; def vsub_lo : SubRegIndex<512>; @@ -200,6 +211,61 @@ let Namespace = "Hexagon" in { def Q1 : Rq<1, "q1">, DwarfRegNum<[132]>; def Q2 : Rq<2, "q2">, DwarfRegNum<[133]>; def Q3 : Rq<3, "q3">, DwarfRegNum<[134]>; + + // Guest Registers + def GELR: Rg<0, "gelr", ["g0"]>, DwarfRegNum<[220]>; + def GSR: Rg<1, "gsr", ["g1"]>, DwarfRegNum<[221]>; + def GOSP: Rg<2, "gosp", ["g2"]>, DwarfRegNum<[222]>; + def G3: Rg<3, "gbadva", ["g3"]>, DwarfRegNum<[223]>; + def G4: Rg<4, "g4">, DwarfRegNum<[224]>; + def G5: Rg<5, "g5">, DwarfRegNum<[225]>; + def G6: Rg<6, "g6">, DwarfRegNum<[226]>; + def G7: Rg<7, "g7">, DwarfRegNum<[227]>; + def G8: Rg<8, "g8">, DwarfRegNum<[228]>; + def G9: Rg<9, "g9">, DwarfRegNum<[229]>; + def G10: Rg<10, "g10">, DwarfRegNum<[230]>; + def G11: Rg<11, "g11">, DwarfRegNum<[231]>; + def G12: Rg<12, "g12">, DwarfRegNum<[232]>; + def G13: Rg<13, "g13">, DwarfRegNum<[233]>; + def G14: Rg<14, "g14">, DwarfRegNum<[234]>; + def G15: Rg<15, "g15">, DwarfRegNum<[235]>; + def GPMUCNT4: Rg<16, "gpmucnt4", ["g16"]>, DwarfRegNum<[236]>; + def GPMUCNT5: Rg<17, "gpmucnt5", ["g17"]>, DwarfRegNum<[237]>; + def GPMUCNT6: Rg<18, "gpmucnt6", ["g18"]>, DwarfRegNum<[238]>; + def GPMUCNT7: Rg<19, "gpmucnt7", ["g19"]>, DwarfRegNum<[239]>; + def G20: Rg<20, "g20">, DwarfRegNum<[240]>; + def G21: Rg<21, "g21">, DwarfRegNum<[241]>; + def G22: Rg<22, "g22">, DwarfRegNum<[242]>; + def G23: Rg<23, "g23">, DwarfRegNum<[243]>; + def GPCYCLELO: Rg<24, "gpcyclelo", ["g24"]>, DwarfRegNum<[244]>; + def GPCYCLEHI: Rg<25, "gpcyclehi", ["g25"]>, DwarfRegNum<[245]>; + def GPMUCNT0: Rg<26, "gpmucnt0", ["g26"]>, DwarfRegNum<[246]>; + def GPMUCNT1: Rg<27, "gpmucnt1", ["g27"]>, DwarfRegNum<[247]>; + def GPMUCNT2: Rg<28, "gpmucnt2", ["g28"]>, DwarfRegNum<[248]>; + def GPMUCNT3: Rg<29, "gpmucnt3", ["g29"]>, DwarfRegNum<[249]>; + def G30: Rg<30, "g30">, DwarfRegNum<[250]>; + def G31: Rg<31, "g31">, DwarfRegNum<[251]>; + + // Guest Register Pairs + let SubRegIndices = [isub_lo, isub_hi], CoveredBySubRegs = 1 in { + def G1_0 : Rgg<0, "g1:0", [GELR, GSR]>, DwarfRegNum<[220]>; + def G3_2 : Rgg<2, "g3:2", [GOSP, G3]>, DwarfRegNum<[222]>; + def G5_4 : Rgg<4, "g5:4", [G4, G5]>, DwarfRegNum<[224]>; + def G7_6 : Rgg<6, "g7:6", [G6, G7]>, DwarfRegNum<[226]>; + def G9_8 : Rgg<8, "g9:8", [G8, G9]>, DwarfRegNum<[228]>; + def G11_10 : Rgg<10, "g11:10", [G10, G11]>, DwarfRegNum<[230]>; + def G13_12 : Rgg<12, "g13:12", [G12, G13]>, DwarfRegNum<[232]>; + def G15_14 : Rgg<14, "g15:14", [G14, G15]>, DwarfRegNum<[234]>; + def G17_16 : Rgg<16, "g17:16", [GPMUCNT4, GPMUCNT5]>, DwarfRegNum<[236]>; + def G19_18 : Rgg<18, "g19:18", [GPMUCNT6, GPMUCNT7]>, DwarfRegNum<[238]>; + def G21_20 : Rgg<20, "g21:20", [G20, G21]>, DwarfRegNum<[240]>; + def G23_22 : Rgg<22, "g23:22", [G22, G23]>, DwarfRegNum<[242]>; + def G25_24 : Rgg<24, "g25:24", [GPCYCLELO, GPCYCLEHI]>, DwarfRegNum<[244]>; + def G27_26 : Rgg<26, "g27:26", [GPMUCNT0, GPMUCNT1]>, DwarfRegNum<[246]>; + def G29_28 : Rgg<28, "g29:28", [GPMUCNT2, GPMUCNT3]>, DwarfRegNum<[248]>; + def G31_30 : Rgg<30, "g31:30", [G30, G31]>, DwarfRegNum<[250]>; + } + } // HVX types @@ -300,6 +366,25 @@ def CtrRegs64 : RegisterClass<"Hexagon", [i64], 64, (add C1_0, C3_2, C5_4, C7_6, C9_8, C11_10, CS, UPCYCLE, C17_16, PKTCOUNT, UTIMER)>; +let Size = 32, isAllocatable = 0 in +def GuestRegs : RegisterClass<"Hexagon", [i32], 32, + (add GELR, GSR, GOSP, + (sequence "G%u", 3, 15), + GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7, + G20, G21, G22, G23, + GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1, + GPMUCNT2, GPMUCNT3, + G30, G31)>; + +let Size = 64, isAllocatable = 0 in +def GuestRegs64 : RegisterClass<"Hexagon", [i64], 64, + (add G1_0, G3_2, + G5_4, G7_6, G9_8, G11_10, G13_12, G15_14, + G17_16, G19_18, + G21_20, G23_22, + G25_24, G27_26, G29_28, + G31_30)>; + // These registers are new for v62 and onward. // The function RegisterMatchesArch() uses this list for validation. let isAllocatable = 0 in @@ -312,7 +397,6 @@ let Size = 32, isAllocatable = 0 in def V65Regs : RegisterClass<"Hexagon", [i32], 32, (add VTMP)>; - def HexagonCSR : CalleeSavedRegs<(add R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27)>; diff --git a/llvm/test/MC/Hexagon/guest.s b/llvm/test/MC/Hexagon/guest.s new file mode 100644 index 0000000..a552afe --- /dev/null +++ b/llvm/test/MC/Hexagon/guest.s @@ -0,0 +1,67 @@ +# RUN: llvm-mc -arch=hexagon -mcpu=hexagonv62 -filetype=obj %s | llvm-objdump -d - | FileCheck %s + + r0=gpmucnt4 + # CHECK: { r0 = gpmucnt4 } + r0=gpmucnt5 + # CHECK: { r0 = gpmucnt5 } + r0=gpmucnt6 + # CHECK: { r0 = gpmucnt6 } + r0=gpmucnt7 + # CHECK: { r0 = gpmucnt7 } + r0=gpcyclelo + # CHECK: { r0 = gpcyclelo } + r0=gpcyclehi + # CHECK: { r0 = gpcyclehi } + r0=gpmucnt0 + # CHECK: { r0 = gpmucnt0 } + r0=gpmucnt1 + # CHECK: { r0 = gpmucnt1 } + r0=gpmucnt2 + # CHECK: { r0 = gpmucnt2 } + r0=gpmucnt3 + # CHECK: { r0 = gpmucnt3 } + r0=gelr + # CHECK: { r0 = gelr } + r0=gsr + # CHECK: { r0 = gsr } + r0=gosp + # CHECK: { r0 = gosp } + r0=gbadva + # CHECK: { r0 = gbadva } + + r1:0=g1:0 + # CHECK: { r1:0 = g1:0 } + r1:0=g3:2 + # CHECK: { r1:0 = g3:2 } + r1:0=g17:16 + # CHECK: { r1:0 = g17:16 } + r1:0=g19:18 + # CHECK: { r1:0 = g19:18 } + r1:0=g25:24 + # CHECK: { r1:0 = g25:24 } + r1:0=g27:26 + # CHECK: { r1:0 = g27:26 } + r1:0=g29:28 + # CHECK: { r1:0 = g29:28 } + +{ + if (!p1) callr r26 + r17=g0 + if (!p3) r26=or(r15,r9) + memb(r11+#-478)=r17.new +} +# CHECK: { r17 = gelr +# CHECK: if (!p1) callr r26 +# CHECK: if (!p3) r26 = or(r15,r9) +# CHECK: memb(r11+#-478) = r17.new } + +{ + if (!p1) callr r26 + r17=gpmucnt2 + if (!p3) r26=or(r15,r9) + memb(r11+#-478)=r17.new +} +# CHECK: { r17 = gpmucnt2 +# CHECK: if (!p1) callr r26 +# CHECK: if (!p3) r26 = or(r15,r9) +# CHECK: memb(r11+#-478) = r17.new } -- 2.7.4