From b7927f100d597b7ea0bbe933d45063382f756b43 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Tue, 18 Nov 2014 20:28:11 +0000 Subject: [PATCH] [Hexagon] Converting from ADD_rr to A2_add which has encoding bits. Adding test to show correct instruction selection and encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222249 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/CMakeLists.txt | 10 +-- .../Disassembler/HexagonDisassembler.cpp | 34 ++++++++ .../Hexagon/HexagonExpandPredSpillCode.cpp | 4 +- lib/Target/Hexagon/HexagonFrameLowering.cpp | 2 +- lib/Target/Hexagon/HexagonInstrInfo.cpp | 6 +- lib/Target/Hexagon/HexagonInstrInfo.td | 79 ++++++++++++++++++- lib/Target/Hexagon/HexagonRegisterInfo.cpp | 8 +- test/MC/Hexagon/instructions.ll | 10 +++ 8 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 test/MC/Hexagon/instructions.ll diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt index 85bfce103f6..d64ecaf5351 100644 --- a/lib/Target/Hexagon/CMakeLists.txt +++ b/lib/Target/Hexagon/CMakeLists.txt @@ -1,14 +1,14 @@ set(LLVM_TARGET_DEFINITIONS Hexagon.td) +tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv) +tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer) tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler) -tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info) tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info) tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter) -tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer) -tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel) -tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv) +tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info) tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget) -tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer) add_public_tablegen_target(HexagonCommonTableGen) add_llvm_target(HexagonCodeGen diff --git a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index c213abb026e..bc64be17b97 100644 --- a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -48,6 +48,40 @@ public: }; } +static const uint16_t IntRegDecoderTable[] = { + Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, + Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, + Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, + Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, + Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, + Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, + Hexagon::R30, Hexagon::R31 }; + +static const uint16_t PredRegDecoderTable[] = { Hexagon::P0, Hexagon::P1, +Hexagon::P2, Hexagon::P3 }; + +static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + void const *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Register = IntRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::CreateReg(Register)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + void const *Decoder) { + if (RegNo > 3) + return MCDisassembler::Fail; + + unsigned Register = PredRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::CreateReg(Register)); + return MCDisassembler::Success; +} + #include "HexagonGenDisassemblerTables.inc" static MCDisassembler *createHexagonDisassembler(Target const &T, diff --git a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp index 34319ee3627..8ef4c3ad74e 100644 --- a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp +++ b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp @@ -100,7 +100,7 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(Offset); - BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), + BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), HEXAGON_RESERVED_REG_1) .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), @@ -146,7 +146,7 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(Offset); - BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), + BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), HEXAGON_RESERVED_REG_1) .addReg(FP) .addReg(HEXAGON_RESERVED_REG_1); diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index 28e2f5529fd..356f2793c9f 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -162,7 +162,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF, if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) { assert(MBBI->getOperand(0).isReg() && "Offset should be in register!"); BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); - BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr), + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::A2_add), Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28); return; } diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index 1fc4f7f4979..0b32d8cd6e0 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1295,10 +1295,12 @@ bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const { switch (MI->getOpcode()) { default: return false; + case Hexagon::A2_paddf: + case Hexagon::A2_paddfnew: + case Hexagon::A2_paddt: + case Hexagon::A2_paddtnew: case Hexagon::ADD_ri_cPt: case Hexagon::ADD_ri_cNotPt: - case Hexagon::ADD_rr_cPt: - case Hexagon::ADD_rr_cNotPt: case Hexagon::XOR_rr_cPt: case Hexagon::XOR_rr_cNotPt: case Hexagon::AND_rr_cPt: diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 42ecab9538a..3acefd5851f 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -92,6 +92,84 @@ def HexagonWrapperCombineII : def HexagonWrapperCombineRR : SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>; +let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in +class T_ALU32_3op MajOp, bits<3> MinOp, bit OpsRev, + bit IsComm> + : ALU32_rr<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt), + "$Rd = "#mnemonic#"($Rs, $Rt)", + [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredRel { + let isCommutable = IsComm; + let BaseOpcode = mnemonic#_rr; + let CextOpcode = mnemonic; + + bits<5> Rs; + bits<5> Rt; + bits<5> Rd; + + let IClass = 0b1111; + let Inst{27} = 0b0; + let Inst{26-24} = MajOp; + let Inst{23-21} = MinOp; + let Inst{20-16} = !if(OpsRev,Rt,Rs); + let Inst{12-8} = !if(OpsRev,Rs,Rt); + let Inst{4-0} = Rd; +} + +let hasSideEffects = 0, hasNewValue = 1 in +class T_ALU32_3op_pred MajOp, bits<3> MinOp, + bit OpsRev, bit PredNot, bit PredNew> + : ALU32_rr<(outs IntRegs:$Rd), (ins PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt), + "if ("#!if(PredNot,"!","")#"$Pu"#!if(PredNew,".new","")#") "# + "$Rd = "#mnemonic#"($Rs, $Rt)", + [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredNewRel { + let isPredicated = 1; + let isPredicatedFalse = PredNot; + let isPredicatedNew = PredNew; + let BaseOpcode = mnemonic#_rr; + let CextOpcode = mnemonic; + + bits<2> Pu; + bits<5> Rs; + bits<5> Rt; + bits<5> Rd; + + let IClass = 0b1111; + let Inst{27} = 0b1; + let Inst{26-24} = MajOp; + let Inst{23-21} = MinOp; + let Inst{20-16} = !if(OpsRev,Rt,Rs); + let Inst{13} = PredNew; + let Inst{12-8} = !if(OpsRev,Rs,Rt); + let Inst{7} = PredNot; + let Inst{6-5} = Pu; + let Inst{4-0} = Rd; +} + +multiclass T_ALU32_3op_p MajOp, bits<3> MinOp, + bit OpsRev> { + def t : T_ALU32_3op_pred; + def f : T_ALU32_3op_pred; + def tnew : T_ALU32_3op_pred; + def fnew : T_ALU32_3op_pred; +} + +multiclass T_ALU32_3op_A2 MajOp, bits<3> MinOp, + bit OpsRev, bit IsComm> { + let isPredicable = 1 in + def A2_#NAME : T_ALU32_3op ; + defm A2_p#NAME : T_ALU32_3op_p; +} + +let isCodeGenOnly = 0 in +defm add : T_ALU32_3op_A2<"add", 0b011, 0b000, 0, 1>; + +// Pats for instruction selection. +class BinOp32_pat + : Pat<(ResT (Op (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))), + (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>; + +def: BinOp32_pat; + multiclass ALU32_Pbase { let isPredicatedNew = isPredNew in @@ -128,7 +206,6 @@ multiclass ALU32_base { } let isCommutable = 1 in { - defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel; defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel; defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel; defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel; diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp index 29613d37176..2b6741cf3e0 100644 --- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -176,7 +176,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, BuildMI(*MI.getParent(), II, MI.getDebugLoc(), TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), + TII.get(Hexagon::A2_add), dstReg).addReg(FrameReg).addReg(dstReg); } else { BuildMI(*MI.getParent(), II, MI.getDebugLoc(), @@ -205,7 +205,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, BuildMI(*MI.getParent(), II, MI.getDebugLoc(), TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), + TII.get(Hexagon::A2_add), resReg).addReg(FrameReg).addReg(resReg); } else { BuildMI(*MI.getParent(), II, MI.getDebugLoc(), @@ -237,7 +237,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, BuildMI(*MI.getParent(), II, MI.getDebugLoc(), TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset); BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg). + TII.get(Hexagon::A2_add), ResReg).addReg(FrameReg). addReg(ResReg); MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false, true); @@ -256,7 +256,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, BuildMI(*MI.getParent(), II, MI.getDebugLoc(), TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), + TII.get(Hexagon::A2_add), dstReg).addReg(FrameReg).addReg(dstReg); // Can we delete MI??? r2 = add (r2, #0). MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true); diff --git a/test/MC/Hexagon/instructions.ll b/test/MC/Hexagon/instructions.ll new file mode 100644 index 00000000000..5377d946910 --- /dev/null +++ b/test/MC/Hexagon/instructions.ll @@ -0,0 +1,10 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-objdump -s - | FileCheck %s + +define i32 @foo (i32 %a, i32 %b) +{ + %1 = add i32 %a, %b + ret i32 %1 +} + +; CHECK: 0000 004100f3 00c09f52 \ No newline at end of file