mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC] Fix RM operands for some instructions
Summary: Some instructions have set the wrong [RM] flag, this patch is to fix it. Instructions x(v|s)r(d|s)pi[zmp]? and fri[npzm] use fixed rounding directions without referencing current rounding mode. Also, the SETRNDi, SETRND, BCLRn, MTFSFI, MTFSB0, MTFSB1, MTFSFb, MTFSFI, MTFSFI_rec, MTFSF, MTFSF_rec should also fix the RM flag. Reviewed By: jsji Differential Revision: https://reviews.llvm.org/D81360
This commit is contained in:
parent
a3714ce03c
commit
4af9b5466a
@ -11931,8 +11931,13 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), MFFSReg);
|
||||
|
||||
// Set rounding mode to round-to-zero.
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1)).addImm(31);
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0)).addImm(30);
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1))
|
||||
.addImm(31)
|
||||
.addReg(PPC::RM, RegState::ImplicitDefine);
|
||||
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0))
|
||||
.addImm(30)
|
||||
.addReg(PPC::RM, RegState::ImplicitDefine);
|
||||
|
||||
// Perform addition.
|
||||
BuildMI(*BB, MI, dl, TII->get(PPC::FADD), Dest).addReg(Src1).addReg(Src2);
|
||||
@ -11994,10 +11999,12 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||
// the immediate to set the bits 62:63 of FPSCR.
|
||||
unsigned Mode = MI.getOperand(1).getImm();
|
||||
BuildMI(*BB, MI, dl, TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
|
||||
.addImm(31);
|
||||
.addImm(31)
|
||||
.addReg(PPC::RM, RegState::ImplicitDefine);
|
||||
|
||||
BuildMI(*BB, MI, dl, TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
|
||||
.addImm(30);
|
||||
.addImm(30)
|
||||
.addReg(PPC::RM, RegState::ImplicitDefine);
|
||||
} else if (MI.getOpcode() == PPC::SETRND) {
|
||||
DebugLoc dl = MI.getDebugLoc();
|
||||
|
||||
|
@ -1563,12 +1563,13 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
|
||||
def BCn : BForm_4<16, 4, 0, 0, (outs), (ins crbitrc:$bi, condbrtarget:$dst),
|
||||
"bc 4, $bi, $dst">;
|
||||
|
||||
let isReturn = 1, Uses = [LR, RM] in
|
||||
let isReturn = 1, Uses = [LR, RM] in {
|
||||
def BCLR : XLForm_2_br2<19, 16, 12, 0, (outs), (ins crbitrc:$bi),
|
||||
"bclr 12, $bi, 0", IIC_BrB, []>;
|
||||
def BCLRn : XLForm_2_br2<19, 16, 4, 0, (outs), (ins crbitrc:$bi),
|
||||
"bclr 4, $bi, 0", IIC_BrB, []>;
|
||||
}
|
||||
}
|
||||
|
||||
let isReturn = 1, Defs = [CTR], Uses = [CTR, LR, RM] in {
|
||||
def BDZLR : XLForm_2_ext<19, 16, 18, 0, 0, (outs), (ins),
|
||||
@ -2584,22 +2585,7 @@ def FTDIV: XForm_17<63, 128, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
|
||||
def FTSQRT: XForm_17a<63, 160, (outs crrc:$crD), (ins f8rc:$fB),
|
||||
"ftsqrt $crD, $fB", IIC_FPCompare>;
|
||||
|
||||
let Uses = [RM], mayRaiseFPException = 1 in {
|
||||
let hasSideEffects = 0 in {
|
||||
defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiw", "$frD, $frB", IIC_FPGeneral,
|
||||
[]>;
|
||||
defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiwu", "$frD, $frB", IIC_FPGeneral,
|
||||
[]>;
|
||||
defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiwz", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f64:$frD, (PPCfctiwz f64:$frB))]>;
|
||||
|
||||
defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB),
|
||||
"frsp", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f32:$frD, (any_fpround f64:$frB))]>;
|
||||
|
||||
let mayRaiseFPException = 1, hasSideEffects = 0 in {
|
||||
let Interpretation64Bit = 1, isCodeGenOnly = 1 in
|
||||
defm FRIND : XForm_26r<63, 392, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"frin", "$frD, $frB", IIC_FPGeneral,
|
||||
@ -2607,9 +2593,7 @@ let Uses = [RM], mayRaiseFPException = 1 in {
|
||||
defm FRINS : XForm_26r<63, 392, (outs f4rc:$frD), (ins f4rc:$frB),
|
||||
"frin", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f32:$frD, (any_fround f32:$frB))]>;
|
||||
}
|
||||
|
||||
let hasSideEffects = 0 in {
|
||||
let Interpretation64Bit = 1, isCodeGenOnly = 1 in
|
||||
defm FRIPD : XForm_26r<63, 456, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"frip", "$frD, $frB", IIC_FPGeneral,
|
||||
@ -2631,6 +2615,22 @@ let Uses = [RM], mayRaiseFPException = 1 in {
|
||||
defm FRIMS : XForm_26r<63, 488, (outs f4rc:$frD), (ins f4rc:$frB),
|
||||
"frim", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f32:$frD, (any_ffloor f32:$frB))]>;
|
||||
}
|
||||
|
||||
let Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in {
|
||||
defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiw", "$frD, $frB", IIC_FPGeneral,
|
||||
[]>;
|
||||
defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiwu", "$frD, $frB", IIC_FPGeneral,
|
||||
[]>;
|
||||
defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fctiwz", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f64:$frD, (PPCfctiwz f64:$frB))]>;
|
||||
|
||||
defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB),
|
||||
"frsp", "$frD, $frB", IIC_FPGeneral,
|
||||
[(set f32:$frD, (any_fpround f64:$frB))]>;
|
||||
|
||||
defm FSQRT : XForm_26r<63, 22, (outs f8rc:$frD), (ins f8rc:$frB),
|
||||
"fsqrt", "$frD, $frB", IIC_FPSqrtD,
|
||||
@ -2640,7 +2640,6 @@ let Uses = [RM], mayRaiseFPException = 1 in {
|
||||
[(set f32:$frD, (any_fsqrt f32:$frB))]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Note that FMR is defined as pseudo-ops on the PPC970 because they are
|
||||
/// often coalesced away and we don't want the dispatch group builder to think
|
||||
@ -2916,13 +2915,17 @@ let Uses = [RM] in {
|
||||
|
||||
// The above pseudo gets expanded to make use of the following instructions
|
||||
// to manipulate FPSCR. Note that FPSCR is not modeled at the DAG level.
|
||||
let Uses = [RM], Defs = [RM] in {
|
||||
|
||||
// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def
|
||||
// RM should be set.
|
||||
def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
|
||||
"mtfsb0 $FM", IIC_IntMTFSB0, []>,
|
||||
PPC970_DGroup_Single, PPC970_Unit_FPU;
|
||||
def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
|
||||
"mtfsb1 $FM", IIC_IntMTFSB0, []>,
|
||||
PPC970_DGroup_Single, PPC970_Unit_FPU;
|
||||
|
||||
let Defs = [RM] in {
|
||||
let isCodeGenOnly = 1 in
|
||||
def MTFSFb : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$rT),
|
||||
"mtfsf $FM, $rT", IIC_IntMTFSB0, []>,
|
||||
@ -4318,6 +4321,8 @@ def MTMSRD : XForm_mtmsr<31, 178, (outs), (ins gprc:$RS, i32imm:$L),
|
||||
def MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA),
|
||||
"mcrfs $BF, $BFA", IIC_BrMCR>;
|
||||
|
||||
// If W is 0 and BF is 7, the 60:63 bits will be set, we should set the
|
||||
// implicit-def RM.
|
||||
def MTFSFI : XLForm_4<63, 134, (outs crrc:$BF), (ins i32imm:$U, i32imm:$W),
|
||||
"mtfsfi $BF, $U, $W", IIC_IntMFFS>;
|
||||
let Defs = [CR1] in
|
||||
@ -4328,6 +4333,7 @@ def : InstAlias<"mtfsfi $BF, $U", (MTFSFI crrc:$BF, i32imm:$U, 0)>;
|
||||
def : InstAlias<"mtfsfi. $BF, $U", (MTFSFI_rec crrc:$BF, i32imm:$U, 0)>;
|
||||
|
||||
let Predicates = [HasFPU] in {
|
||||
let Defs = [RM] in {
|
||||
def MTFSF : XFLForm_1<63, 711, (outs),
|
||||
(ins i32imm:$FLM, f8rc:$FRB, i32imm:$L, i32imm:$W),
|
||||
"mtfsf $FLM, $FRB, $L, $W", IIC_IntMFFS, []>;
|
||||
@ -4335,6 +4341,7 @@ let Defs = [CR1] in
|
||||
def MTFSF_rec : XFLForm_1<63, 711, (outs),
|
||||
(ins i32imm:$FLM, f8rc:$FRB, i32imm:$L, i32imm:$W),
|
||||
"mtfsf. $FLM, $FRB, $L, $W", IIC_IntMFFS, []>, isRecordForm;
|
||||
}
|
||||
|
||||
def : InstAlias<"mtfsf $FLM, $FRB", (MTFSF i32imm:$FLM, f8rc:$FRB, 0, 0)>;
|
||||
def : InstAlias<"mtfsf. $FLM, $FRB", (MTFSF_rec i32imm:$FLM, f8rc:$FRB, 0, 0)>;
|
||||
|
@ -362,7 +362,8 @@ let hasSideEffects = 0 in {
|
||||
}
|
||||
} // mayStore
|
||||
|
||||
let Uses = [RM], mayRaiseFPException = 1 in {
|
||||
let mayRaiseFPException = 1 in {
|
||||
let Uses = [RM] in {
|
||||
// Add/Mul Instructions
|
||||
let isCommutable = 1 in {
|
||||
def XSADDDP : XX3Form<60, 32,
|
||||
@ -885,70 +886,19 @@ let hasSideEffects = 0 in {
|
||||
"xvcvuxwsp $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>;
|
||||
|
||||
// Rounding Instructions
|
||||
def XSRDPI : XX2Form<60, 73,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpi $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_fround f64:$XB))]>;
|
||||
// Rounding Instructions respecting current rounding mode
|
||||
def XSRDPIC : XX2Form<60, 107,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpic $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_fnearbyint f64:$XB))]>;
|
||||
def XSRDPIM : XX2Form<60, 121,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpim $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_ffloor f64:$XB))]>;
|
||||
def XSRDPIP : XX2Form<60, 105,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpip $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_fceil f64:$XB))]>;
|
||||
def XSRDPIZ : XX2Form<60, 89,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpiz $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_ftrunc f64:$XB))]>;
|
||||
|
||||
def XVRDPI : XX2Form<60, 201,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpi $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_fround v2f64:$XB))]>;
|
||||
def XVRDPIC : XX2Form<60, 235,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpic $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_fnearbyint v2f64:$XB))]>;
|
||||
def XVRDPIM : XX2Form<60, 249,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpim $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
|
||||
def XVRDPIP : XX2Form<60, 233,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpip $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
|
||||
def XVRDPIZ : XX2Form<60, 217,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpiz $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
|
||||
|
||||
def XVRSPI : XX2Form<60, 137,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspi $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_fround v4f32:$XB))]>;
|
||||
def XVRSPIC : XX2Form<60, 171,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspic $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_fnearbyint v4f32:$XB))]>;
|
||||
def XVRSPIM : XX2Form<60, 185,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspim $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
|
||||
def XVRSPIP : XX2Form<60, 169,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspip $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
|
||||
def XVRSPIZ : XX2Form<60, 153,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspiz $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
|
||||
|
||||
// Max/Min Instructions
|
||||
let isCommutable = 1 in {
|
||||
def XSMAXDP : XX3Form<60, 160,
|
||||
@ -984,7 +934,60 @@ let hasSideEffects = 0 in {
|
||||
[(set vsrc:$XT,
|
||||
(int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
|
||||
} // isCommutable
|
||||
} // Uses = [RM], mayRaiseFPException
|
||||
} // Uses = [RM]
|
||||
|
||||
// Rounding Instructions with static direction.
|
||||
def XSRDPI : XX2Form<60, 73,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpi $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_fround f64:$XB))]>;
|
||||
def XSRDPIM : XX2Form<60, 121,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpim $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_ffloor f64:$XB))]>;
|
||||
def XSRDPIP : XX2Form<60, 105,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpip $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_fceil f64:$XB))]>;
|
||||
def XSRDPIZ : XX2Form<60, 89,
|
||||
(outs vsfrc:$XT), (ins vsfrc:$XB),
|
||||
"xsrdpiz $XT, $XB", IIC_VecFP,
|
||||
[(set f64:$XT, (any_ftrunc f64:$XB))]>;
|
||||
|
||||
def XVRDPI : XX2Form<60, 201,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpi $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_fround v2f64:$XB))]>;
|
||||
def XVRDPIM : XX2Form<60, 249,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpim $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
|
||||
def XVRDPIP : XX2Form<60, 233,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpip $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
|
||||
def XVRDPIZ : XX2Form<60, 217,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrdpiz $XT, $XB", IIC_VecFP,
|
||||
[(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
|
||||
|
||||
def XVRSPI : XX2Form<60, 137,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspi $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_fround v4f32:$XB))]>;
|
||||
def XVRSPIM : XX2Form<60, 185,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspim $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
|
||||
def XVRSPIP : XX2Form<60, 169,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspip $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
|
||||
def XVRSPIZ : XX2Form<60, 153,
|
||||
(outs vsrc:$XT), (ins vsrc:$XB),
|
||||
"xvrspiz $XT, $XB", IIC_VecFP,
|
||||
[(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
|
||||
} // mayRaiseFPException
|
||||
|
||||
// Logical Instructions
|
||||
let isCommutable = 1 in
|
||||
|
26
test/CodeGen/PowerPC/rounding-rm-flag.ll
Normal file
26
test/CodeGen/PowerPC/rounding-rm-flag.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
|
||||
; RUN: -mcpu=pwr9 -stop-after=early-ifcvt < %s | FileCheck %s
|
||||
|
||||
define float @test_XSRDPI(float %f) {
|
||||
entry:
|
||||
%0 = tail call float @llvm.round.f32(float %f)
|
||||
ret float %0
|
||||
|
||||
; CHECK-LABEL: name: test_XSRDPI
|
||||
; CHECK-NOT: %2:vsfrc = nofpexcept XSRDPI killed %1, implicit $rm
|
||||
; CHECK: %2:vsfrc = nofpexcept XSRDPI killed %1
|
||||
}
|
||||
|
||||
define double @test_XSRDPIM(double %d) {
|
||||
entry:
|
||||
%0 = tail call double @llvm.floor.f64(double %d)
|
||||
ret double %0
|
||||
|
||||
; CHECK-LABEL: name: test_XSRDPIM
|
||||
; CHECK-NOT: %1:vsfrc = nofpexcept XSRDPIM %0, implicit $rm
|
||||
; CHECK: %1:vsfrc = nofpexcept XSRDPIM %0
|
||||
}
|
||||
|
||||
declare float @llvm.round.f32(float)
|
||||
declare double @llvm.floor.f64(double)
|
||||
|
@ -19,8 +19,8 @@ entry:
|
||||
|
||||
; AFTER-FINALIZE-ISEL: test_setrndi
|
||||
; AFTER-FINALIZE-ISEL: MFFS implicit $rm
|
||||
; AFTER-FINALIZE-ISEL: MTFSB0 31, implicit-def $rm, implicit $rm
|
||||
; AFTER-FINALIZE-ISEL: MTFSB1 30, implicit-def $rm, implicit $rm
|
||||
; AFTER-FINALIZE-ISEL: MTFSB0 31, implicit-def $rm
|
||||
; AFTER-FINALIZE-ISEL: MTFSB1 30, implicit-def $rm
|
||||
|
||||
; CHECK-LABEL: @test_setrndi
|
||||
; CHECK: # %bb.0:
|
||||
@ -40,7 +40,7 @@ entry:
|
||||
|
||||
; AFTER-FINALIZE-ISEL: test_setrnd
|
||||
; AFTER-FINALIZE-ISEL: MFFS implicit $rm
|
||||
; AFTER-FINALIZE-ISEL: MTFSF 255, %7, 0, 0
|
||||
; AFTER-FINALIZE-ISEL: MTFSF 255, %7, 0, 0, implicit-def $rm
|
||||
|
||||
; CHECK-LABEL: @test_setrnd
|
||||
; CHECK: # %bb.0:
|
||||
|
Loading…
x
Reference in New Issue
Block a user