mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
Recommitting parts of r48130. These do not appear to cause the observed failures.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48223 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5b4153710e
commit
1fab4a6bbb
@ -90,32 +90,21 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
|
|||||||
MachineFunction &MF = *MBB->getParent();
|
MachineFunction &MF = *MBB->getParent();
|
||||||
const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
|
const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
|
||||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||||
unsigned DstReg = 0;
|
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
||||||
|
((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) ||
|
||||||
|
MI->getOperand(1).isImmediate()) &&
|
||||||
|
(MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
|
||||||
|
MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
|
||||||
|
|
||||||
|
unsigned DstReg = MI->getOperand(0).getReg();
|
||||||
unsigned SrcReg = 0;
|
unsigned SrcReg = 0;
|
||||||
unsigned InsReg = 0;
|
// Check if we're inserting into an implicit value.
|
||||||
unsigned SubIdx = 0;
|
if (MI->getOperand(1).isImmediate())
|
||||||
|
|
||||||
// If only have 3 operands, then the source superreg is undef
|
|
||||||
// and we can supress the copy from the undef value
|
|
||||||
if (MI->getNumOperands() == 3) {
|
|
||||||
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
|
||||||
(MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
|
|
||||||
MI->getOperand(2).isImmediate() && "Invalid extract_subreg");
|
|
||||||
DstReg = MI->getOperand(0).getReg();
|
|
||||||
SrcReg = DstReg;
|
SrcReg = DstReg;
|
||||||
InsReg = MI->getOperand(1).getReg();
|
else
|
||||||
SubIdx = MI->getOperand(2).getImm();
|
|
||||||
} else if (MI->getNumOperands() == 4) {
|
|
||||||
assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
|
|
||||||
(MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
|
|
||||||
(MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
|
|
||||||
MI->getOperand(3).isImmediate() && "Invalid extract_subreg");
|
|
||||||
DstReg = MI->getOperand(0).getReg();
|
|
||||||
SrcReg = MI->getOperand(1).getReg();
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
InsReg = MI->getOperand(2).getReg();
|
unsigned InsReg = MI->getOperand(2).getReg();
|
||||||
SubIdx = MI->getOperand(3).getImm();
|
unsigned SubIdx = MI->getOperand(3).getImm();
|
||||||
} else
|
|
||||||
assert(0 && "Malformed extract_subreg");
|
|
||||||
|
|
||||||
assert(SubIdx != 0 && "Invalid index for extract_subreg");
|
assert(SubIdx != 0 && "Invalid index for extract_subreg");
|
||||||
unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
|
unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
|
||||||
|
@ -695,19 +695,11 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
|
|||||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||||
|
|
||||||
} else if (Opc == TargetInstrInfo::INSERT_SUBREG) {
|
} else if (Opc == TargetInstrInfo::INSERT_SUBREG) {
|
||||||
assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) &&
|
SDOperand N0 = Node->getOperand(0);
|
||||||
"Malformed insert_subreg node");
|
SDOperand N1 = Node->getOperand(1);
|
||||||
bool isUndefInput = (Node->getNumOperands() == 2);
|
SDOperand N2 = Node->getOperand(2);
|
||||||
unsigned SubReg = 0;
|
unsigned SubReg = getVR(N1, VRBaseMap);
|
||||||
unsigned SubIdx = 0;
|
unsigned SubIdx = cast<ConstantSDNode>(N2)->getValue();
|
||||||
|
|
||||||
if (isUndefInput) {
|
|
||||||
SubReg = getVR(Node->getOperand(0), VRBaseMap);
|
|
||||||
SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
|
|
||||||
} else {
|
|
||||||
SubReg = getVR(Node->getOperand(1), VRBaseMap);
|
|
||||||
SubIdx = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs
|
// TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs
|
||||||
// to allow coalescing in the allocator
|
// to allow coalescing in the allocator
|
||||||
@ -745,9 +737,15 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
||||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
|
|
||||||
if (!isUndefInput)
|
// If N0 is a constant then it indicates the insert is being done
|
||||||
AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap);
|
// into a target specific constant value, not a register.
|
||||||
|
if (const ConstantSDNode *SD = dyn_cast<ConstantSDNode>(N0))
|
||||||
|
MI->addOperand(MachineOperand::CreateImm(SD->getValue()));
|
||||||
|
else
|
||||||
|
AddOperand(MI, N0, 0, 0, VRBaseMap);
|
||||||
|
// Add the subregster being inserted
|
||||||
|
AddOperand(MI, N1, 0, 0, VRBaseMap);
|
||||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||||
} else
|
} else
|
||||||
assert(0 && "Node is not a subreg insert or extract");
|
assert(0 && "Node is not a subreg insert or extract");
|
||||||
|
@ -263,6 +263,10 @@ def variable_ops;
|
|||||||
/// flags. But currently we have but one flag.
|
/// flags. But currently we have but one flag.
|
||||||
def ptr_rc;
|
def ptr_rc;
|
||||||
|
|
||||||
|
/// unknown definition - Mark this operand as being of unknown type, causing
|
||||||
|
/// it to be resolved by inference in the context it is used.
|
||||||
|
def unknown;
|
||||||
|
|
||||||
/// Operand Types - These provide the built-in operand types that may be used
|
/// Operand Types - These provide the built-in operand types that may be used
|
||||||
/// by a target. Targets can optionally provide their own operand types as
|
/// by a target. Targets can optionally provide their own operand types as
|
||||||
/// needed, though this should not be needed for RISC targets.
|
/// needed, though this should not be needed for RISC targets.
|
||||||
@ -351,15 +355,15 @@ def DECLARE : Instruction {
|
|||||||
let hasCtrlDep = 1;
|
let hasCtrlDep = 1;
|
||||||
}
|
}
|
||||||
def EXTRACT_SUBREG : Instruction {
|
def EXTRACT_SUBREG : Instruction {
|
||||||
let OutOperandList = (ops variable_ops);
|
let OutOperandList = (ops unknown:$dst);
|
||||||
let InOperandList = (ops variable_ops);
|
let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
|
||||||
let AsmString = "";
|
let AsmString = "";
|
||||||
let Namespace = "TargetInstrInfo";
|
let Namespace = "TargetInstrInfo";
|
||||||
let neverHasSideEffects = 1;
|
let neverHasSideEffects = 1;
|
||||||
}
|
}
|
||||||
def INSERT_SUBREG : Instruction {
|
def INSERT_SUBREG : Instruction {
|
||||||
let OutOperandList = (ops variable_ops);
|
let OutOperandList = (ops unknown:$dst);
|
||||||
let InOperandList = (ops variable_ops);
|
let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
|
||||||
let AsmString = "";
|
let AsmString = "";
|
||||||
let Namespace = "TargetInstrInfo";
|
let Namespace = "TargetInstrInfo";
|
||||||
let neverHasSideEffects = 1;
|
let neverHasSideEffects = 1;
|
||||||
|
@ -1533,22 +1533,27 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
|
|||||||
AddToISelQueue(N0);
|
AddToISelQueue(N0);
|
||||||
if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
|
if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
|
||||||
SDOperand SRIdx;
|
SDOperand SRIdx;
|
||||||
|
SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF,
|
||||||
|
MVT::i32);
|
||||||
switch(N0.getValueType()) {
|
switch(N0.getValueType()) {
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
|
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
|
||||||
|
// x86-64 zero extends 32-bit inserts int 64-bit registers
|
||||||
|
if (Subtarget->is64Bit())
|
||||||
|
ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);
|
||||||
break;
|
break;
|
||||||
case MVT::i16:
|
case MVT::i16:
|
||||||
SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
|
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
|
||||||
break;
|
break;
|
||||||
case MVT::i8:
|
case MVT::i8:
|
||||||
if (Subtarget->is64Bit())
|
if (Subtarget->is64Bit())
|
||||||
SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
|
SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
|
||||||
break;
|
break;
|
||||||
default: assert(0 && "Unknown any_extend!");
|
default: assert(0 && "Unknown any_extend!");
|
||||||
}
|
}
|
||||||
if (SRIdx.Val) {
|
if (SRIdx.Val) {
|
||||||
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
|
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
|
||||||
NVT, N0, SRIdx);
|
NVT, ImplVal, N0, SRIdx);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
DOUT << std::string(Indent-2, ' ') << "=> ";
|
||||||
|
@ -46,6 +46,14 @@ namespace X86 {
|
|||||||
COND_INVALID
|
COND_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// X86 specific implict values used for subregister inserts.
|
||||||
|
// This can be used to model the fact that x86-64 by default
|
||||||
|
// inserts 32-bit values into 64-bit registers implicitly containing zeros.
|
||||||
|
enum ImplicitVal {
|
||||||
|
IMPL_VAL_UNDEF = 0,
|
||||||
|
IMPL_VAL_ZERO = 1
|
||||||
|
};
|
||||||
|
|
||||||
// Turn condition code into conditional branch opcode.
|
// Turn condition code into conditional branch opcode.
|
||||||
unsigned GetCondBranchFromCond(CondCode CC);
|
unsigned GetCondBranchFromCond(CondCode CC);
|
||||||
|
|
||||||
|
@ -161,6 +161,10 @@ def i32i8imm : Operand<i32>;
|
|||||||
// Branch targets have OtherVT type.
|
// Branch targets have OtherVT type.
|
||||||
def brtarget : Operand<OtherVT>;
|
def brtarget : Operand<OtherVT>;
|
||||||
|
|
||||||
|
// These should match the enum X86::ImplicitVal
|
||||||
|
def x86_impl_val_undef : PatLeaf<(i32 0)>;
|
||||||
|
def x86_impl_val_zero : PatLeaf<(i32 1)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// X86 Complex Pattern Definitions.
|
// X86 Complex Pattern Definitions.
|
||||||
//
|
//
|
||||||
|
@ -32,6 +32,15 @@ namespace N86 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace X86 {
|
||||||
|
/// SubregIndex - The index of various sized subregister classes. Note that
|
||||||
|
/// these indices must be kept in sync with the class indices in the
|
||||||
|
/// X86RegisterInfo.td file.
|
||||||
|
enum SubregIndex {
|
||||||
|
SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// DWARFFlavour - Flavour of dwarf regnumbers
|
/// DWARFFlavour - Flavour of dwarf regnumbers
|
||||||
///
|
///
|
||||||
namespace DWARFFlavour {
|
namespace DWARFFlavour {
|
||||||
|
@ -176,6 +176,10 @@ let Namespace = "X86" in {
|
|||||||
// sub registers for each register.
|
// sub registers for each register.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
def x86_subreg_8bit : PatLeaf<(i32 1)>;
|
||||||
|
def x86_subreg_16bit : PatLeaf<(i32 2)>;
|
||||||
|
def x86_subreg_32bit : PatLeaf<(i32 3)>;
|
||||||
|
|
||||||
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
|
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
|
||||||
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
|
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
|
||||||
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,
|
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,
|
||||||
|
Loading…
Reference in New Issue
Block a user