]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: add support for op(extended register) with RSP arguments
authorfanzha02 <fannie.zhang@arm.com>
Wed, 20 Jan 2021 09:58:21 +0000 (17:58 +0800)
committerfannie zhang <Fannie.Zhang@arm.com>
Fri, 12 Mar 2021 01:47:01 +0000 (01:47 +0000)
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>
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/asm/internal/asm/testdata/arm64error.s
src/cmd/internal/obj/arm64/asm7.go

index 8635708320875d987f40f303f618315e1c32cdde..d859171103dafacc0ca9e32516dce1f780ae9422 100644 (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
index 1c8eaa17524635bc375e642a75039a096db3884e..64bade2051246fd0afc1ffe9aa0190bef5ce8a1e 100644 (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
index e9f18e1bf0344a545811d0828005fa891895df30..275799aad32963fc4c4d16730e51096620660624 100644 (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
                }
        }