@@ -1823,58 +1823,30 @@ func (ins *instruction) validate(ctxt *obj.Link) {
1823
1823
enc .validate (ctxt , ins )
1824
1824
}
1825
1825
1826
- // instructionsForProg returns the machine instructions for an *obj.Prog.
1827
- func instructionsForProg (p * obj.Prog ) [] * instruction {
1826
+ // instructionForProg returns the default *obj.Prog to instruction mapping .
1827
+ func instructionForProg (p * obj.Prog ) * instruction {
1828
1828
ins := & instruction {
1829
1829
as : p .As ,
1830
1830
rd : uint32 (p .To .Reg ),
1831
1831
rs1 : uint32 (p .Reg ),
1832
1832
rs2 : uint32 (p .From .Reg ),
1833
1833
imm : p .From .Offset ,
1834
1834
}
1835
-
1836
1835
if len (p .RestArgs ) == 1 {
1837
1836
ins .rs3 = uint32 (p .RestArgs [0 ].Reg )
1838
- } else if len (p .RestArgs ) > 0 {
1839
- p .Ctxt .Diag ("too many source registers" )
1840
1837
}
1838
+ return ins
1839
+ }
1841
1840
1841
+ // instructionsForMOV returns the machine instructions for an *obj.Prog that
1842
+ // uses a MOV pseudo-instruction.
1843
+ func instructionsForMOV (p * obj.Prog ) []* instruction {
1844
+ ins := instructionForProg (p )
1842
1845
inss := []* instruction {ins }
1843
- switch ins .as {
1844
- case AJAL , AJALR :
1845
- ins .rd , ins .rs1 , ins .rs2 = uint32 (p .From .Reg ), uint32 (p .To .Reg ), obj .REG_NONE
1846
- ins .imm = p .To .Offset
1847
1846
1848
- case ABEQ , ABEQZ , ABGE , ABGEU , ABGEZ , ABGT , ABGTU , ABGTZ , ABLE , ABLEU , ABLEZ , ABLT , ABLTU , ABLTZ , ABNE , ABNEZ :
1849
- switch ins .as {
1850
- case ABEQZ :
1851
- ins .as , ins .rs1 , ins .rs2 = ABEQ , REG_ZERO , uint32 (p .From .Reg )
1852
- case ABGEZ :
1853
- ins .as , ins .rs1 , ins .rs2 = ABGE , REG_ZERO , uint32 (p .From .Reg )
1854
- case ABGT :
1855
- ins .as , ins .rs1 , ins .rs2 = ABLT , uint32 (p .From .Reg ), uint32 (p .Reg )
1856
- case ABGTU :
1857
- ins .as , ins .rs1 , ins .rs2 = ABLTU , uint32 (p .From .Reg ), uint32 (p .Reg )
1858
- case ABGTZ :
1859
- ins .as , ins .rs1 , ins .rs2 = ABLT , uint32 (p .From .Reg ), REG_ZERO
1860
- case ABLE :
1861
- ins .as , ins .rs1 , ins .rs2 = ABGE , uint32 (p .From .Reg ), uint32 (p .Reg )
1862
- case ABLEU :
1863
- ins .as , ins .rs1 , ins .rs2 = ABGEU , uint32 (p .From .Reg ), uint32 (p .Reg )
1864
- case ABLEZ :
1865
- ins .as , ins .rs1 , ins .rs2 = ABGE , uint32 (p .From .Reg ), REG_ZERO
1866
- case ABLTZ :
1867
- ins .as , ins .rs1 , ins .rs2 = ABLT , REG_ZERO , uint32 (p .From .Reg )
1868
- case ABNEZ :
1869
- ins .as , ins .rs1 , ins .rs2 = ABNE , REG_ZERO , uint32 (p .From .Reg )
1870
- }
1871
- ins .imm = p .To .Offset
1872
-
1873
- case AMOV , AMOVB , AMOVH , AMOVW , AMOVBU , AMOVHU , AMOVWU , AMOVF , AMOVD :
1847
+ switch {
1848
+ case p .From .Type == obj .TYPE_REG && p .To .Type == obj .TYPE_REG :
1874
1849
// Handle register to register moves.
1875
- if p .From .Type != obj .TYPE_REG || p .To .Type != obj .TYPE_REG {
1876
- return nil
1877
- }
1878
1850
switch p .As {
1879
1851
case AMOV : // MOV Ra, Rb -> ADDI $0, Ra, Rb
1880
1852
ins .as , ins .rs1 , ins .rs2 , ins .imm = AADDI , uint32 (p .From .Reg ), obj .REG_NONE , 0
@@ -1908,6 +1880,61 @@ func instructionsForProg(p *obj.Prog) []*instruction {
1908
1880
inss = append (inss , ins2 )
1909
1881
}
1910
1882
1883
+ default :
1884
+ // If we get here with a MOV pseudo-instruction it is going to
1885
+ // remain unhandled. For now we trust rewriteMOV to catch these.
1886
+ switch p .As {
1887
+ case AMOV , AMOVB , AMOVH , AMOVW , AMOVBU , AMOVHU , AMOVWU , AMOVF , AMOVD :
1888
+ return nil
1889
+ }
1890
+ }
1891
+
1892
+ return inss
1893
+ }
1894
+
1895
+ // instructionsForProg returns the machine instructions for an *obj.Prog.
1896
+ func instructionsForProg (p * obj.Prog ) []* instruction {
1897
+ ins := instructionForProg (p )
1898
+ inss := []* instruction {ins }
1899
+
1900
+ if len (p .RestArgs ) > 1 {
1901
+ p .Ctxt .Diag ("too many source registers" )
1902
+ return nil
1903
+ }
1904
+
1905
+ switch ins .as {
1906
+ case AJAL , AJALR :
1907
+ ins .rd , ins .rs1 , ins .rs2 = uint32 (p .From .Reg ), uint32 (p .To .Reg ), obj .REG_NONE
1908
+ ins .imm = p .To .Offset
1909
+
1910
+ case ABEQ , ABEQZ , ABGE , ABGEU , ABGEZ , ABGT , ABGTU , ABGTZ , ABLE , ABLEU , ABLEZ , ABLT , ABLTU , ABLTZ , ABNE , ABNEZ :
1911
+ switch ins .as {
1912
+ case ABEQZ :
1913
+ ins .as , ins .rs1 , ins .rs2 = ABEQ , REG_ZERO , uint32 (p .From .Reg )
1914
+ case ABGEZ :
1915
+ ins .as , ins .rs1 , ins .rs2 = ABGE , REG_ZERO , uint32 (p .From .Reg )
1916
+ case ABGT :
1917
+ ins .as , ins .rs1 , ins .rs2 = ABLT , uint32 (p .From .Reg ), uint32 (p .Reg )
1918
+ case ABGTU :
1919
+ ins .as , ins .rs1 , ins .rs2 = ABLTU , uint32 (p .From .Reg ), uint32 (p .Reg )
1920
+ case ABGTZ :
1921
+ ins .as , ins .rs1 , ins .rs2 = ABLT , uint32 (p .From .Reg ), REG_ZERO
1922
+ case ABLE :
1923
+ ins .as , ins .rs1 , ins .rs2 = ABGE , uint32 (p .From .Reg ), uint32 (p .Reg )
1924
+ case ABLEU :
1925
+ ins .as , ins .rs1 , ins .rs2 = ABGEU , uint32 (p .From .Reg ), uint32 (p .Reg )
1926
+ case ABLEZ :
1927
+ ins .as , ins .rs1 , ins .rs2 = ABGE , uint32 (p .From .Reg ), REG_ZERO
1928
+ case ABLTZ :
1929
+ ins .as , ins .rs1 , ins .rs2 = ABLT , REG_ZERO , uint32 (p .From .Reg )
1930
+ case ABNEZ :
1931
+ ins .as , ins .rs1 , ins .rs2 = ABNE , REG_ZERO , uint32 (p .From .Reg )
1932
+ }
1933
+ ins .imm = p .To .Offset
1934
+
1935
+ case AMOV , AMOVB , AMOVH , AMOVW , AMOVBU , AMOVHU , AMOVWU , AMOVF , AMOVD :
1936
+ return instructionsForMOV (p )
1937
+
1911
1938
case ALW , ALWU , ALH , ALHU , ALB , ALBU , ALD , AFLW , AFLD :
1912
1939
if p .From .Type != obj .TYPE_MEM {
1913
1940
p .Ctxt .Diag ("%v requires memory for source" , p )
0 commit comments