mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 16:17:17 +00:00
Add ScheduleDAG support for copytoreg where the src/dst register are
in different register classes, e.g. copy of ST(0) to RFP*. This gets some really trivial inline asm working that plops things on the top of stack (PR879) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48105 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -433,21 +433,25 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TargetRegisterClass *TRC = 0;
|
const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
|
||||||
|
SrcRC = TRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg);
|
||||||
|
|
||||||
// Figure out the register class to create for the destreg.
|
// Figure out the register class to create for the destreg.
|
||||||
if (VRBase)
|
if (VRBase) {
|
||||||
TRC = RegInfo.getRegClass(VRBase);
|
DstRC = RegInfo.getRegClass(VRBase);
|
||||||
else
|
} else {
|
||||||
TRC = TRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg);
|
DstRC = DAG.getTargetLoweringInfo()
|
||||||
|
.getRegClassFor(Node->getValueType(ResNo));
|
||||||
|
}
|
||||||
|
|
||||||
// If all uses are reading from the src physical register and copying the
|
// If all uses are reading from the src physical register and copying the
|
||||||
// register is either impossible or very expensive, then don't create a copy.
|
// register is either impossible or very expensive, then don't create a copy.
|
||||||
if (MatchReg && TRC->getCopyCost() < 0) {
|
if (MatchReg && SrcRC->getCopyCost() < 0) {
|
||||||
VRBase = SrcReg;
|
VRBase = SrcReg;
|
||||||
} else {
|
} else {
|
||||||
// Create the reg, emit the copy.
|
// Create the reg, emit the copy.
|
||||||
VRBase = RegInfo.createVirtualRegister(TRC);
|
VRBase = RegInfo.createVirtualRegister(DstRC);
|
||||||
TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC, TRC);
|
TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InstanceNo > 0)
|
if (InstanceNo > 0)
|
||||||
@@ -594,14 +598,14 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
|
|||||||
unsigned VReg = getVR(Op, VRBaseMap);
|
unsigned VReg = getVR(Op, VRBaseMap);
|
||||||
MI->addOperand(MachineOperand::CreateReg(VReg, false));
|
MI->addOperand(MachineOperand::CreateReg(VReg, false));
|
||||||
|
|
||||||
// Verify that it is right.
|
// Verify that it is right. Note that the reg class of the physreg and the
|
||||||
|
// vreg don't necessarily need to match, but the target copy insertion has
|
||||||
|
// to be able to handle it. This handles things like copies from ST(0) to
|
||||||
|
// an FP vreg on x86.
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
|
assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
|
||||||
if (II) {
|
if (II) {
|
||||||
const TargetRegisterClass *RC =
|
assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) &&
|
||||||
getInstrOperandRegClass(TRI, TII, *II, IIOpNum);
|
"Don't have operand info for this instruction!");
|
||||||
assert(RC && "Don't have operand info for this instruction!");
|
|
||||||
assert(RegInfo.getRegClass(VReg) == RC &&
|
|
||||||
"Register class of operand and regclass of use don't agree!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,8 +678,7 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
|
|||||||
|
|
||||||
if (VRBase) {
|
if (VRBase) {
|
||||||
// Grab the destination register
|
// Grab the destination register
|
||||||
const TargetRegisterClass *DRC = 0;
|
const TargetRegisterClass *DRC = RegInfo.getRegClass(VRBase);
|
||||||
DRC = RegInfo.getRegClass(VRBase);
|
|
||||||
assert(SRC && DRC && SRC == DRC &&
|
assert(SRC && DRC && SRC == DRC &&
|
||||||
"Source subregister and destination must have the same class");
|
"Source subregister and destination must have the same class");
|
||||||
} else {
|
} else {
|
||||||
|
13
test/CodeGen/X86/inline-asm-fpstack.ll
Normal file
13
test/CodeGen/X86/inline-asm-fpstack.ll
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=x86
|
||||||
|
|
||||||
|
define x86_fp80 @test1() {
|
||||||
|
%tmp85 = call x86_fp80 asm sideeffect "fld0", "={st(0)}"()
|
||||||
|
ret x86_fp80 %tmp85
|
||||||
|
}
|
||||||
|
|
||||||
|
define double @test2() {
|
||||||
|
%tmp85 = call double asm sideeffect "fld0", "={st(0)}"()
|
||||||
|
ret double %tmp85
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user