Skip to content

Commit e1f8fe8

Browse files
ceseolaboger
authored andcommitted
cmd/internal/obj/ppc64: implement full operand support for l*arx instructions
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Lynn Boger <[email protected]>
1 parent ca9abbb commit e1f8fe8

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

src/cmd/asm/internal/asm/testdata/ppc64.s

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,26 @@ label1:
11991199
CALL foo(SB)
12001200
RET foo(SB)
12011201

1202+
// load-and-reserve
1203+
// L*AR (RB)(RA*1),EH,RT produces
1204+
// l*arx RT,RA,RB,EH
1205+
//
1206+
// Extended forms also accepted. Assumes RA=0, EH=0:
1207+
// L*AR (RB),RT
1208+
// L*AR (RB),EH,RT
1209+
LBAR (R4)(R3*1), $1, R5
1210+
LBAR (R4), $0, R5
1211+
LBAR (R3), R5
1212+
LHAR (R4)(R3*1), $1, R5
1213+
LHAR (R4), $0, R5
1214+
LHAR (R3), R5
1215+
LWAR (R4)(R3*1), $1, R5
1216+
LWAR (R4), $0, R5
1217+
LWAR (R3), R5
1218+
LDAR (R4)(R3*1), $1, R5
1219+
LDAR (R4), $0, R5
1220+
LDAR (R3), R5
1221+
12021222
// END
12031223
//
12041224
// LEND comma // asm doesn't support the trailing comma.

src/cmd/asm/internal/asm/testdata/ppc64enc.s

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,18 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
8484
XOR $1234567, R5 // 641f001263ffd6877fe52a78
8585
XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78
8686

87+
// load-and-reserve
88+
LBAR (R4)(R3*1),$1,R5 // 7ca32069
89+
LBAR (R4),$0,R5 // 7ca02068
90+
LBAR (R3),R5 // 7ca01868
91+
LHAR (R4)(R3*1),$1,R5 // 7ca320e9
92+
LHAR (R4),$0,R5 // 7ca020e8
93+
LHAR (R3),R5 // 7ca018e8
94+
LWAR (R4)(R3*1),$1,R5 // 7ca32029
95+
LWAR (R4),$0,R5 // 7ca02028
96+
LWAR (R3),R5 // 7ca01828
97+
LDAR (R4)(R3*1),$1,R5 // 7ca320a9
98+
LDAR (R4),$0,R5 // 7ca020a8
99+
LDAR (R3),R5 // 7ca018a8
100+
87101
RET

src/cmd/internal/obj/ppc64/a.out.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ const (
519519
AISEL
520520
AMOVMW
521521
ALBAR
522+
ALHAR
522523
ALSW
523524
ALWAR
524525
ALWSYNC

src/cmd/internal/obj/ppc64/anames.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ var Anames = []string{
126126
"ISEL",
127127
"MOVMW",
128128
"LBAR",
129+
"LHAR",
129130
"LSW",
130131
"LWAR",
131132
"LWSYNC",

src/cmd/internal/obj/ppc64/asm9.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,8 @@ var optab = []Optab{
581581
{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
582582
{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
583583
{AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
584+
{ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
585+
{ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
584586
{AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
585587
{ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
586588
{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
@@ -1791,10 +1793,10 @@ func buildop(ctxt *obj.Link) {
17911793
opset(AFMOVS, r0)
17921794
opset(AFMOVSU, r0)
17931795

1794-
case AECIWX:
1796+
case ALDAR:
17951797
opset(ALBAR, r0)
1798+
opset(ALHAR, r0)
17961799
opset(ALWAR, r0)
1797-
opset(ALDAR, r0)
17981800

17991801
case ASYSCALL: /* just the op; flow of control */
18001802
opset(ARFI, r0)
@@ -1861,6 +1863,7 @@ func buildop(ctxt *obj.Link) {
18611863
AVMSUMUDM,
18621864
AADDEX,
18631865
ACMPEQB,
1866+
AECIWX,
18641867
obj.ANOP,
18651868
obj.ATEXT,
18661869
obj.AUNDEF,
@@ -1993,6 +1996,11 @@ func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
19931996
return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
19941997
}
19951998

1999+
/* X-form, 3-register operands + EH field */
2000+
func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2001+
return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2002+
}
2003+
19962004
func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
19972005
return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
19982006
}
@@ -2994,8 +3002,24 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
29943002
o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
29953003

29963004
case 45: /* indexed load */
2997-
o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
2998-
3005+
switch p.As {
3006+
/* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3007+
/* The EH field can be used as a lock acquire/release hint as follows: */
3008+
/* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3009+
/* 1 = Exclusive Access (lock acquire and release) */
3010+
case ALBAR, ALHAR, ALWAR, ALDAR:
3011+
if p.From3Type() != obj.TYPE_NONE {
3012+
eh := int(c.regoff(p.GetFrom3()))
3013+
if eh > 1 {
3014+
c.ctxt.Diag("illegal EH field\n%v", p)
3015+
}
3016+
o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3017+
} else {
3018+
o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3019+
}
3020+
default:
3021+
o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3022+
}
29993023
case 46: /* plain op */
30003024
o1 = c.oprrr(p.As)
30013025

@@ -4765,10 +4789,12 @@ func (c *ctxt9) oploadx(a obj.As) uint32 {
47654789
return OPVCC(31, 310, 0, 0) /* eciwx */
47664790
case ALBAR:
47674791
return OPVCC(31, 52, 0, 0) /* lbarx */
4792+
case ALHAR:
4793+
return OPVCC(31, 116, 0, 0) /* lharx */
47684794
case ALWAR:
47694795
return OPVCC(31, 20, 0, 0) /* lwarx */
47704796
case ALDAR:
4771-
return OPVCC(31, 84, 0, 0)
4797+
return OPVCC(31, 84, 0, 0) /* ldarx */
47724798
case ALSW:
47734799
return OPVCC(31, 533, 0, 0) /* lswx */
47744800
case AMOVD:

0 commit comments

Comments
 (0)