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:
parent
71a6c13164
commit
a607408403
10
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
10
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user