mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 02:29:22 +00:00
[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
This commit is contained in:
parent
3980c542e6
commit
b7927f100d
@ -1,14 +1,14 @@
|
|||||||
set(LLVM_TARGET_DEFINITIONS Hexagon.td)
|
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 HexagonGenDisassemblerTables.inc -gen-disassembler)
|
||||||
tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
|
|
||||||
tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
|
tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
|
||||||
tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
|
tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
|
||||||
tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
|
tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
|
||||||
tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
|
|
||||||
tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
|
|
||||||
tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
|
tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
|
||||||
tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer)
|
|
||||||
add_public_tablegen_target(HexagonCommonTableGen)
|
add_public_tablegen_target(HexagonCommonTableGen)
|
||||||
|
|
||||||
add_llvm_target(HexagonCodeGen
|
add_llvm_target(HexagonCodeGen
|
||||||
|
@ -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"
|
#include "HexagonGenDisassemblerTables.inc"
|
||||||
|
|
||||||
static MCDisassembler *createHexagonDisassembler(Target const &T,
|
static MCDisassembler *createHexagonDisassembler(Target const &T,
|
||||||
|
@ -100,7 +100,7 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
||||||
TII->get(Hexagon::CONST32_Int_Real),
|
TII->get(Hexagon::CONST32_Int_Real),
|
||||||
HEXAGON_RESERVED_REG_1).addImm(Offset);
|
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)
|
HEXAGON_RESERVED_REG_1)
|
||||||
.addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
|
.addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
|
||||||
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
|
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
|
||||||
@ -146,7 +146,7 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
||||||
TII->get(Hexagon::CONST32_Int_Real),
|
TII->get(Hexagon::CONST32_Int_Real),
|
||||||
HEXAGON_RESERVED_REG_1).addImm(Offset);
|
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)
|
HEXAGON_RESERVED_REG_1)
|
||||||
.addReg(FP)
|
.addReg(FP)
|
||||||
.addReg(HEXAGON_RESERVED_REG_1);
|
.addReg(HEXAGON_RESERVED_REG_1);
|
||||||
|
@ -162,7 +162,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
|
if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
|
||||||
assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
|
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::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);
|
Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1295,10 +1295,12 @@ bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const {
|
|||||||
switch (MI->getOpcode())
|
switch (MI->getOpcode())
|
||||||
{
|
{
|
||||||
default: return false;
|
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_cPt:
|
||||||
case Hexagon::ADD_ri_cNotPt:
|
case Hexagon::ADD_ri_cNotPt:
|
||||||
case Hexagon::ADD_rr_cPt:
|
|
||||||
case Hexagon::ADD_rr_cNotPt:
|
|
||||||
case Hexagon::XOR_rr_cPt:
|
case Hexagon::XOR_rr_cPt:
|
||||||
case Hexagon::XOR_rr_cNotPt:
|
case Hexagon::XOR_rr_cNotPt:
|
||||||
case Hexagon::AND_rr_cPt:
|
case Hexagon::AND_rr_cPt:
|
||||||
|
@ -92,6 +92,84 @@ def HexagonWrapperCombineII :
|
|||||||
def HexagonWrapperCombineRR :
|
def HexagonWrapperCombineRR :
|
||||||
SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
|
SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
|
||||||
|
|
||||||
|
let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in
|
||||||
|
class T_ALU32_3op<string mnemonic, bits<3> 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<string mnemonic, bits<3> 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<string mnemonic, bits<3> MajOp, bits<3> MinOp,
|
||||||
|
bit OpsRev> {
|
||||||
|
def t : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 0>;
|
||||||
|
def f : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 0>;
|
||||||
|
def tnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 1>;
|
||||||
|
def fnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 1>;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass T_ALU32_3op_A2<string mnemonic, bits<3> MajOp, bits<3> MinOp,
|
||||||
|
bit OpsRev, bit IsComm> {
|
||||||
|
let isPredicable = 1 in
|
||||||
|
def A2_#NAME : T_ALU32_3op <mnemonic, MajOp, MinOp, OpsRev, IsComm>;
|
||||||
|
defm A2_p#NAME : T_ALU32_3op_p<mnemonic, MajOp, MinOp, OpsRev>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isCodeGenOnly = 0 in
|
||||||
|
defm add : T_ALU32_3op_A2<"add", 0b011, 0b000, 0, 1>;
|
||||||
|
|
||||||
|
// Pats for instruction selection.
|
||||||
|
class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT>
|
||||||
|
: Pat<(ResT (Op (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))),
|
||||||
|
(ResT (MI IntRegs:$Rs, IntRegs:$Rt))>;
|
||||||
|
|
||||||
|
def: BinOp32_pat<add, A2_add, i32>;
|
||||||
|
|
||||||
multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
|
multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
|
||||||
bit isPredNew> {
|
bit isPredNew> {
|
||||||
let isPredicatedNew = isPredNew in
|
let isPredicatedNew = isPredNew in
|
||||||
@ -128,7 +206,6 @@ multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isCommutable = 1 in {
|
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 AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel;
|
||||||
defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
|
defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
|
||||||
defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
|
defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
|
||||||
|
@ -176,7 +176,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
|
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::ADD_rr),
|
TII.get(Hexagon::A2_add),
|
||||||
dstReg).addReg(FrameReg).addReg(dstReg);
|
dstReg).addReg(FrameReg).addReg(dstReg);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
@ -205,7 +205,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset);
|
TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset);
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::ADD_rr),
|
TII.get(Hexagon::A2_add),
|
||||||
resReg).addReg(FrameReg).addReg(resReg);
|
resReg).addReg(FrameReg).addReg(resReg);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
@ -237,7 +237,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
|
TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg).
|
TII.get(Hexagon::A2_add), ResReg).addReg(FrameReg).
|
||||||
addReg(ResReg);
|
addReg(ResReg);
|
||||||
MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
|
MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
|
||||||
true);
|
true);
|
||||||
@ -256,7 +256,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
|
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
|
||||||
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
|
||||||
TII.get(Hexagon::ADD_rr),
|
TII.get(Hexagon::A2_add),
|
||||||
dstReg).addReg(FrameReg).addReg(dstReg);
|
dstReg).addReg(FrameReg).addReg(dstReg);
|
||||||
// Can we delete MI??? r2 = add (r2, #0).
|
// Can we delete MI??? r2 = add (r2, #0).
|
||||||
MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true);
|
MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true);
|
||||||
|
10
test/MC/Hexagon/instructions.ll
Normal file
10
test/MC/Hexagon/instructions.ll
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user