mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-05 14:34:55 +00:00
Use ARM/t2PseudoInst class from ARM/Thumb2 special adds/subs patterns.
Clean up the patterns, fix comments, and avoid confusing both tools and coders. Note that the special adds/subs SelectionDAG nodes no longer have the dummy cc_out operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9d45de252c
commit
90b7b12f01
@ -356,6 +356,15 @@ class Instruction {
|
|||||||
// associated with them. Once we've migrated all of them over to true
|
// associated with them. Once we've migrated all of them over to true
|
||||||
// pseudo-instructions that are lowered to real instructions prior to
|
// pseudo-instructions that are lowered to real instructions prior to
|
||||||
// the printer/emitter, we can remove this attribute and just use isPseudo.
|
// the printer/emitter, we can remove this attribute and just use isPseudo.
|
||||||
|
//
|
||||||
|
// The intended use is:
|
||||||
|
// isPseudo: Does not have encoding information and should be expanded,
|
||||||
|
// at the latest, during lowering to MCInst.
|
||||||
|
//
|
||||||
|
// isCodeGenOnly: Does have encoding information and can go through to the
|
||||||
|
// CodeEmitter unchanged, but duplicates a canonical instruction
|
||||||
|
// definition's encoding and should be ignored when constructing the
|
||||||
|
// assembler match tables.
|
||||||
bit isCodeGenOnly = 0;
|
bit isCodeGenOnly = 0;
|
||||||
|
|
||||||
// Is this instruction a pseudo instruction for use by the assembler parser.
|
// Is this instruction a pseudo instruction for use by the assembler parser.
|
||||||
|
@ -1478,7 +1478,6 @@ static AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[] = {
|
|||||||
{ARM::SUBSrsr, ARM::SUBrsr},
|
{ARM::SUBSrsr, ARM::SUBrsr},
|
||||||
|
|
||||||
{ARM::RSBSri, ARM::RSBri},
|
{ARM::RSBSri, ARM::RSBri},
|
||||||
{ARM::RSBSrr, ARM::RSBrr},
|
|
||||||
{ARM::RSBSrsi, ARM::RSBrsi},
|
{ARM::RSBSrsi, ARM::RSBrsi},
|
||||||
{ARM::RSBSrsr, ARM::RSBrsr},
|
{ARM::RSBSrsr, ARM::RSBrsr},
|
||||||
|
|
||||||
|
@ -6319,8 +6319,8 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
|||||||
|
|
||||||
void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
|
void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
|
||||||
SDNode *Node) const {
|
SDNode *Node) const {
|
||||||
const MCInstrDesc &MCID = MI->getDesc();
|
const MCInstrDesc *MCID = &MI->getDesc();
|
||||||
if (!MCID.hasPostISelHook()) {
|
if (!MCID->hasPostISelHook()) {
|
||||||
assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
|
assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
|
||||||
"Pseudo flag-setting opcodes must be marked with 'hasPostISelHook'");
|
"Pseudo flag-setting opcodes must be marked with 'hasPostISelHook'");
|
||||||
return;
|
return;
|
||||||
@ -6331,20 +6331,28 @@ void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
|
|||||||
// operand is still set to noreg. If needed, set the optional operand's
|
// operand is still set to noreg. If needed, set the optional operand's
|
||||||
// register to CPSR, and remove the redundant implicit def.
|
// register to CPSR, and remove the redundant implicit def.
|
||||||
//
|
//
|
||||||
// e.g. ADCS (...opt:%noreg, CPSR<imp-def>) -> ADC (... opt:CPSR<def>).
|
// e.g. ADCS (..., CPSR<imp-def>) -> ADC (... opt:CPSR<def>).
|
||||||
|
|
||||||
// Rename pseudo opcodes.
|
// Rename pseudo opcodes.
|
||||||
unsigned NewOpc = convertAddSubFlagsOpcode(MI->getOpcode());
|
unsigned NewOpc = convertAddSubFlagsOpcode(MI->getOpcode());
|
||||||
if (NewOpc) {
|
if (NewOpc) {
|
||||||
const ARMBaseInstrInfo *TII =
|
const ARMBaseInstrInfo *TII =
|
||||||
static_cast<const ARMBaseInstrInfo*>(getTargetMachine().getInstrInfo());
|
static_cast<const ARMBaseInstrInfo*>(getTargetMachine().getInstrInfo());
|
||||||
MI->setDesc(TII->get(NewOpc));
|
MCID = &TII->get(NewOpc);
|
||||||
|
|
||||||
|
assert(MCID->getNumOperands() == MI->getDesc().getNumOperands() + 1 &&
|
||||||
|
"converted opcode should be the same except for cc_out");
|
||||||
|
|
||||||
|
MI->setDesc(*MCID);
|
||||||
|
|
||||||
|
// Add the optional cc_out operand
|
||||||
|
MI->addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
|
||||||
}
|
}
|
||||||
unsigned ccOutIdx = MCID.getNumOperands() - 1;
|
unsigned ccOutIdx = MCID->getNumOperands() - 1;
|
||||||
|
|
||||||
// Any ARM instruction that sets the 's' bit should specify an optional
|
// Any ARM instruction that sets the 's' bit should specify an optional
|
||||||
// "cc_out" operand in the last operand position.
|
// "cc_out" operand in the last operand position.
|
||||||
if (!MCID.hasOptionalDef() || !MCID.OpInfo[ccOutIdx].isOptionalDef()) {
|
if (!MCID->hasOptionalDef() || !MCID->OpInfo[ccOutIdx].isOptionalDef()) {
|
||||||
assert(!NewOpc && "Optional cc_out operand required");
|
assert(!NewOpc && "Optional cc_out operand required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -6352,7 +6360,7 @@ void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
|
|||||||
// since we already have an optional CPSR def.
|
// since we already have an optional CPSR def.
|
||||||
bool definesCPSR = false;
|
bool definesCPSR = false;
|
||||||
bool deadCPSR = false;
|
bool deadCPSR = false;
|
||||||
for (unsigned i = MCID.getNumOperands(), e = MI->getNumOperands();
|
for (unsigned i = MCID->getNumOperands(), e = MI->getNumOperands();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
|
if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
|
||||||
|
@ -1040,69 +1040,58 @@ multiclass AsI1_rbin_irs<bits<4> opcod, string opc,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AsI1_rbin_s_is - Same as AsI1_rbin_s_is except it sets 's' bit by default.
|
|
||||||
///
|
|
||||||
/// These opcodes will be converted to the real non-S opcodes by
|
|
||||||
/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
|
|
||||||
let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in {
|
|
||||||
multiclass AsI1_rbin_s_is<bits<4> opcod, string opc,
|
|
||||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
|
||||||
PatFrag opnode, bit Commutable = 0> {
|
|
||||||
def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
|
|
||||||
iii, opc, "\t$Rd, $Rn, $imm",
|
|
||||||
[(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>;
|
|
||||||
|
|
||||||
def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
|
|
||||||
iir, opc, "\t$Rd, $Rn, $Rm",
|
|
||||||
[/* pattern left blank */]>;
|
|
||||||
|
|
||||||
def rsi : AsI1<opcod, (outs GPR:$Rd),
|
|
||||||
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
|
|
||||||
iis, opc, "\t$Rd, $Rn, $shift",
|
|
||||||
[(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift, GPR:$Rn))]>;
|
|
||||||
|
|
||||||
def rsr : AsI1<opcod, (outs GPR:$Rd),
|
|
||||||
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
|
|
||||||
iis, opc, "\t$Rd, $Rn, $shift",
|
|
||||||
[(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift, GPR:$Rn))]> {
|
|
||||||
bits<4> Rd;
|
|
||||||
bits<4> Rn;
|
|
||||||
bits<12> shift;
|
|
||||||
let Inst{25} = 0;
|
|
||||||
let Inst{19-16} = Rn;
|
|
||||||
let Inst{15-12} = Rd;
|
|
||||||
let Inst{11-8} = shift{11-8};
|
|
||||||
let Inst{7} = 0;
|
|
||||||
let Inst{6-5} = shift{6-5};
|
|
||||||
let Inst{4} = 1;
|
|
||||||
let Inst{3-0} = shift{3-0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
|
/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
|
||||||
///
|
///
|
||||||
/// These opcodes will be converted to the real non-S opcodes by
|
/// These opcodes will be converted to the real non-S opcodes by
|
||||||
/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
|
/// AdjustInstrPostInstrSelection after giving them an optional CPSR operand.
|
||||||
let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in {
|
let hasPostISelHook = 1, Defs = [CPSR] in {
|
||||||
multiclass AsI1_bin_s_irs<bits<4> opcod, string opc,
|
multiclass AsI1_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
|
||||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
InstrItinClass iis, PatFrag opnode,
|
||||||
PatFrag opnode, bit Commutable = 0> {
|
bit Commutable = 0> {
|
||||||
def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
|
def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
|
||||||
iii, opc, "\t$Rd, $Rn, $imm",
|
4, iii,
|
||||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>;
|
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]>;
|
||||||
def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
|
|
||||||
iir, opc, "\t$Rd, $Rn, $Rm",
|
|
||||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]>;
|
|
||||||
def rsi : AsI1<opcod, (outs GPR:$Rd),
|
|
||||||
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
|
|
||||||
iis, opc, "\t$Rd, $Rn, $shift",
|
|
||||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift))]>;
|
|
||||||
|
|
||||||
def rsr : AsI1<opcod, (outs GPR:$Rd),
|
def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p),
|
||||||
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
|
4, iir,
|
||||||
iis, opc, "\t$Rd, $Rn, $shift",
|
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]> {
|
||||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_reg:$shift))]>;
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
|
def rsi : ARMPseudoInst<(outs GPR:$Rd),
|
||||||
|
(ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
|
||||||
|
4, iis,
|
||||||
|
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
|
||||||
|
so_reg_imm:$shift))]>;
|
||||||
|
|
||||||
|
def rsr : ARMPseudoInst<(outs GPR:$Rd),
|
||||||
|
(ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
|
||||||
|
4, iis,
|
||||||
|
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn,
|
||||||
|
so_reg_reg:$shift))]>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AsI1_rbin_s_is - Same as AsI1_bin_s_irs, except selection DAG
|
||||||
|
/// operands are reversed.
|
||||||
|
let hasPostISelHook = 1, Defs = [CPSR] in {
|
||||||
|
multiclass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir,
|
||||||
|
InstrItinClass iis, PatFrag opnode,
|
||||||
|
bit Commutable = 0> {
|
||||||
|
def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm, pred:$p),
|
||||||
|
4, iii,
|
||||||
|
[(set GPR:$Rd, CPSR, (opnode so_imm:$imm, GPR:$Rn))]>;
|
||||||
|
|
||||||
|
def rsi : ARMPseudoInst<(outs GPR:$Rd),
|
||||||
|
(ins GPR:$Rn, so_reg_imm:$shift, pred:$p),
|
||||||
|
4, iis,
|
||||||
|
[(set GPR:$Rd, CPSR, (opnode so_reg_imm:$shift,
|
||||||
|
GPR:$Rn))]>;
|
||||||
|
|
||||||
|
def rsr : ARMPseudoInst<(outs GPR:$Rd),
|
||||||
|
(ins GPR:$Rn, so_reg_reg:$shift, pred:$p),
|
||||||
|
4, iis,
|
||||||
|
[(set GPR:$Rd, CPSR, (opnode so_reg_reg:$shift,
|
||||||
|
GPR:$Rn))]>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3079,20 +3068,18 @@ defm SUB : AsI1_bin_irs<0b0010, "sub",
|
|||||||
|
|
||||||
// ADD and SUB with 's' bit set.
|
// ADD and SUB with 's' bit set.
|
||||||
//
|
//
|
||||||
// Currently, t2ADDS/t2SUBS are pseudo opcodes that exist only in the
|
// Currently, ADDS/SUBS are pseudo opcodes that exist only in the
|
||||||
// selection DAG. They are "lowered" to real t2ADD/t2SUB opcodes by
|
// selection DAG. They are "lowered" to real ADD/SUB opcodes by
|
||||||
// AdjustInstrPostInstrSelection where we determine whether or not to
|
// AdjustInstrPostInstrSelection where we determine whether or not to
|
||||||
// set the "s" bit based on CPSR liveness.
|
// set the "s" bit based on CPSR liveness.
|
||||||
//
|
//
|
||||||
// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen
|
// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
|
||||||
// support for an optional CPSR definition that corresponds to the DAG
|
// support for an optional CPSR definition that corresponds to the DAG
|
||||||
// node's second value. We can then eliminate the implicit def of CPSR.
|
// node's second value. We can then eliminate the implicit def of CPSR.
|
||||||
defm ADDS : AsI1_bin_s_irs<0b0100, "add",
|
defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
||||||
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||||
defm SUBS : AsI1_bin_s_irs<0b0010, "sub",
|
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
|
||||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
|
||||||
|
|
||||||
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
|
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
|
||||||
BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>,
|
BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>,
|
||||||
@ -3107,9 +3094,8 @@ defm RSB : AsI1_rbin_irs <0b0011, "rsb",
|
|||||||
|
|
||||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||||
// CPSR and the implicit def of CPSR is not needed.
|
// CPSR and the implicit def of CPSR is not needed.
|
||||||
defm RSBS : AsI1_rbin_s_is<0b0011, "rsb",
|
defm RSBS : AsI1_rbin_s_is<IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
|
||||||
|
|
||||||
defm RSC : AI1_rsc_irs<0b0111, "rsc",
|
defm RSC : AI1_rsc_irs<0b0111, "rsc",
|
||||||
BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>,
|
BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>,
|
||||||
|
@ -608,25 +608,48 @@ multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
|
|||||||
///
|
///
|
||||||
/// These opcodes will be converted to the real non-S opcodes by
|
/// These opcodes will be converted to the real non-S opcodes by
|
||||||
/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
|
/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
|
||||||
let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in {
|
let hasPostISelHook = 1, Defs = [CPSR] in {
|
||||||
multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
|
multiclass T2I_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
|
||||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
InstrItinClass iis, PatFrag opnode,
|
||||||
PatFrag opnode, bit Commutable = 0> {
|
bit Commutable = 0> {
|
||||||
// shifted imm
|
// shifted imm
|
||||||
def ri : T2sTwoRegImm<
|
def ri : t2PseudoInst<(outs rGPR:$Rd),
|
||||||
(outs rGPR:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), iii,
|
(ins GPRnopc:$Rn, t2_so_imm:$imm, pred:$p),
|
||||||
opc, ".w\t$Rd, $Rn, $imm",
|
4, iii,
|
||||||
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>;
|
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
|
||||||
|
t2_so_imm:$imm))]>;
|
||||||
// register
|
// register
|
||||||
def rr : T2sThreeReg<
|
def rr : t2PseudoInst<(outs rGPR:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm, pred:$p),
|
||||||
(outs rGPR:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm), iir,
|
4, iir,
|
||||||
opc, ".w\t$Rd, $Rn, $Rm",
|
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
|
||||||
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, rGPR:$Rm))]>;
|
rGPR:$Rm))]> {
|
||||||
|
let isCommutable = Commutable;
|
||||||
|
}
|
||||||
// shifted register
|
// shifted register
|
||||||
def rs : T2sTwoRegShiftedReg<
|
def rs : t2PseudoInst<(outs rGPR:$Rd),
|
||||||
(outs rGPR:$Rd), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), iis,
|
(ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p),
|
||||||
opc, ".w\t$Rd, $Rn, $ShiftedRm",
|
4, iis,
|
||||||
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>;
|
[(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
|
||||||
|
t2_so_reg:$ShiftedRm))]>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// T2I_rbin_s_is - Same as T2I_bin_s_irs, except selection DAG
|
||||||
|
/// operands are reversed.
|
||||||
|
let hasPostISelHook = 1, Defs = [CPSR] in {
|
||||||
|
multiclass T2I_rbin_s_is<PatFrag opnode> {
|
||||||
|
// shifted imm
|
||||||
|
def ri : t2PseudoInst<(outs rGPR:$Rd),
|
||||||
|
(ins GPRnopc:$Rn, t2_so_imm:$imm, pred:$p),
|
||||||
|
4, IIC_iALUi,
|
||||||
|
[(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm,
|
||||||
|
GPRnopc:$Rn))]>;
|
||||||
|
// shifted register
|
||||||
|
def rs : t2PseudoInst<(outs rGPR:$Rd),
|
||||||
|
(ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p),
|
||||||
|
4, IIC_iALUsi,
|
||||||
|
[(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm,
|
||||||
|
GPRnopc:$Rn))]>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,26 +758,6 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
|
|
||||||
/// version is not needed since this is only for codegen.
|
|
||||||
///
|
|
||||||
/// These opcodes will be converted to the real non-S opcodes by
|
|
||||||
/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
|
|
||||||
let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in {
|
|
||||||
multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
|
|
||||||
// shifted imm
|
|
||||||
def ri : T2sTwoRegImm<
|
|
||||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
|
|
||||||
opc, ".w\t$Rd, $Rn, $imm",
|
|
||||||
[(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm, rGPR:$Rn))]>;
|
|
||||||
// shifted register
|
|
||||||
def rs : T2sTwoRegShiftedReg<
|
|
||||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
|
|
||||||
IIC_iALUsi, opc, "\t$Rd, $Rn, $ShiftedRm",
|
|
||||||
[(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
|
/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
|
||||||
// rotate operation that produces a value.
|
// rotate operation that produces a value.
|
||||||
multiclass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode,
|
multiclass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode,
|
||||||
@ -1845,11 +1848,9 @@ defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
|
|||||||
// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen
|
// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen
|
||||||
// support for an optional CPSR definition that corresponds to the DAG
|
// support for an optional CPSR definition that corresponds to the DAG
|
||||||
// node's second value. We can then eliminate the implicit def of CPSR.
|
// node's second value. We can then eliminate the implicit def of CPSR.
|
||||||
defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
|
defm t2ADDS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi,
|
||||||
IIC_iALUi, IIC_iALUr, IIC_iALUsi,
|
|
||||||
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
||||||
defm t2SUBS : T2I_bin_s_irs <0b1101, "sub",
|
defm t2SUBS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi,
|
||||||
IIC_iALUi, IIC_iALUr, IIC_iALUsi,
|
|
||||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||||
|
|
||||||
let hasPostISelHook = 1 in {
|
let hasPostISelHook = 1 in {
|
||||||
@ -1865,8 +1866,7 @@ defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
|
|||||||
|
|
||||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||||
// CPSR and the implicit def of CPSR is not needed.
|
// CPSR and the implicit def of CPSR is not needed.
|
||||||
defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
|
defm t2RSBS : T2I_rbin_s_is <BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
|
||||||
|
|
||||||
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
|
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
|
||||||
// The assume-no-carry-in form uses the negation of the input since add/sub
|
// The assume-no-carry-in form uses the negation of the input since add/sub
|
||||||
|
Loading…
x
Reference in New Issue
Block a user