Skip to content

Commit ab7c904

Browse files
committed
cmd/internal/obj/riscv: factor out instructions for MOV pseudo-instructions
This factors out the machine instruction generation for MOV pseudo-instructions, which will simplify further changes. Change-Id: Ic0d2c3ae9e0881f7894af50ed45e93b0e4961632 Reviewed-on: https://go-review.googlesource.com/c/go/+/344461 Trust: Joel Sing <[email protected]> Trust: Meng Zhuo <[email protected]> Run-TryBot: Joel Sing <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Meng Zhuo <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 17910ed commit ab7c904

File tree

1 file changed

+65
-38
lines changed
  • src/cmd/internal/obj/riscv

1 file changed

+65
-38
lines changed

src/cmd/internal/obj/riscv/obj.go

Lines changed: 65 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,58 +1823,30 @@ func (ins *instruction) validate(ctxt *obj.Link) {
18231823
enc.validate(ctxt, ins)
18241824
}
18251825

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 {
18281828
ins := &instruction{
18291829
as: p.As,
18301830
rd: uint32(p.To.Reg),
18311831
rs1: uint32(p.Reg),
18321832
rs2: uint32(p.From.Reg),
18331833
imm: p.From.Offset,
18341834
}
1835-
18361835
if len(p.RestArgs) == 1 {
18371836
ins.rs3 = uint32(p.RestArgs[0].Reg)
1838-
} else if len(p.RestArgs) > 0 {
1839-
p.Ctxt.Diag("too many source registers")
18401837
}
1838+
return ins
1839+
}
18411840

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)
18421845
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
18471846

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:
18741849
// Handle register to register moves.
1875-
if p.From.Type != obj.TYPE_REG || p.To.Type != obj.TYPE_REG {
1876-
return nil
1877-
}
18781850
switch p.As {
18791851
case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb
18801852
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 {
19081880
inss = append(inss, ins2)
19091881
}
19101882

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+
19111938
case ALW, ALWU, ALH, ALHU, ALB, ALBU, ALD, AFLW, AFLD:
19121939
if p.From.Type != obj.TYPE_MEM {
19131940
p.Ctxt.Diag("%v requires memory for source", p)

0 commit comments

Comments
 (0)