diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-10-07 18:49:46 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-10-07 18:49:46 +0000 |
commit | 243702b95a471ffb7d2374dfad3d7f8b11bee7e7 (patch) | |
tree | ab2d61d1494d5822ce311f09c9f00add40957013 /lib/Target/Mips/MipsInstrInfo.td | |
parent | 379f76e873b91550e3d9cee79dff814e3ce1e86e (diff) | |
download | llvm-243702b95a471ffb7d2374dfad3d7f8b11bee7e7.tar.gz llvm-243702b95a471ffb7d2374dfad3d7f8b11bee7e7.tar.bz2 llvm-243702b95a471ffb7d2374dfad3d7f8b11bee7e7.tar.xz |
[mips] Fix definition of mfhi and mflo instructions to read from the whole
accumulator instead of its sub-registers, $hi and $lo.
We need this change to prevent a mflo following a mtlo from reading an
unpredictable/undefined value, as shown in the following example:
mult $6, $7 // result of $6 * $7 is written to $lo and $hi.
mflo $2 // read lower 32-bit result from $lo.
mtlo $4 // write to $lo. the content of $hi becomes unpredictable.
mfhi $3 // read higher 32-bit from $hi, which has an unpredictable value.
I don't have a test case for this change that reliably reproduces the problem.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192119 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsInstrInfo.td')
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index f92f3336f1..cdc1bae777 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -23,8 +23,7 @@ def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisInt<4>]>; def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; -def SDT_ExtractLOHI : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVT<1, untyped>, - SDTCisVT<2, i32>]>; +def SDT_ExtractLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>; def SDT_InsertLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; @@ -86,8 +85,9 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, [SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, SDNPOutGlue]>; -// Node used to extract integer from LO/HI register. -def ExtractLOHI : SDNode<"MipsISD::ExtractLOHI", SDT_ExtractLOHI>; +// Nodes used to extract LO/HI registers. +def MipsExtractHI : SDNode<"MipsISD::ExtractHI", SDT_ExtractLOHI>; +def MipsExtractLO : SDNode<"MipsISD::ExtractLO", SDT_ExtractLOHI>; // Node used to insert 32-bit integers to LOHI register pair. def InsertLOHI : SDNode<"MipsISD::InsertLOHI", SDT_InsertLOHI>; @@ -697,10 +697,14 @@ class Div<string opstr, InstrItinClass itin, RegisterOperand RO, } // Move from Hi/Lo -class MoveFromLOHI<string opstr, RegisterOperand RO, list<Register> UseRegs>: - InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, - FrmR, opstr> { - let Uses = UseRegs; +class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode> + : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo), + [(set DstRC:$rd, (OpNode SrcRC:$hilo))], IIHiLo>; + +class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>: + InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR, + opstr> { + let Uses = [UseReg]; let neverHasSideEffects = 1; } @@ -1035,8 +1039,10 @@ def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, IIIdiv, def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>; def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>; -def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, [HI0]>, MFLO_FM<0x10>; -def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, [LO0]>, MFLO_FM<0x12>; +def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>; +def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>; +def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsExtractHI>; +def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsExtractLO>; /// Sign Ext In Register Instructions. def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd>, SEB_FM<0x10, 0x20>; @@ -1349,10 +1355,6 @@ defm : SetgeImmPats<GPR32, SLTi, SLTiu>; // bswap pattern def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; -// mflo/hi patterns. -def : MipsPat<(i32 (ExtractLOHI ACC64:$ac, imm:$lohi_idx)), - (EXTRACT_SUBREG ACC64:$ac, imm:$lohi_idx)>; - // Load halfword/word patterns. let AddedComplexity = 40 in { let Predicates = [HasStdEnc] in { |