Add a RM pseudoreg for the rounding mode, which

allows ppcf128->int conversion to work with
DeadInstructionElimination.  This is now turned
off but RM is harmless.  It does not do a complete
job of modeling the rounding mode.

Revert marking MFCR as using all 7 CR subregisters;
while correct, this caused the problem in PR 2964,
plus the local RA crash noted in the comments.
This was needed to make DeadInstructionElimination,
but as we are not running that, it is backed out
for now.  Eventually it should go back in and the
other problems fixed where they're broken.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58391 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2008-10-29 18:26:45 +00:00
parent 492f04c203
commit b384ab9ea1
4 changed files with 200 additions and 165 deletions

View File

@ -70,13 +70,15 @@ let isCall = 1, PPC970_Unit = 7,
LR8,CTR8, LR8,CTR8,
CR0,CR1,CR5,CR6,CR7] in { CR0,CR1,CR5,CR6,CR7] in {
// Convenient aliases for call instructions // Convenient aliases for call instructions
def BL8_Macho : IForm<18, 0, 1, let Uses = [RM] in {
(outs), (ins calltarget:$func, variable_ops), def BL8_Macho : IForm<18, 0, 1,
"bl $func", BrB, []>; // See Pat patterns below. (outs), (ins calltarget:$func, variable_ops),
def BLA8_Macho : IForm<18, 1, 1, "bl $func", BrB, []>; // See Pat patterns below.
(outs), (ins aaddr:$func, variable_ops), def BLA8_Macho : IForm<18, 1, 1,
"bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>; (outs), (ins aaddr:$func, variable_ops),
let Uses = [CTR8] in { "bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>;
}
let Uses = [CTR8, RM] in {
def BCTRL8_Macho : XLForm_2_ext<19, 528, 20, 0, 1, def BCTRL8_Macho : XLForm_2_ext<19, 528, 20, 0, 1,
(outs), (ins variable_ops), (outs), (ins variable_ops),
"bctrl", BrB, "bctrl", BrB,
@ -94,13 +96,15 @@ let isCall = 1, PPC970_Unit = 7,
LR8,CTR8, LR8,CTR8,
CR0,CR1,CR5,CR6,CR7] in { CR0,CR1,CR5,CR6,CR7] in {
// Convenient aliases for call instructions // Convenient aliases for call instructions
def BL8_ELF : IForm<18, 0, 1, let Uses = [RM] in {
(outs), (ins calltarget:$func, variable_ops), def BL8_ELF : IForm<18, 0, 1,
"bl $func", BrB, []>; // See Pat patterns below. (outs), (ins calltarget:$func, variable_ops),
def BLA8_ELF : IForm<18, 1, 1, "bl $func", BrB, []>; // See Pat patterns below.
(outs), (ins aaddr:$func, variable_ops), def BLA8_ELF : IForm<18, 1, 1,
"bla $func", BrB, [(PPCcall_ELF (i64 imm:$func))]>; (outs), (ins aaddr:$func, variable_ops),
let Uses = [CTR8] in { "bla $func", BrB, [(PPCcall_ELF (i64 imm:$func))]>;
}
let Uses = [CTR8, RM] in {
def BCTRL8_ELF : XLForm_2_ext<19, 528, 20, 0, 1, def BCTRL8_ELF : XLForm_2_ext<19, 528, 20, 0, 1,
(outs), (ins variable_ops), (outs), (ins variable_ops),
"bctrl", BrB, "bctrl", BrB,
@ -172,39 +176,39 @@ def STDCX : XForm_1<31, 214, (outs), (ins G8RC:$rS, memrr:$dst),
[(PPCstcx G8RC:$rS, xoaddr:$dst)]>, [(PPCstcx G8RC:$rS, xoaddr:$dst)]>,
isDOT; isDOT;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNdi8 :Pseudo< (outs), def TCRETURNdi8 :Pseudo< (outs),
(ins calltarget:$dst, i32imm:$offset, variable_ops), (ins calltarget:$dst, i32imm:$offset, variable_ops),
"#TC_RETURNd8 $dst $offset", "#TC_RETURNd8 $dst $offset",
[]>; []>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNai8 :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset, variable_ops), def TCRETURNai8 :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset, variable_ops),
"#TC_RETURNa8 $func $offset", "#TC_RETURNa8 $func $offset",
[(PPCtc_return (i64 imm:$func), imm:$offset)]>; [(PPCtc_return (i64 imm:$func), imm:$offset)]>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNri8 : Pseudo<(outs), (ins CTRRC8:$dst, i32imm:$offset, variable_ops), def TCRETURNri8 : Pseudo<(outs), (ins CTRRC8:$dst, i32imm:$offset, variable_ops),
"#TC_RETURNr8 $dst $offset", "#TC_RETURNr8 $dst $offset",
[]>; []>;
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1, let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1,
isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR] in isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR, RM] in
def TAILBCTR8 : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>, def TAILBCTR8 : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>,
Requires<[In64BitMode]>; Requires<[In64BitMode]>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
isBarrier = 1, isCall = 1, isReturn = 1 in isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
def TAILB8 : IForm<18, 0, 0, (outs), (ins calltarget:$dst), def TAILB8 : IForm<18, 0, 0, (outs), (ins calltarget:$dst),
"b $dst", BrB, "b $dst", BrB,
[]>; []>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
isBarrier = 1, isCall = 1, isReturn = 1 in isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
def TAILBA8 : IForm<18, 0, 0, (outs), (ins aaddr:$dst), def TAILBA8 : IForm<18, 0, 0, (outs), (ins aaddr:$dst),
"ba $dst", BrB, "ba $dst", BrB,
[]>; []>;
@ -634,7 +638,7 @@ def STDX_32 : XForm_8<31, 149, (outs), (ins GPRC:$rT, memrr:$dst),
// //
let PPC970_Unit = 3 in { // FPU Operations. let PPC970_Unit = 3, Uses = [RM] in { // FPU Operations.
def FCFID : XForm_26<63, 846, (outs F8RC:$frD), (ins F8RC:$frB), def FCFID : XForm_26<63, 846, (outs F8RC:$frD), (ins F8RC:$frB),
"fcfid $frD, $frB", FPGeneral, "fcfid $frD, $frB", FPGeneral,
[(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64; [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64;

View File

@ -385,7 +385,7 @@ def SPILL_CR : Pseudo<(outs), (ins GPRC:$cond, memri:$F),
"${:comment} SPILL_CR $cond $F", []>; "${:comment} SPILL_CR $cond $F", []>;
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in { let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
let isReturn = 1, Uses = [LR] in let isReturn = 1, Uses = [LR, RM] in
def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p), def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p),
"b${p:cc}lr ${p:reg}", BrB, "b${p:cc}lr ${p:reg}", BrB,
[(retflag)]>; [(retflag)]>;
@ -423,13 +423,15 @@ let isCall = 1, PPC970_Unit = 7,
CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ, CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN] in { CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN] in {
// Convenient aliases for call instructions // Convenient aliases for call instructions
def BL_Macho : IForm<18, 0, 1, let Uses = [RM] in {
(outs), (ins calltarget:$func, variable_ops), def BL_Macho : IForm<18, 0, 1,
"bl $func", BrB, []>; // See Pat patterns below. (outs), (ins calltarget:$func, variable_ops),
def BLA_Macho : IForm<18, 1, 1, "bl $func", BrB, []>; // See Pat patterns below.
(outs), (ins aaddr:$func, variable_ops), def BLA_Macho : IForm<18, 1, 1,
"bla $func", BrB, [(PPCcall_Macho (i32 imm:$func))]>; (outs), (ins aaddr:$func, variable_ops),
let Uses = [CTR] in { "bla $func", BrB, [(PPCcall_Macho (i32 imm:$func))]>;
}
let Uses = [CTR, RM] in {
def BCTRL_Macho : XLForm_2_ext<19, 528, 20, 0, 1, def BCTRL_Macho : XLForm_2_ext<19, 528, 20, 0, 1,
(outs), (ins variable_ops), (outs), (ins variable_ops),
"bctrl", BrB, "bctrl", BrB,
@ -448,14 +450,16 @@ let isCall = 1, PPC970_Unit = 7,
CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ, CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN] in { CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN] in {
// Convenient aliases for call instructions // Convenient aliases for call instructions
def BL_ELF : IForm<18, 0, 1, let Uses = [RM] in {
(outs), (ins calltarget:$func, variable_ops), def BL_ELF : IForm<18, 0, 1,
"bl $func", BrB, []>; // See Pat patterns below. (outs), (ins calltarget:$func, variable_ops),
def BLA_ELF : IForm<18, 1, 1, "bl $func", BrB, []>; // See Pat patterns below.
(outs), (ins aaddr:$func, variable_ops), def BLA_ELF : IForm<18, 1, 1,
"bla $func", BrB, (outs), (ins aaddr:$func, variable_ops),
[(PPCcall_ELF (i32 imm:$func))]>; "bla $func", BrB,
let Uses = [CTR] in { [(PPCcall_ELF (i32 imm:$func))]>;
}
let Uses = [CTR, RM] in {
def BCTRL_ELF : XLForm_2_ext<19, 528, 20, 0, 1, def BCTRL_ELF : XLForm_2_ext<19, 528, 20, 0, 1,
(outs), (ins variable_ops), (outs), (ins variable_ops),
"bctrl", BrB, "bctrl", BrB,
@ -464,40 +468,40 @@ let isCall = 1, PPC970_Unit = 7,
} }
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNdi :Pseudo< (outs), def TCRETURNdi :Pseudo< (outs),
(ins calltarget:$dst, i32imm:$offset, variable_ops), (ins calltarget:$dst, i32imm:$offset, variable_ops),
"#TC_RETURNd $dst $offset", "#TC_RETURNd $dst $offset",
[]>; []>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNai :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset, variable_ops), def TCRETURNai :Pseudo<(outs), (ins aaddr:$func, i32imm:$offset, variable_ops),
"#TC_RETURNa $func $offset", "#TC_RETURNa $func $offset",
[(PPCtc_return (i32 imm:$func), imm:$offset)]>; [(PPCtc_return (i32 imm:$func), imm:$offset)]>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
def TCRETURNri : Pseudo<(outs), (ins CTRRC:$dst, i32imm:$offset, variable_ops), def TCRETURNri : Pseudo<(outs), (ins CTRRC:$dst, i32imm:$offset, variable_ops),
"#TC_RETURNr $dst $offset", "#TC_RETURNr $dst $offset",
[]>; []>;
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1, let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1,
isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR] in isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR, RM] in
def TAILBCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>, def TAILBCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>,
Requires<[In32BitMode]>; Requires<[In32BitMode]>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
isBarrier = 1, isCall = 1, isReturn = 1 in isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
def TAILB : IForm<18, 0, 0, (outs), (ins calltarget:$dst), def TAILB : IForm<18, 0, 0, (outs), (ins calltarget:$dst),
"b $dst", BrB, "b $dst", BrB,
[]>; []>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7, let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
isBarrier = 1, isCall = 1, isReturn = 1 in isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
def TAILBA : IForm<18, 0, 0, (outs), (ins aaddr:$dst), def TAILBA : IForm<18, 0, 0, (outs), (ins aaddr:$dst),
"ba $dst", BrB, "ba $dst", BrB,
[]>; []>;
@ -982,18 +986,20 @@ def FCMPUS : XForm_17<63, 0, (outs CRRC:$crD), (ins F4RC:$fA, F4RC:$fB),
def FCMPUD : XForm_17<63, 0, (outs CRRC:$crD), (ins F8RC:$fA, F8RC:$fB), def FCMPUD : XForm_17<63, 0, (outs CRRC:$crD), (ins F8RC:$fA, F8RC:$fB),
"fcmpu $crD, $fA, $fB", FPCompare>; "fcmpu $crD, $fA, $fB", FPCompare>;
def FCTIWZ : XForm_26<63, 15, (outs F8RC:$frD), (ins F8RC:$frB), let Uses = [RM] in {
"fctiwz $frD, $frB", FPGeneral, def FCTIWZ : XForm_26<63, 15, (outs F8RC:$frD), (ins F8RC:$frB),
[(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>; "fctiwz $frD, $frB", FPGeneral,
def FRSP : XForm_26<63, 12, (outs F4RC:$frD), (ins F8RC:$frB), [(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>;
"frsp $frD, $frB", FPGeneral, def FRSP : XForm_26<63, 12, (outs F4RC:$frD), (ins F8RC:$frB),
[(set F4RC:$frD, (fround F8RC:$frB))]>; "frsp $frD, $frB", FPGeneral,
def FSQRT : XForm_26<63, 22, (outs F8RC:$frD), (ins F8RC:$frB), [(set F4RC:$frD, (fround F8RC:$frB))]>;
"fsqrt $frD, $frB", FPSqrt, def FSQRT : XForm_26<63, 22, (outs F8RC:$frD), (ins F8RC:$frB),
[(set F8RC:$frD, (fsqrt F8RC:$frB))]>; "fsqrt $frD, $frB", FPSqrt,
def FSQRTS : XForm_26<59, 22, (outs F4RC:$frD), (ins F4RC:$frB), [(set F8RC:$frD, (fsqrt F8RC:$frB))]>;
"fsqrts $frD, $frB", FPSqrt, def FSQRTS : XForm_26<59, 22, (outs F4RC:$frD), (ins F4RC:$frB),
[(set F4RC:$frD, (fsqrt F4RC:$frB))]>; "fsqrts $frD, $frB", FPSqrt,
[(set F4RC:$frD, (fsqrt F4RC:$frB))]>;
}
} }
/// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending. /// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending.
@ -1095,10 +1101,15 @@ def MFVRSAVE : XFXForm_1_ext<31, 339, 256, (outs GPRC:$rT), (ins),
def MTCRF : XFXForm_5<31, 144, (outs), (ins crbitm:$FXM, GPRC:$rS), def MTCRF : XFXForm_5<31, 144, (outs), (ins crbitm:$FXM, GPRC:$rS),
"mtcrf $FXM, $rS", BrMCRX>, "mtcrf $FXM, $rS", BrMCRX>,
PPC970_MicroCode, PPC970_Unit_CRU; PPC970_MicroCode, PPC970_Unit_CRU;
let Uses = [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7] in { // FIXME: this Uses all the CR registers. Marking it as such is
// necessary for DeadMachineInstructionElim to do the right thing.
// However, marking it also exposes PR 2964, and causes crashes in
// the Local RA because it doesn't like this sequence:
// vreg = MCRF CR0
// MFCR <kill of whatever preg got assigned to vreg>
// For now DeadMachineInstructionElim is turned off, so don't do the marking.
def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins), "mfcr $rT", SprMFCR>, def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins), "mfcr $rT", SprMFCR>,
PPC970_MicroCode, PPC970_Unit_CRU; PPC970_MicroCode, PPC970_Unit_CRU;
}
def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM), def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM),
"mfcr $rT, $FXM", SprMFCR>, "mfcr $rT, $FXM", SprMFCR>,
PPC970_DGroup_First, PPC970_Unit_CRU; PPC970_DGroup_First, PPC970_Unit_CRU;
@ -1106,33 +1117,38 @@ def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM),
// Instructions to manipulate FPSCR. Only long double handling uses these. // Instructions to manipulate FPSCR. Only long double handling uses these.
// FPSCR is not modelled; we use the SDNode Flag to keep things in order. // FPSCR is not modelled; we use the SDNode Flag to keep things in order.
def MFFS : XForm_42<63, 583, (outs F8RC:$rT), (ins), let Uses = [RM], Defs = [RM] in {
"mffs $rT", IntMFFS, def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
[(set F8RC:$rT, (PPCmffs))]>, "mtfsb0 $FM", IntMTFSB0,
PPC970_DGroup_Single, PPC970_Unit_FPU; [(PPCmtfsb0 (i32 imm:$FM))]>,
def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM), PPC970_DGroup_Single, PPC970_Unit_FPU;
"mtfsb0 $FM", IntMTFSB0, def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
[(PPCmtfsb0 (i32 imm:$FM))]>, "mtfsb1 $FM", IntMTFSB0,
PPC970_DGroup_Single, PPC970_Unit_FPU; [(PPCmtfsb1 (i32 imm:$FM))]>,
def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM), PPC970_DGroup_Single, PPC970_Unit_FPU;
"mtfsb1 $FM", IntMTFSB0, // MTFSF does not actually produce an FP result. We pretend it copies
[(PPCmtfsb1 (i32 imm:$FM))]>, // input reg B to the output. If we didn't do this it would look like the
PPC970_DGroup_Single, PPC970_Unit_FPU; // instruction had no outputs (because we aren't modelling the FPSCR) and
def FADDrtz: AForm_2<63, 21, // it would be deleted.
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), def MTFSF : XFLForm<63, 711, (outs F8RC:$FRA),
"fadd $FRT, $FRA, $FRB", FPGeneral, (ins i32imm:$FM, F8RC:$rT, F8RC:$FRB),
[(set F8RC:$FRT, (PPCfaddrtz F8RC:$FRA, F8RC:$FRB))]>, "mtfsf $FM, $rT", "$FRB = $FRA", IntMTFSB0,
PPC970_DGroup_Single, PPC970_Unit_FPU; [(set F8RC:$FRA, (PPCmtfsf (i32 imm:$FM),
// MTFSF does not actually produce an FP result. We pretend it copies F8RC:$rT, F8RC:$FRB))]>,
// input reg B to the output. If we didn't do this it would look like the PPC970_DGroup_Single, PPC970_Unit_FPU;
// instruction had no outputs (because we aren't modelling the FPSCR) and }
// it would be deleted. let Uses = [RM] in {
def MTFSF : XFLForm<63, 711, (outs F8RC:$FRA), def MFFS : XForm_42<63, 583, (outs F8RC:$rT), (ins),
(ins i32imm:$FM, F8RC:$rT, F8RC:$FRB), "mffs $rT", IntMFFS,
"mtfsf $FM, $rT", "$FRB = $FRA", IntMTFSB0, [(set F8RC:$rT, (PPCmffs))]>,
[(set F8RC:$FRA, (PPCmtfsf (i32 imm:$FM), PPC970_DGroup_Single, PPC970_Unit_FPU;
F8RC:$rT, F8RC:$FRB))]>, def FADDrtz: AForm_2<63, 21,
PPC970_DGroup_Single, PPC970_Unit_FPU; (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB),
"fadd $FRT, $FRA, $FRB", FPGeneral,
[(set F8RC:$FRT, (PPCfaddrtz F8RC:$FRA, F8RC:$FRB))]>,
PPC970_DGroup_Single, PPC970_Unit_FPU;
}
let PPC970_Unit = 1 in { // FXU Operations. let PPC970_Unit = 1 in { // FXU Operations.
@ -1196,54 +1212,56 @@ def SUBFZE : XOForm_3<31, 200, 0, (outs GPRC:$rT), (ins GPRC:$rA),
// this type. // this type.
// //
let PPC970_Unit = 3 in { // FPU Operations. let PPC970_Unit = 3 in { // FPU Operations.
def FMADD : AForm_1<63, 29, let Uses = [RM] in {
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), def FMADD : AForm_1<63, 29,
"fmadd $FRT, $FRA, $FRC, $FRB", FPFused, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
[(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC), "fmadd $FRT, $FRA, $FRC, $FRB", FPFused,
F8RC:$FRB))]>, [(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC),
Requires<[FPContractions]>; F8RC:$FRB))]>,
def FMADDS : AForm_1<59, 29, Requires<[FPContractions]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), def FMADDS : AForm_1<59, 29,
"fmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
[(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC), "fmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
F4RC:$FRB))]>, [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC),
Requires<[FPContractions]>; F4RC:$FRB))]>,
def FMSUB : AForm_1<63, 28, Requires<[FPContractions]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), def FMSUB : AForm_1<63, 28,
"fmsub $FRT, $FRA, $FRC, $FRB", FPFused, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
[(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC), "fmsub $FRT, $FRA, $FRC, $FRB", FPFused,
F8RC:$FRB))]>, [(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC),
Requires<[FPContractions]>; F8RC:$FRB))]>,
def FMSUBS : AForm_1<59, 28, Requires<[FPContractions]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), def FMSUBS : AForm_1<59, 28,
"fmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
[(set F4RC:$FRT, (fsub (fmul F4RC:$FRA, F4RC:$FRC), "fmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
F4RC:$FRB))]>, [(set F4RC:$FRT, (fsub (fmul F4RC:$FRA, F4RC:$FRC),
Requires<[FPContractions]>; F4RC:$FRB))]>,
def FNMADD : AForm_1<63, 31, Requires<[FPContractions]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), def FNMADD : AForm_1<63, 31,
"fnmadd $FRT, $FRA, $FRC, $FRB", FPFused, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
[(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC), "fnmadd $FRT, $FRA, $FRC, $FRB", FPFused,
F8RC:$FRB)))]>, [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
Requires<[FPContractions]>; F8RC:$FRB)))]>,
def FNMADDS : AForm_1<59, 31, Requires<[FPContractions]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), def FNMADDS : AForm_1<59, 31,
"fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
[(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC), "fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
F4RC:$FRB)))]>, [(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC),
Requires<[FPContractions]>; F4RC:$FRB)))]>,
def FNMSUB : AForm_1<63, 30, Requires<[FPContractions]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), def FNMSUB : AForm_1<63, 30,
"fnmsub $FRT, $FRA, $FRC, $FRB", FPFused, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
[(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC), "fnmsub $FRT, $FRA, $FRC, $FRB", FPFused,
F8RC:$FRB)))]>, [(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
Requires<[FPContractions]>; F8RC:$FRB)))]>,
def FNMSUBS : AForm_1<59, 30, Requires<[FPContractions]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), def FNMSUBS : AForm_1<59, 30,
"fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
[(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC), "fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
F4RC:$FRB)))]>, [(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC),
Requires<[FPContractions]>; F4RC:$FRB)))]>,
Requires<[FPContractions]>;
}
// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid // FSEL is artificially split into 4 and 8-byte forms for the result. To avoid
// having 4 of these, force the comparison to always be an 8-byte double (code // having 4 of these, force the comparison to always be an 8-byte double (code
// should use an FMRSD if the input comparison value really wants to be a float) // should use an FMRSD if the input comparison value really wants to be a float)
@ -1256,38 +1274,40 @@ def FSELS : AForm_1<63, 23,
(outs F4RC:$FRT), (ins F8RC:$FRA, F4RC:$FRC, F4RC:$FRB), (outs F4RC:$FRT), (ins F8RC:$FRA, F4RC:$FRC, F4RC:$FRB),
"fsel $FRT, $FRA, $FRC, $FRB", FPGeneral, "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral,
[(set F4RC:$FRT, (PPCfsel F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>; [(set F4RC:$FRT, (PPCfsel F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>;
def FADD : AForm_2<63, 21, let Uses = [RM] in {
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), def FADD : AForm_2<63, 21,
"fadd $FRT, $FRA, $FRB", FPGeneral, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB),
[(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>; "fadd $FRT, $FRA, $FRB", FPGeneral,
def FADDS : AForm_2<59, 21, [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), def FADDS : AForm_2<59, 21,
"fadds $FRT, $FRA, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB),
[(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>; "fadds $FRT, $FRA, $FRB", FPGeneral,
def FDIV : AForm_2<63, 18, [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), def FDIV : AForm_2<63, 18,
"fdiv $FRT, $FRA, $FRB", FPDivD, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB),
[(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>; "fdiv $FRT, $FRA, $FRB", FPDivD,
def FDIVS : AForm_2<59, 18, [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), def FDIVS : AForm_2<59, 18,
"fdivs $FRT, $FRA, $FRB", FPDivS, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB),
[(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>; "fdivs $FRT, $FRA, $FRB", FPDivS,
def FMUL : AForm_3<63, 25, [(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), def FMUL : AForm_3<63, 25,
"fmul $FRT, $FRA, $FRB", FPFused, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB),
[(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>; "fmul $FRT, $FRA, $FRB", FPFused,
def FMULS : AForm_3<59, 25, [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), def FMULS : AForm_3<59, 25,
"fmuls $FRT, $FRA, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB),
[(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>; "fmuls $FRT, $FRA, $FRB", FPGeneral,
def FSUB : AForm_2<63, 20, [(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>;
(outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB), def FSUB : AForm_2<63, 20,
"fsub $FRT, $FRA, $FRB", FPGeneral, (outs F8RC:$FRT), (ins F8RC:$FRA, F8RC:$FRB),
[(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>; "fsub $FRT, $FRA, $FRB", FPGeneral,
def FSUBS : AForm_2<59, 20, [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>;
(outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB), def FSUBS : AForm_2<59, 20,
"fsubs $FRT, $FRA, $FRB", FPGeneral, (outs F4RC:$FRT), (ins F4RC:$FRA, F4RC:$FRB),
[(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>; "fsubs $FRT, $FRA, $FRB", FPGeneral,
[(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>;
}
} }
let PPC970_Unit = 1 in { // FXU Operations. let PPC970_Unit = 1 in { // FXU Operations.

View File

@ -347,6 +347,7 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(PPC::R1); Reserved.set(PPC::R1);
Reserved.set(PPC::LR); Reserved.set(PPC::LR);
Reserved.set(PPC::LR8); Reserved.set(PPC::LR8);
Reserved.set(PPC::RM);
// In Linux, r2 is reserved for the OS. // In Linux, r2 is reserved for the OS.
if (!Subtarget.isDarwin()) if (!Subtarget.isDarwin())
@ -1163,7 +1164,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
for (unsigned I = 0, E = CSI.size(); I != E; ++I) { for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
unsigned Reg = CSI[I].getReg(); unsigned Reg = CSI[I].getReg();
if (Reg == PPC::LR || Reg == PPC::LR8) continue; if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg); MachineLocation CSSrc(Reg);
Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));

View File

@ -254,6 +254,16 @@ def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66]>;
// VRsave register // VRsave register
def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<[107]>; def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<[107]>;
// FP rounding mode: bits 30 and 31 of the FP status and control register
// This is not allocated as a normal register; it appears only in
// Uses and Defs. The ABI says it needs to be preserved by a function,
// but this is not achieved by saving and restoring it as with
// most registers, it has to be done in code; to make this work all the
// return and call instructions are described as Uses of RM, so instructions
// that do nothing but change RM will not get deleted.
// Also, in the architecture it is not really a SPR; 512 is arbitrary.
def RM: SPR<512, "**ROUNDING MODE**">, DwarfRegNum<[0]>;
/// Register classes /// Register classes
// Allocate volatiles first // Allocate volatiles first
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31 // then nonvolatiles in reverse order since stmw/lmw save from rN to r31