]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: fix encoding of condition
authorWei Xiao <wei.xiao@arm.com>
Fri, 21 Apr 2017 07:59:07 +0000 (15:59 +0800)
committerCherry Zhang <cherryyz@google.com>
Thu, 27 Apr 2017 13:35:59 +0000 (13:35 +0000)
The current code treats condition as special register and write
its raw data directly into instruction.

The fix converts the raw data into correct condition encoding.
Also fix the operand catogery of FCCMP.

Add tests to cover all cases.

Change-Id: Ib194041bd9017dd0edbc241564fe983082ac616b
Reviewed-on: https://go-review.googlesource.com/41511
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/internal/obj/arm64/asm7.go

index 9dfcab5fba2c9e116fdf3193035b5ab11dc55984..734ed152b222b5d723766ef03716e29b06426673 100644 (file)
@@ -156,7 +156,7 @@ again:
 //     {
 //             outcode($1, &$2, NREG, &$4);
 //     }
-       CSET    GT, R1
+       CSET    GT, R1  // e1d79f9a
 //
 // CSEL/CSINC/CSNEG/CSINV
 //
@@ -164,16 +164,18 @@ again:
 //     {
 //             outgcode($1, &$2, $6.reg, &$4, &$8);
 //     }
-       CSEL    LT, R1, R2, ZR
-       CSINC   GT, R1, ZR, R3
-       CSNEG   MI, R1, R2, R3
-       CSINV   CS, R1, R2, R3 // CSINV HS, R1, R2, R3
+       CSEL    LT, R1, R2, ZR  // 3fb0829a
+       CSINC   GT, R1, ZR, R3  // 23c49f9a
+       CSNEG   MI, R1, R2, R3  // 234482da
+       CSINV   CS, R1, R2, R3  // CSINV HS, R1, R2, R3 // 232082da
 
 //             LTYPES cond ',' reg ',' reg
 //     {
 //             outcode($1, &$2, $4.reg, &$6);
 //     }
-       CSEL    LT, R1, R2
+       CINC    EQ, R4, R9      // 8914849a
+       CINV    PL, R11, R22    // 76418bda
+       CNEG    LS, R13, R7     // a7858dda
 //
 // CCMN
 //
@@ -181,7 +183,7 @@ again:
 //     {
 //             outgcode($1, &$2, $6.reg, &$4, &$8);
 //     }
-       CCMN    MI, ZR, R1, $4
+       CCMN    MI, ZR, R1, $4  // e44341ba
 
 //
 // FADDD
@@ -217,7 +219,7 @@ again:
 //     {
 //             outgcode($1, &$2, $6.reg, &$4, &$8);
 //     }
-//     FCCMP   LT, F1, F2, $1
+       FCCMPS  LT, F1, F2, $1  // 41b4211e
 
 //
 // FMULA
index b0510267fe824fa11660d059eb9c617fd76689ad..8218c6b333e4aacc04d0f2b5f74b3a81ceb0eec7 100644 (file)
@@ -495,7 +495,7 @@ var optab = []Optab{
        {AFMOVD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
        {AFCMPS, C_FREG, C_FREG, C_NONE, 56, 4, 0, 0, 0},
        {AFCMPS, C_FCON, C_FREG, C_NONE, 56, 4, 0, 0, 0},
-       {AFCCMPS, C_COND, C_REG, C_VCON, 57, 4, 0, 0, 0},
+       {AFCCMPS, C_COND, C_FREG, C_VCON, 57, 4, 0, 0, 0},
        {AFCSELD, C_COND, C_REG, C_FREG, 18, 4, 0, 0, 0},
        {AFCVTSD, C_FREG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
        {ACLREX, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0},
@@ -2224,6 +2224,12 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 = c.oprrr(p, p.As)
 
                cond := int(p.From.Reg)
+               if cond < COND_EQ || cond > COND_NV {
+                       c.ctxt.Diag("invalid condition\n%v", p)
+               } else {
+                       cond -= COND_EQ
+               }
+
                r := int(p.Reg)
                var rf int
                if r != 0 {
@@ -2246,12 +2252,17 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                }
 
                rt := int(p.To.Reg)
-               o1 |= (uint32(rf&31) << 16) | (uint32(cond&31) << 12) | (uint32(r&31) << 5) | uint32(rt&31)
+               o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(r&31) << 5) | uint32(rt&31)
 
        case 19: /* CCMN cond, (Rm|uimm5),Rn, uimm4 -> ccmn Rn,Rm,uimm4,cond */
                nzcv := int(p.To.Offset)
 
                cond := int(p.From.Reg)
+               if cond < COND_EQ || cond > COND_NV {
+                       c.ctxt.Diag("invalid condition\n%v", p)
+               } else {
+                       cond -= COND_EQ
+               }
                var rf int
                if p.From3.Type == obj.TYPE_REG {
                        o1 = c.oprrr(p, p.As)
@@ -2261,7 +2272,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        rf = int(p.From3.Offset & 0x1F)
                }
 
-               o1 |= (uint32(rf&31) << 16) | (uint32(cond) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
+               o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
 
        case 20: /* movT R,O(R) -> strT */
                v := int32(c.regoff(&p.To))
@@ -2794,6 +2805,12 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 = c.oprrr(p, p.As)
 
                cond := int(p.From.Reg)
+               if cond < COND_EQ || cond > COND_NV {
+                       c.ctxt.Diag("invalid condition\n%v", p)
+               } else {
+                       cond -= COND_EQ
+               }
+
                nzcv := int(p.To.Offset)
                if nzcv&^0xF != 0 {
                        c.ctxt.Diag("implausible condition\n%v", p)
@@ -2804,7 +2821,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        break
                }
                rt := int(p.From3.Reg)
-               o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
+               o1 |= uint32(rf&31)<<16 | uint32(cond&15)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
 
        case 58: /* ldar/ldxr/ldaxr */
                o1 = c.opload(p, p.As)