1
0
mirror of https://github.com/golang/go synced 2024-11-26 05:48:05 -07:00

cmd/internal/obj/arm64: add support for op(extended register) with RSP arguments

Refer to ARM reference manual, like add(extended register) instructions,
the extension is encoded in the "option" field. If "Rd" or "Rn" is
RSP and "option" is "010" then LSL is preferred. Therefore, the instrution
"add Rm<<imm, RSP, RSP" or "add Rm<<imm RSP" is valid and can be encoded
as add(extended register) instruction.

But the current assembler can not handle like "op R1<<1, RSP, RSP"
instructions, this patch adds the support.

Because MVN(extended register) does not exist, remove it.

Add test cases.

Change-Id: I968749d75c6b93a4f297b39c73cc292e6b1035ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/284900
Trust: fannie zhang <Fannie.Zhang@arm.com>
Run-TryBot: fannie zhang <Fannie.Zhang@arm.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
fanzha02 2021-01-20 17:58:21 +08:00 committed by fannie zhang
parent 71a6c13164
commit a607408403
3 changed files with 54 additions and 5 deletions

View File

@ -64,6 +64,16 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
CMN R1.SXTX<<2, R10 // 5fe921ab
CMPW R2.UXTH<<3, R11 // 7f2d226b
CMNW R1.SXTB, R9 // 3f81212b
ADD R1<<1, RSP, R3 // e367218b
ADDW R1<<2, R3, RSP // 7f48210b
SUB R1<<3, RSP // ff6f21cb
SUBS R1<<4, RSP, R3 // e37321eb
ADDS R1<<1, RSP, R4 // e46721ab
CMP R1<<2, RSP // ff6b21eb
CMN R1<<3, RSP // ff6f21ab
ADDS R1<<1, ZR, R4 // e40701ab
ADD R3<<50, ZR, ZR // ffcb038b
CMP R4<<24, ZR // ff6304eb
CMPW $0x60060, R2 // CMPW $393312, R2 // 1b0c8052db00a0725f001b6b
CMPW $40960, R0 // 1f284071
CMPW $27745, R2 // 3b8c8d525f001b6b

View File

@ -368,4 +368,7 @@ TEXT errors(SB),$0
CASPD (R2, R3), (R2), (R9, R10) // ERROR "destination register pair must start from even register"
CASPD (R2, R4), (R2), (R8, R9) // ERROR "source register pair must be contiguous"
CASPD (R2, R3), (R2), (R8, R10) // ERROR "destination register pair must be contiguous"
ADD R1>>2, RSP, R3 // ERROR "illegal combination"
ADDS R2<<3, R3, RSP // ERROR "unexpected SP reference"
CMP R1<<5, RSP // ERROR "the left shift amount out of range 0 to 4"
RET

View File

@ -321,15 +321,17 @@ var optab = []Optab{
{ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
{AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
{AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
{AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 107, 4, 0, 0, 0},
{AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 107, 4, 0, 0, 0},
{AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
{ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
{ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 107, 4, 0, 0, 0},
{ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 26, 4, 0, 0, 0},
{AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
{AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{AMVN, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
{ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
{AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
{AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
@ -5458,6 +5460,41 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
c.ctxt.Diag("illegal destination register: %v\n", p)
}
o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
case 107: // op R<<n, RSP, RSP (extended register)
// Refer to ARM reference manual, if "Rd" or "Rn" is RSP,
// it can be encoded as op(extended regster) instruction.
if !(p.To.Reg == REGSP || p.Reg == REGSP) {
c.ctxt.Diag("expected SP reference: %v", p)
break
}
if p.To.Reg == REGSP && (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) {
c.ctxt.Diag("unexpected SP reference: %v", p)
break
}
amount := (p.From.Offset >> 10) & 63
shift := (p.From.Offset >> 22) & 3
if shift != 0 {
c.ctxt.Diag("illegal combination: %v", p)
break
}
if amount > 4 {
c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p)
break
}
rf := (p.From.Offset >> 16) & 31
rt := int(p.To.Reg)
r := int(p.Reg)
if p.To.Type == obj.TYPE_NONE {
rt = REGZERO
}
if r == 0 {
r = rt
}
o1 = c.opxrrr(p, p.As, false)
o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31)
}
out[0] = o1
out[1] = o2
@ -6394,11 +6431,10 @@ func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 {
extension := uint32(0)
if !extend {
switch a {
case AADD, ACMN, AADDS, ASUB, ACMP, ASUBS:
if isADDop(a) {
extension = LSL0_64
case AADDW, ACMNW, AADDSW, ASUBW, ACMPW, ASUBSW:
}
if isADDWop(a) {
extension = LSL0_32
}
}