]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: implement full operand support for l*arx instructions
authorCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Wed, 10 Jan 2018 17:29:50 +0000 (15:29 -0200)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Tue, 13 Mar 2018 19:46:54 +0000 (19:46 +0000)
The current implementation of l*arx instructions does not accept non-zero
offsets in RA nor the EH field. This change adds full functionality to those
instructions.

Updates #23845

Change-Id: If113f70d11de5f35f8389520b049390dbc40e863
Reviewed-on: https://go-review.googlesource.com/99635
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/asm/internal/asm/testdata/ppc64enc.s
src/cmd/internal/obj/ppc64/a.out.go
src/cmd/internal/obj/ppc64/anames.go
src/cmd/internal/obj/ppc64/asm9.go

index e34671231fcb2e6a2fab85788157a03237087d34..c6150573fc37b6a8c761532571a2049a4680f27c 100644 (file)
@@ -1199,6 +1199,26 @@ label1:
        CALL    foo(SB)
        RET     foo(SB)
 
+// load-and-reserve
+//     L*AR (RB)(RA*1),EH,RT produces
+//     l*arx RT,RA,RB,EH
+//
+//     Extended forms also accepted. Assumes RA=0, EH=0:
+//     L*AR (RB),RT
+//     L*AR (RB),EH,RT
+       LBAR (R4)(R3*1), $1, R5
+       LBAR (R4), $0, R5
+       LBAR (R3), R5
+       LHAR (R4)(R3*1), $1, R5
+       LHAR (R4), $0, R5
+       LHAR (R3), R5
+       LWAR (R4)(R3*1), $1, R5
+       LWAR (R4), $0, R5
+       LWAR (R3), R5
+       LDAR (R4)(R3*1), $1, R5
+       LDAR (R4), $0, R5
+       LDAR (R3), R5
+
 // END
 //
 //     LEND    comma // asm doesn't support the trailing comma.
index f39c0728eb5a0141cd3774a688f5c973862a068f..7ab1a578f867261dd3f5deec6bf2179a46128160 100644 (file)
@@ -84,4 +84,18 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        XOR $1234567, R5                // 641f001263ffd6877fe52a78
        XOR $1234567, R5, R3            // 641f001263ffd6877fe32a78
 
+       // load-and-reserve
+       LBAR (R4)(R3*1),$1,R5           // 7ca32069
+       LBAR (R4),$0,R5                 // 7ca02068
+       LBAR (R3),R5                    // 7ca01868
+       LHAR (R4)(R3*1),$1,R5           // 7ca320e9
+       LHAR (R4),$0,R5                 // 7ca020e8
+       LHAR (R3),R5                    // 7ca018e8
+       LWAR (R4)(R3*1),$1,R5           // 7ca32029
+       LWAR (R4),$0,R5                 // 7ca02028
+       LWAR (R3),R5                    // 7ca01828
+       LDAR (R4)(R3*1),$1,R5           // 7ca320a9
+       LDAR (R4),$0,R5                 // 7ca020a8
+       LDAR (R3),R5                    // 7ca018a8
+
        RET
index 16a959d62a713a841d465552a4f791ce396c8831..55e544209d58183d26728435483e0189d1691143 100644 (file)
@@ -519,6 +519,7 @@ const (
        AISEL
        AMOVMW
        ALBAR
+       ALHAR
        ALSW
        ALWAR
        ALWSYNC
index 28bbd4248f6a6cd2ef9ca530417bd606a6befbef..bfbb544d09451d1413fe232d06ea560d71351e22 100644 (file)
@@ -126,6 +126,7 @@ var Anames = []string{
        "ISEL",
        "MOVMW",
        "LBAR",
+       "LHAR",
        "LSW",
        "LWAR",
        "LWSYNC",
index 11c43ec2e502b3db20f04f5bfc591a1e0339283a..92365e917861d06a18b390c17771b29f7cb5e7ec 100644 (file)
@@ -581,6 +581,8 @@ var optab = []Optab{
        {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
        {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
        {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
+       {ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
+       {ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
        {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
        {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
        {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
@@ -1791,10 +1793,10 @@ func buildop(ctxt *obj.Link) {
                        opset(AFMOVS, r0)
                        opset(AFMOVSU, r0)
 
-               case AECIWX:
+               case ALDAR:
                        opset(ALBAR, r0)
+                       opset(ALHAR, r0)
                        opset(ALWAR, r0)
-                       opset(ALDAR, r0)
 
                case ASYSCALL: /* just the op; flow of control */
                        opset(ARFI, r0)
@@ -1861,6 +1863,7 @@ func buildop(ctxt *obj.Link) {
                        AVMSUMUDM,
                        AADDEX,
                        ACMPEQB,
+                       AECIWX,
                        obj.ANOP,
                        obj.ATEXT,
                        obj.AUNDEF,
@@ -1993,6 +1996,11 @@ func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
        return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
 }
 
+/* X-form, 3-register operands + EH field */
+func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
+       return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
+}
+
 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
        return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
 }
@@ -2994,8 +3002,24 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
 
        case 45: /* indexed load */
-               o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
-
+               switch p.As {
+               /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
+               /* The EH field can be used as a lock acquire/release hint as follows: */
+               /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
+               /* 1 = Exclusive Access (lock acquire and release) */
+               case ALBAR, ALHAR, ALWAR, ALDAR:
+                       if p.From3Type() != obj.TYPE_NONE {
+                               eh := int(c.regoff(p.GetFrom3()))
+                               if eh > 1 {
+                                       c.ctxt.Diag("illegal EH field\n%v", p)
+                               }
+                               o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
+                       } else {
+                               o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
+                       }
+               default:
+                       o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
+               }
        case 46: /* plain op */
                o1 = c.oprrr(p.As)
 
@@ -4765,10 +4789,12 @@ func (c *ctxt9) oploadx(a obj.As) uint32 {
                return OPVCC(31, 310, 0, 0) /* eciwx */
        case ALBAR:
                return OPVCC(31, 52, 0, 0) /* lbarx */
+       case ALHAR:
+               return OPVCC(31, 116, 0, 0) /* lharx */
        case ALWAR:
                return OPVCC(31, 20, 0, 0) /* lwarx */
        case ALDAR:
-               return OPVCC(31, 84, 0, 0)
+               return OPVCC(31, 84, 0, 0) /* ldarx */
        case ALSW:
                return OPVCC(31, 533, 0, 0) /* lswx */
        case AMOVD: