mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-06 19:31:13 +00:00
Long double patch 8 of N: make it partially work in
SSE mode (all but conversions <-> other FP types, I think): >>Do not mark all-80-bit operations as "Requires[FPStack]" (which really means "not SSE"). >>Refactor load-and-extend to facilitate this. >>Update comments. >>Handle long double in SSE when computing FP_REG_KILL. llvm-svn: 40906
This commit is contained in:
parent
935996673b
commit
6b8e91e7e3
@ -424,7 +424,10 @@ static const TableEntry OpcodeTable[] = {
|
||||
{ X86::LD_Fp164 , X86::LD_F1 },
|
||||
{ X86::LD_Fp180 , X86::LD_F1 },
|
||||
{ X86::LD_Fp32m , X86::LD_F32m },
|
||||
{ X86::LD_Fp32m64 , X86::LD_F32m },
|
||||
{ X86::LD_Fp32m80 , X86::LD_F32m },
|
||||
{ X86::LD_Fp64m , X86::LD_F64m },
|
||||
{ X86::LD_Fp64m80 , X86::LD_F64m },
|
||||
{ X86::LD_Fp80m , X86::LD_F80m },
|
||||
{ X86::MUL_Fp32m , X86::MUL_F32m },
|
||||
{ X86::MUL_Fp64m , X86::MUL_F64m },
|
||||
|
@ -479,61 +479,61 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
// If we are emitting FP stack code, scan the basic block to determine if this
|
||||
// block defines any FP values. If so, put an FP_REG_KILL instruction before
|
||||
// the terminator of the block.
|
||||
if (!Subtarget->hasSSE2()) {
|
||||
// Note that FP stack instructions *are* used in SSE code when returning
|
||||
// values, but these are not live out of the basic block, so we don't need
|
||||
// an FP_REG_KILL in this case either.
|
||||
bool ContainsFPCode = false;
|
||||
|
||||
// Scan all of the machine instructions in these MBBs, checking for FP
|
||||
// stores.
|
||||
MachineFunction::iterator MBBI = FirstMBB;
|
||||
do {
|
||||
for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
|
||||
!ContainsFPCode && I != E; ++I) {
|
||||
if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
|
||||
const TargetRegisterClass *clas;
|
||||
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
|
||||
if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
|
||||
MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
|
||||
((clas = RegMap->getRegClass(I->getOperand(0).getReg())) ==
|
||||
X86::RFP32RegisterClass ||
|
||||
clas == X86::RFP64RegisterClass ||
|
||||
clas == X86::RFP80RegisterClass)) {
|
||||
ContainsFPCode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!ContainsFPCode && &*(MBBI++) != BB);
|
||||
|
||||
// Check PHI nodes in successor blocks. These PHI's will be lowered to have
|
||||
// a copy of the input value in this block.
|
||||
if (!ContainsFPCode) {
|
||||
// Final check, check LLVM BB's that are successors to the LLVM BB
|
||||
// corresponding to BB for FP PHI nodes.
|
||||
const BasicBlock *LLVMBB = BB->getBasicBlock();
|
||||
const PHINode *PN;
|
||||
for (succ_const_iterator SI = succ_begin(LLVMBB), E = succ_end(LLVMBB);
|
||||
!ContainsFPCode && SI != E; ++SI) {
|
||||
for (BasicBlock::const_iterator II = SI->begin();
|
||||
(PN = dyn_cast<PHINode>(II)); ++II) {
|
||||
if (PN->getType()->isFloatingPoint()) {
|
||||
|
||||
// Note that FP stack instructions *are* used in SSE code for long double,
|
||||
// so we do need this check.
|
||||
bool ContainsFPCode = false;
|
||||
|
||||
// Scan all of the machine instructions in these MBBs, checking for FP
|
||||
// stores. (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.)
|
||||
MachineFunction::iterator MBBI = FirstMBB;
|
||||
do {
|
||||
for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
|
||||
!ContainsFPCode && I != E; ++I) {
|
||||
if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
|
||||
const TargetRegisterClass *clas;
|
||||
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
|
||||
if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
|
||||
MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
|
||||
((clas = RegMap->getRegClass(I->getOperand(0).getReg())) ==
|
||||
X86::RFP32RegisterClass ||
|
||||
clas == X86::RFP64RegisterClass ||
|
||||
clas == X86::RFP80RegisterClass)) {
|
||||
ContainsFPCode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!ContainsFPCode && &*(MBBI++) != BB);
|
||||
|
||||
// Finally, if we found any FP code, emit the FP_REG_KILL instruction.
|
||||
if (ContainsFPCode) {
|
||||
BuildMI(*BB, BB->getFirstTerminator(),
|
||||
TM.getInstrInfo()->get(X86::FP_REG_KILL));
|
||||
++NumFPKill;
|
||||
// Check PHI nodes in successor blocks. These PHI's will be lowered to have
|
||||
// a copy of the input value in this block. In SSE mode, we only care about
|
||||
// 80-bit values.
|
||||
if (!ContainsFPCode) {
|
||||
// Final check, check LLVM BB's that are successors to the LLVM BB
|
||||
// corresponding to BB for FP PHI nodes.
|
||||
const BasicBlock *LLVMBB = BB->getBasicBlock();
|
||||
const PHINode *PN;
|
||||
for (succ_const_iterator SI = succ_begin(LLVMBB), E = succ_end(LLVMBB);
|
||||
!ContainsFPCode && SI != E; ++SI) {
|
||||
for (BasicBlock::const_iterator II = SI->begin();
|
||||
(PN = dyn_cast<PHINode>(II)); ++II) {
|
||||
if (PN->getType()==Type::X86_FP80Ty ||
|
||||
(!Subtarget->hasSSE2() && PN->getType()->isFloatingPoint())) {
|
||||
ContainsFPCode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, if we found any FP code, emit the FP_REG_KILL instruction.
|
||||
if (ContainsFPCode) {
|
||||
BuildMI(*BB, BB->getFirstTerminator(),
|
||||
TM.getInstrInfo()->get(X86::FP_REG_KILL));
|
||||
++NumFPKill;
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the Evan Cheng and is distributed under
|
||||
// This file was developed by Evan Cheng and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -48,10 +48,6 @@ def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
|
||||
def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
def extloadf80f32 : PatFrag<(ops node:$ptr), (f80 (extloadf32 node:$ptr))>;
|
||||
def extloadf80f64 : PatFrag<(ops node:$ptr), (f80 (extloadf64 node:$ptr))>;
|
||||
def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extloadf32 node:$ptr))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FPStack pattern fragments
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -116,18 +112,18 @@ let isTerminator = 1 in
|
||||
let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
|
||||
def FP_REG_KILL : I<0, Pseudo, (outs), (ins), "#FP_REG_KILL", []>;
|
||||
|
||||
// All FP Stack operations are represented with three instructions here. The
|
||||
// first two instructions, generated by the instruction selector, uses "RFP32"
|
||||
// or "RFP64" registers: traditional register files to reference 32-bit or
|
||||
// 64-bit floating point values. These sizes apply to the values, not the
|
||||
// registers, which are always 64 bits; RFP32 and RFP64 can be copied to
|
||||
// each other without losing information. These instructions are all psuedo
|
||||
// instructions and use the "_Fp" suffix.
|
||||
// In some cases there are additional variants with a mixture of 32-bit and
|
||||
// 64-bit registers.
|
||||
// All FP Stack operations are represented with four instructions here. The
|
||||
// first three instructions, generated by the instruction selector, use "RFP32"
|
||||
// "RFP64" or "RFP80" registers: traditional register files to reference 32-bit,
|
||||
// 64-bit or 80-bit floating point values. These sizes apply to the values,
|
||||
// not the registers, which are always 80 bits; RFP32, RFP64 and RFP80 can be
|
||||
// copied to each other without losing information. These instructions are all
|
||||
// pseudo instructions and use the "_Fp" suffix.
|
||||
// In some cases there are additional variants with a mixture of different
|
||||
// register sizes.
|
||||
// The second instruction is defined with FPI, which is the actual instruction
|
||||
// emitted by the assembler. These use "RST" registers, although frequently
|
||||
// the actual register(s) used are implicit. These are always 64-bits.
|
||||
// the actual register(s) used are implicit. These are always 80 bits.
|
||||
// The FP stackifier pass converts one to the other after register allocation
|
||||
// occurs.
|
||||
//
|
||||
@ -135,7 +131,7 @@ let isTerminator = 1 in
|
||||
// a pattern) and the FPI instruction should have emission info (e.g. opcode
|
||||
// encoding and asm printing info).
|
||||
|
||||
// Random Pseudo Instructions.
|
||||
// Pseudo Instructions for FP stack return values.
|
||||
def FpGETRESULT32 : FpI_<(outs RFP32:$dst), (ins), SpecialFP,
|
||||
[(set RFP32:$dst, X86fpget)]>; // FPR = ST(0)
|
||||
|
||||
@ -155,6 +151,8 @@ def FpSETRESULT80 : FpI_<(outs), (ins RFP80:$src), SpecialFP,
|
||||
[(X86fpset RFP80:$src)]>, Imp<[], [ST0]>;// ST(0) = FPR
|
||||
|
||||
// FpI - Floating Point Psuedo Instruction template. Predicated on FPStack.
|
||||
// Note that f80-only instructions are used even in SSE mode and use FpI_
|
||||
// not this predicate.
|
||||
class FpI<dag outs, dag ins, FPFormat fp, list<dag> pattern> :
|
||||
FpI_<outs, ins, fp, pattern>, Requires<[FPStack]>;
|
||||
|
||||
@ -167,7 +165,7 @@ def MOV_Fp8032 : FpI<(outs RFP32:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
def MOV_Fp3280 : FpI<(outs RFP80:$dst), (ins RFP32:$src), SpecialFP, []>;
|
||||
def MOV_Fp8064 : FpI<(outs RFP64:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
def MOV_Fp6480 : FpI<(outs RFP80:$dst), (ins RFP64:$src), SpecialFP, []>;
|
||||
def MOV_Fp8080 : FpI<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
def MOV_Fp8080 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
|
||||
// Factoring for arithmetic.
|
||||
multiclass FPBinary_rr<SDNode OpNode> {
|
||||
@ -177,7 +175,7 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), TwoArgFP,
|
||||
[(set RFP32:$dst, (OpNode RFP32:$src1, RFP32:$src2))]>;
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), TwoArgFP,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src1, RFP64:$src2))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP,
|
||||
def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1, RFP80:$src2))]>;
|
||||
}
|
||||
// The FopST0 series are not included here because of the irregularities
|
||||
@ -193,13 +191,13 @@ def _Fp64m : FpI<(outs RFP64:$dst), (ins RFP64:$src1, f64mem:$src2), OneArgFPRW
|
||||
(OpNode RFP64:$src1, (loadf64 addr:$src2)))]>;
|
||||
def _Fp64m32: FpI<(outs RFP64:$dst), (ins RFP64:$src1, f32mem:$src2), OneArgFPRW,
|
||||
[(set RFP64:$dst,
|
||||
(OpNode RFP64:$src1, (extloadf64f32 addr:$src2)))]>;
|
||||
def _Fp80m32: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), OneArgFPRW,
|
||||
(OpNode RFP64:$src1, (f64 (extloadf32 addr:$src2))))]>;
|
||||
def _Fp80m32: FpI_<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst,
|
||||
(OpNode RFP80:$src1, (extloadf80f32 addr:$src2)))]>;
|
||||
def _Fp80m64: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f64mem:$src2), OneArgFPRW,
|
||||
(OpNode RFP80:$src1, (f80 (extloadf32 addr:$src2))))]>;
|
||||
def _Fp80m64: FpI_<(outs RFP80:$dst), (ins RFP80:$src1, f64mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst,
|
||||
(OpNode RFP80:$src1, (extloadf80f64 addr:$src2)))]>;
|
||||
(OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>;
|
||||
def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src),
|
||||
!strconcat("f", !strconcat(asmstring, "{s}\t$src"))>;
|
||||
def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src),
|
||||
@ -217,10 +215,10 @@ def _FpI16m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i16mem:$src2), OneArgFP
|
||||
def _FpI32m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i32mem:$src2), OneArgFPRW,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src1,
|
||||
(X86fild addr:$src2, i32)))]>;
|
||||
def _FpI16m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), OneArgFPRW,
|
||||
def _FpI16m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1,
|
||||
(X86fild addr:$src2, i16)))]>;
|
||||
def _FpI32m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), OneArgFPRW,
|
||||
def _FpI32m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1,
|
||||
(X86fild addr:$src2, i32)))]>;
|
||||
def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src),
|
||||
@ -275,7 +273,7 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src), OneArgFPRW,
|
||||
[(set RFP32:$dst, (OpNode RFP32:$src))]>;
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src), OneArgFPRW,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW,
|
||||
def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src))]>;
|
||||
def _F : FPI<opcode, RawFrm, (outs), (ins), asmstring>, D9;
|
||||
}
|
||||
@ -290,7 +288,7 @@ def TST_Fp32 : FpI<(outs), (ins RFP32:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_Fp64 : FpI<(outs), (ins RFP64:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_Fp80 : FpI<(outs), (ins RFP80:$src), OneArgFP,
|
||||
def TST_Fp80 : FpI_<(outs), (ins RFP80:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_F : FPI<0xE4, RawFrm, (outs), (ins), "ftst">, D9;
|
||||
|
||||
@ -302,7 +300,7 @@ multiclass FPCMov<PatLeaf cc> {
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), CondMovFP,
|
||||
[(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2,
|
||||
cc))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), CondMovFP,
|
||||
def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), CondMovFP,
|
||||
[(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2,
|
||||
cc))]>;
|
||||
}
|
||||
@ -340,8 +338,14 @@ def LD_Fp32m : FpI<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP,
|
||||
[(set RFP32:$dst, (loadf32 addr:$src))]>;
|
||||
def LD_Fp64m : FpI<(outs RFP64:$dst), (ins f64mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (loadf64 addr:$src))]>;
|
||||
def LD_Fp80m : FpI<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP,
|
||||
def LD_Fp80m : FpI_<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (loadf80 addr:$src))]>;
|
||||
def LD_Fp32m64 : FpI<(outs RFP64:$dst), (ins f32mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (f64 (extloadf32 addr:$src)))]>;
|
||||
def LD_Fp64m80 : FpI_<(outs RFP80:$dst), (ins f64mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (f80 (extloadf64 addr:$src)))]>;
|
||||
def LD_Fp32m80 : FpI_<(outs RFP80:$dst), (ins f32mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (f80 (extloadf32 addr:$src)))]>;
|
||||
def ILD_Fp16m32: FpI<(outs RFP32:$dst), (ins i16mem:$src), ZeroArgFP,
|
||||
[(set RFP32:$dst, (X86fild addr:$src, i16))]>;
|
||||
def ILD_Fp32m32: FpI<(outs RFP32:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
@ -354,11 +358,11 @@ def ILD_Fp32m64: FpI<(outs RFP64:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (X86fild addr:$src, i32))]>;
|
||||
def ILD_Fp64m64: FpI<(outs RFP64:$dst), (ins i64mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (X86fild addr:$src, i64))]>;
|
||||
def ILD_Fp16m80: FpI<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP,
|
||||
def ILD_Fp16m80: FpI_<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i16))]>;
|
||||
def ILD_Fp32m80: FpI<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
def ILD_Fp32m80: FpI_<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i32))]>;
|
||||
def ILD_Fp64m80: FpI<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP,
|
||||
def ILD_Fp64m80: FpI_<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i64))]>;
|
||||
|
||||
def ST_Fp32m : FpI<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP,
|
||||
@ -367,9 +371,9 @@ def ST_Fp64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP,
|
||||
[(truncstoref32 RFP64:$src, addr:$op)]>;
|
||||
def ST_Fp64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP,
|
||||
[(store RFP64:$src, addr:$op)]>;
|
||||
def ST_Fp80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP,
|
||||
def ST_Fp80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP,
|
||||
[(truncstoref32 RFP80:$src, addr:$op)]>;
|
||||
def ST_Fp80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP,
|
||||
def ST_Fp80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP,
|
||||
[(truncstoref64 RFP80:$src, addr:$op)]>;
|
||||
// FST does not support 80-bit memory target; FSTP must be used.
|
||||
|
||||
@ -378,7 +382,7 @@ def ST_FpP64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def ST_FpP64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def ST_FpP80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def ST_FpP80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def ST_FpP80m : FpI<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP,
|
||||
def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP,
|
||||
[(store RFP80:$src, addr:$op)]>;
|
||||
def IST_Fp16m32 : FpI<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def IST_Fp32m32 : FpI<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
@ -386,9 +390,9 @@ def IST_Fp64m32 : FpI<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def IST_Fp16m64 : FpI<(outs), (ins i16mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp32m64 : FpI<(outs), (ins i32mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp64m64 : FpI<(outs), (ins i64mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp16m80 : FpI<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp32m80 : FpI<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp64m80 : FpI<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
|
||||
def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">;
|
||||
def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">;
|
||||
@ -456,9 +460,9 @@ def LD_Fp064 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP64:$dst, fpimm0)]>;
|
||||
def LD_Fp164 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP64:$dst, fpimm1)]>;
|
||||
def LD_Fp080 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
def LD_Fp080 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP80:$dst, fpimm0)]>;
|
||||
def LD_Fp180 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
def LD_Fp180 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP80:$dst, fpimm1)]>;
|
||||
}
|
||||
|
||||
@ -475,9 +479,9 @@ def UCOM_Fpr64 : FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP,
|
||||
[]>; // FPSW = cmp ST(0) with ST(i)
|
||||
def UCOM_FpIr64: FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP,
|
||||
[(X86cmp RFP64:$lhs, RFP64:$rhs)]>; // CC = ST(0) cmp ST(i)
|
||||
def UCOM_Fpr80 : FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
def UCOM_Fpr80 : FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
[]>; // FPSW = cmp ST(0) with ST(i)
|
||||
def UCOM_FpIr80: FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
[(X86cmp RFP80:$lhs, RFP80:$rhs)]>; // CC = ST(0) cmp ST(i)
|
||||
|
||||
def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i)
|
||||
@ -510,12 +514,12 @@ def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
||||
// Non-Instruction Patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Required for RET of f32 / f64 values.
|
||||
// Required for RET of f32 / f64 / f80 values.
|
||||
def : Pat<(X86fld addr:$src, f32), (LD_Fp32m addr:$src)>;
|
||||
def : Pat<(X86fld addr:$src, f64), (LD_Fp64m addr:$src)>;
|
||||
def : Pat<(X86fld addr:$src, f80), (LD_Fp80m addr:$src)>;
|
||||
|
||||
// Required for CALL which return f32 / f64 values.
|
||||
// Required for CALL which return f32 / f64 / f80 values.
|
||||
def : Pat<(X86fst RFP32:$src, addr:$op, f32), (ST_Fp32m addr:$op, RFP32:$src)>;
|
||||
def : Pat<(X86fst RFP64:$src, addr:$op, f32), (ST_Fp64m32 addr:$op, RFP64:$src)>;
|
||||
def : Pat<(X86fst RFP64:$src, addr:$op, f64), (ST_Fp64m addr:$op, RFP64:$src)>;
|
||||
@ -528,19 +532,12 @@ def : Pat<(f32 fpimmneg0), (CHS_Fp32 (LD_Fp032))>, Requires<[FPStack]>;
|
||||
def : Pat<(f32 fpimmneg1), (CHS_Fp32 (LD_Fp132))>, Requires<[FPStack]>;
|
||||
def : Pat<(f64 fpimmneg0), (CHS_Fp64 (LD_Fp064))>, Requires<[FPStack]>;
|
||||
def : Pat<(f64 fpimmneg1), (CHS_Fp64 (LD_Fp164))>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>;
|
||||
def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>;
|
||||
|
||||
// Used to conv. i64 to f64 since there isn't a SSE version.
|
||||
def : Pat<(X86fildflag addr:$src, i64), (ILD_Fp64m64 addr:$src)>;
|
||||
|
||||
def : Pat<(extloadf80f32 addr:$src),
|
||||
(MOV_Fp3280 (LD_Fp32m addr:$src))>, Requires<[FPStack]>;
|
||||
def : Pat<(extloadf80f64 addr:$src),
|
||||
(MOV_Fp6480 (LD_Fp64m addr:$src))>, Requires<[FPStack]>;
|
||||
def : Pat<(extloadf64f32 addr:$src),
|
||||
(MOV_Fp3264 (LD_Fp32m addr:$src))>, Requires<[FPStack]>;
|
||||
|
||||
def : Pat<(f64 (fextend RFP32:$src)), (MOV_Fp3264 RFP32:$src)>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 (fextend RFP32:$src)), (MOV_Fp3280 RFP32:$src)>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 (fextend RFP64:$src)), (MOV_Fp6480 RFP64:$src)>, Requires<[FPStack]>;
|
||||
|
Loading…
Reference in New Issue
Block a user