@@ -1727,37 +1727,59 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1727
1727
}
1728
1728
1729
1729
namespace {
1730
+ void emitRX (unsigned Opcode, unsigned DstReg, MCOperand Imm, SMLoc IDLoc,
1731
+ SmallVectorImpl<MCInst> &Instructions) {
1732
+ MCInst tmpInst;
1733
+ tmpInst.setOpcode (Opcode);
1734
+ tmpInst.addOperand (MCOperand::createReg (DstReg));
1735
+ tmpInst.addOperand (Imm);
1736
+ tmpInst.setLoc (IDLoc);
1737
+ Instructions.push_back (tmpInst);
1738
+ }
1739
+
1740
+ void emitRI (unsigned Opcode, unsigned DstReg, int16_t Imm, SMLoc IDLoc,
1741
+ SmallVectorImpl<MCInst> &Instructions) {
1742
+ emitRX (Opcode, DstReg, MCOperand::createImm (Imm), IDLoc, Instructions);
1743
+ }
1744
+
1745
+
1746
+ void emitRRX (unsigned Opcode, unsigned DstReg, unsigned SrcReg, MCOperand Imm,
1747
+ SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1748
+ MCInst tmpInst;
1749
+ tmpInst.setOpcode (Opcode);
1750
+ tmpInst.addOperand (MCOperand::createReg (DstReg));
1751
+ tmpInst.addOperand (MCOperand::createReg (SrcReg));
1752
+ tmpInst.addOperand (Imm);
1753
+ tmpInst.setLoc (IDLoc);
1754
+ Instructions.push_back (tmpInst);
1755
+ }
1756
+
1757
+ void emitRRR (unsigned Opcode, unsigned DstReg, unsigned SrcReg,
1758
+ unsigned SrcReg2, SMLoc IDLoc,
1759
+ SmallVectorImpl<MCInst> &Instructions) {
1760
+ emitRRX (Opcode, DstReg, SrcReg, MCOperand::createReg (SrcReg2), IDLoc,
1761
+ Instructions);
1762
+ }
1763
+
1764
+ void emitRRI (unsigned Opcode, unsigned DstReg, unsigned SrcReg, int16_t Imm,
1765
+ SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1766
+ emitRRX (Opcode, DstReg, SrcReg, MCOperand::createImm (Imm), IDLoc,
1767
+ Instructions);
1768
+ }
1769
+
1730
1770
template <unsigned ShiftAmount>
1731
1771
void createLShiftOri (MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1732
1772
SmallVectorImpl<MCInst> &Instructions) {
1733
- MCInst tmpInst;
1734
- if (ShiftAmount >= 32 ) {
1735
- tmpInst.setOpcode (Mips::DSLL32);
1736
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1737
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1738
- tmpInst.addOperand (MCOperand::createImm (ShiftAmount - 32 ));
1739
- tmpInst.setLoc (IDLoc);
1740
- Instructions.push_back (tmpInst);
1741
- tmpInst.clear ();
1742
- } else if (ShiftAmount > 0 ) {
1743
- tmpInst.setOpcode (Mips::DSLL);
1744
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1745
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1746
- tmpInst.addOperand (MCOperand::createImm (ShiftAmount));
1747
- tmpInst.setLoc (IDLoc);
1748
- Instructions.push_back (tmpInst);
1749
- tmpInst.clear ();
1750
- }
1773
+ if (ShiftAmount >= 32 )
1774
+ emitRRI (Mips::DSLL32, RegNo, RegNo, ShiftAmount - 32 , IDLoc, Instructions);
1775
+ else if (ShiftAmount > 0 )
1776
+ emitRRI (Mips::DSLL, RegNo, RegNo, ShiftAmount, IDLoc, Instructions);
1777
+
1751
1778
// There's no need for an ORi if the immediate is 0.
1752
1779
if (Operand.isImm () && Operand.getImm () == 0 )
1753
1780
return ;
1754
1781
1755
- tmpInst.setOpcode (Mips::ORi);
1756
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1757
- tmpInst.addOperand (MCOperand::createReg (RegNo));
1758
- tmpInst.addOperand (Operand);
1759
- tmpInst.setLoc (IDLoc);
1760
- Instructions.push_back (tmpInst);
1782
+ emitRRX (Mips::ORi, RegNo, RegNo, Operand, IDLoc, Instructions);
1761
1783
}
1762
1784
1763
1785
template <unsigned ShiftAmount>
@@ -1818,12 +1840,22 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1818
1840
return true ;
1819
1841
}
1820
1842
1843
+ if (Is32BitImm) {
1844
+ if (isInt<32 >(ImmValue) || isUInt<32 >(ImmValue)) {
1845
+ // Sign extend up to 64-bit so that the predicates match the hardware
1846
+ // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
1847
+ // true.
1848
+ ImmValue = SignExtend64<32 >(ImmValue);
1849
+ } else {
1850
+ Error (IDLoc, " instruction requires a 32-bit immediate" );
1851
+ return true ;
1852
+ }
1853
+ }
1854
+
1821
1855
bool UseSrcReg = false ;
1822
1856
if (SrcReg != Mips::NoRegister)
1823
1857
UseSrcReg = true ;
1824
1858
1825
- MCInst tmpInst;
1826
-
1827
1859
unsigned TmpReg = DstReg;
1828
1860
if (UseSrcReg && (DstReg == SrcReg)) {
1829
1861
// At this point we need AT to perform the expansions and we exit if it is
@@ -1834,29 +1866,26 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1834
1866
TmpReg = ATReg;
1835
1867
}
1836
1868
1837
- tmpInst.setLoc (IDLoc);
1838
1869
// FIXME: gas has a special case for values that are 000...1111, which
1839
1870
// becomes a li -1 and then a dsrl
1840
- if (0 <= ImmValue && ImmValue <= 65535 ) {
1841
- // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1842
- // li d,j => ori d,$zero,j
1843
- if (!UseSrcReg)
1844
- SrcReg = isGP64bit () ? Mips::ZERO_64 : Mips::ZERO;
1845
- tmpInst.setOpcode (Mips::ORi);
1846
- tmpInst.addOperand (MCOperand::createReg (DstReg));
1847
- tmpInst.addOperand (MCOperand::createReg (SrcReg));
1848
- tmpInst.addOperand (MCOperand::createImm (ImmValue));
1849
- Instructions.push_back (tmpInst);
1850
- } else if (ImmValue < 0 && ImmValue >= -32768 ) {
1851
- // For negative signed 16-bit values (-32768 <= j < 0):
1871
+ if (isInt<16 >(ImmValue)) {
1852
1872
// li d,j => addiu d,$zero,j
1853
1873
if (!UseSrcReg)
1854
1874
SrcReg = Mips::ZERO;
1855
- tmpInst.setOpcode (Mips::ADDiu);
1856
- tmpInst.addOperand (MCOperand::createReg (DstReg));
1857
- tmpInst.addOperand (MCOperand::createReg (SrcReg));
1858
- tmpInst.addOperand (MCOperand::createImm (ImmValue));
1859
- Instructions.push_back (tmpInst);
1875
+ emitRRI (Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1876
+ } else if (isUInt<16 >(ImmValue)) {
1877
+ // li d,j => ori d,$zero,j
1878
+ unsigned TmpReg = DstReg;
1879
+ if (SrcReg == DstReg) {
1880
+ unsigned ATReg = getATReg (IDLoc);
1881
+ if (!ATReg)
1882
+ return true ;
1883
+ TmpReg = ATReg;
1884
+ }
1885
+
1886
+ emitRRI (Mips::ORi, TmpReg, Mips::ZERO, ImmValue, IDLoc, Instructions);
1887
+ if (UseSrcReg)
1888
+ emitRRR (Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1860
1889
} else if (isInt<32 >(ImmValue) || isUInt<32 >(ImmValue)) {
1861
1890
warnIfNoMacro (IDLoc);
1862
1891
@@ -1869,30 +1898,16 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1869
1898
if (!Is32BitImm && !isInt<32 >(ImmValue)) {
1870
1899
// For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1871
1900
// upper 32 bits.
1872
- tmpInst.setOpcode (Mips::ORi);
1873
- tmpInst.addOperand (MCOperand::createReg (TmpReg));
1874
- tmpInst.addOperand (MCOperand::createReg (Mips::ZERO));
1875
- tmpInst.addOperand (MCOperand::createImm (Bits31To16));
1876
- tmpInst.setLoc (IDLoc);
1877
- Instructions.push_back (tmpInst);
1878
- // Move the value to the upper 16 bits by doing a 16-bit left shift.
1879
- createLShiftOri<16 >(0 , TmpReg, IDLoc, Instructions);
1880
- } else {
1881
- tmpInst.setOpcode (Mips::LUi);
1882
- tmpInst.addOperand (MCOperand::createReg (TmpReg));
1883
- tmpInst.addOperand (MCOperand::createImm (Bits31To16));
1884
- Instructions.push_back (tmpInst);
1885
- }
1901
+ emitRRI (Mips::ORi, TmpReg, Mips::ZERO, Bits31To16, IDLoc, Instructions);
1902
+ emitRRI (Mips::DSLL, TmpReg, TmpReg, 16 , IDLoc, Instructions);
1903
+ } else
1904
+ emitRI (Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1886
1905
createLShiftOri<0 >(Bits15To0, TmpReg, IDLoc, Instructions);
1887
1906
1888
1907
if (UseSrcReg)
1889
1908
createAddu (DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1890
1909
1891
1910
} else if ((ImmValue & (0xffffLL << 48 )) == 0 ) {
1892
- if (Is32BitImm) {
1893
- Error (IDLoc, " instruction requires a 32-bit immediate" );
1894
- return true ;
1895
- }
1896
1911
warnIfNoMacro (IDLoc);
1897
1912
1898
1913
// <------- lo32 ------>
@@ -1912,21 +1927,14 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1912
1927
uint16_t Bits31To16 = (ImmValue >> 16 ) & 0xffff ;
1913
1928
uint16_t Bits15To0 = ImmValue & 0xffff ;
1914
1929
1915
- tmpInst.setOpcode (Mips::LUi);
1916
- tmpInst.addOperand (MCOperand::createReg (TmpReg));
1917
- tmpInst.addOperand (MCOperand::createImm (Bits47To32));
1918
- Instructions.push_back (tmpInst);
1930
+ emitRI (Mips::LUi, TmpReg, Bits47To32, IDLoc, Instructions);
1919
1931
createLShiftOri<0 >(Bits31To16, TmpReg, IDLoc, Instructions);
1920
1932
createLShiftOri<16 >(Bits15To0, TmpReg, IDLoc, Instructions);
1921
1933
1922
1934
if (UseSrcReg)
1923
1935
createAddu (DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1924
1936
1925
1937
} else {
1926
- if (Is32BitImm) {
1927
- Error (IDLoc, " instruction requires a 32-bit immediate" );
1928
- return true ;
1929
- }
1930
1938
warnIfNoMacro (IDLoc);
1931
1939
1932
1940
// <------- hi32 ------> <------- lo32 ------>
@@ -1948,10 +1956,7 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1948
1956
uint16_t Bits31To16 = (ImmValue >> 16 ) & 0xffff ;
1949
1957
uint16_t Bits15To0 = ImmValue & 0xffff ;
1950
1958
1951
- tmpInst.setOpcode (Mips::LUi);
1952
- tmpInst.addOperand (MCOperand::createReg (TmpReg));
1953
- tmpInst.addOperand (MCOperand::createImm (Bits63To48));
1954
- Instructions.push_back (tmpInst);
1959
+ emitRI (Mips::LUi, TmpReg, Bits63To48, IDLoc, Instructions);
1955
1960
createLShiftOri<0 >(Bits47To32, TmpReg, IDLoc, Instructions);
1956
1961
1957
1962
// When Bits31To16 is 0, do a left shift of 32 bits instead of doing
@@ -2096,8 +2101,8 @@ bool MipsAsmParser::loadAndAddSymbolAddress(
2096
2101
tmpInst.addOperand (MCOperand::createExpr (HiExpr));
2097
2102
Instructions.push_back (tmpInst);
2098
2103
2099
- createLShiftOri< 0 >( MCOperand::createExpr (LoExpr), TmpReg , SMLoc (),
2100
- Instructions);
2104
+ emitRRX (Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr (LoExpr), SMLoc (),
2105
+ Instructions);
2101
2106
}
2102
2107
2103
2108
if (UseSrcReg)
@@ -2708,12 +2713,8 @@ void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2708
2713
void MipsAsmParser::createAddu (unsigned DstReg, unsigned SrcReg,
2709
2714
unsigned TrgReg, bool Is64Bit,
2710
2715
SmallVectorImpl<MCInst> &Instructions) {
2711
- MCInst AdduInst;
2712
- AdduInst.setOpcode (Is64Bit ? Mips::DADDu : Mips::ADDu);
2713
- AdduInst.addOperand (MCOperand::createReg (DstReg));
2714
- AdduInst.addOperand (MCOperand::createReg (SrcReg));
2715
- AdduInst.addOperand (MCOperand::createReg (TrgReg));
2716
- Instructions.push_back (AdduInst);
2716
+ emitRRR (Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc (),
2717
+ Instructions);
2717
2718
}
2718
2719
2719
2720
unsigned MipsAsmParser::checkTargetMatchPredicate (MCInst &Inst) {
0 commit comments