mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/loong64: change the immediate range of ALSL{W/WU/V}
When executing the alsl.w/wu/d family of instructions, the actual shift amount is the immediate value in the instruction encoding plus one. Therefore, this change is made to align the immediate value in the assembly code with the programmer's intended shift amount, and to include the result of the immediate value minus one in the final encoding. Change-Id: Ic82249251878eabde8372e183d841a03f963f9f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/693475 Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: abner chenc <chenguoqi@loongson.cn> Reviewed-by: sophie zhao <zhaoxiaolin@loongson.cn>
This commit is contained in:
parent
f3606b0825
commit
73ff6d1480
3 changed files with 30 additions and 5 deletions
|
|
@ -1101,6 +1101,6 @@ lable2:
|
||||||
XVBITREVV $63, X2, X1 // 41fc1977
|
XVBITREVV $63, X2, X1 // 41fc1977
|
||||||
|
|
||||||
// ALSL{W/WU/D}
|
// ALSL{W/WU/D}
|
||||||
ALSLW $3, R4, R5, R6 // 86940500
|
ALSLW $4, R4, R5, R6 // 86940500
|
||||||
ALSLWU $3, R4, R5, R6 // 86940700
|
ALSLWU $4, R4, R5, R6 // 86940700
|
||||||
ALSLV $3, R4, R5, R6 // 86942d00
|
ALSLV $4, R4, R5, R6 // 86942d00
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ var optab = []Optab{
|
||||||
{APRELD, C_SOREG, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0},
|
{APRELD, C_SOREG, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0},
|
||||||
{APRELDX, C_SOREG, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0},
|
{APRELDX, C_SOREG, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0},
|
||||||
|
|
||||||
{AALSLV, C_U2CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0},
|
{AALSLV, C_U3CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0},
|
||||||
|
|
||||||
{obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
|
{obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
|
||||||
{obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0},
|
{obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0},
|
||||||
|
|
@ -2742,8 +2742,12 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
|
o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
|
||||||
|
|
||||||
case 64: // alsl rd, rj, rk, sa2
|
case 64: // alsl rd, rj, rk, sa2
|
||||||
|
sa := p.From.Offset - 1
|
||||||
|
if sa > 3 {
|
||||||
|
c.ctxt.Diag("The shift amount is too large.")
|
||||||
|
}
|
||||||
r := p.GetFrom3().Reg
|
r := p.GetFrom3().Reg
|
||||||
o1 = OP_2IRRR(c.opirrr(p.As), uint32(p.From.Offset), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
|
o1 = OP_2IRRR(c.opirrr(p.As), uint32(sa), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
|
case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
|
||||||
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
|
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,27 @@ Note: In the following sections 3.1 to 3.6, "ui4" (4-bit unsigned int immediate)
|
||||||
bits[11:1]: block size, the value range is [16, 1024], and it must be an integer multiple of 16
|
bits[11:1]: block size, the value range is [16, 1024], and it must be an integer multiple of 16
|
||||||
bits[20:12]: block num, the value range is [1, 256]
|
bits[20:12]: block num, the value range is [1, 256]
|
||||||
bits[36:21]: stride, the value range is [0, 0xffff]
|
bits[36:21]: stride, the value range is [0, 0xffff]
|
||||||
|
|
||||||
|
4. ShiftAdd instructions
|
||||||
|
Mapping between Go and platform assembly:
|
||||||
|
Go assembly | platform assembly
|
||||||
|
ALSL.W/WU/V $Imm, Rj, Rk, Rd | alsl.w/wu/d rd, rj, rk, $imm
|
||||||
|
|
||||||
|
Instruction encoding format is as follows:
|
||||||
|
|
||||||
|
| 31 ~ 17 | 16 ~ 15 | 14 ~ 10 | 9 ~ 5 | 4 ~ 0 |
|
||||||
|
| opcode | sa2 | rk | rj | rd |
|
||||||
|
|
||||||
|
The alsl.w/wu/v series of instructions shift the data in rj left by sa+1, add the value
|
||||||
|
in rk, and write the result to rd.
|
||||||
|
|
||||||
|
To allow programmers to directly write the desired shift amount in assembly code, we actually write
|
||||||
|
the value of sa2+1 in the assembly code and then include the value of sa2 in the instruction encoding.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
Go assembly | instruction Encoding
|
||||||
|
ALSLV $4, r4, r5, R6 | 002d9486
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package loong64
|
package loong64
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue