mirror of
https://github.com/golang/go
synced 2024-11-20 00:44:45 -07:00
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 <laboger@linux.vnet.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
parent
ca9abbb731
commit
e1f8fe8dff
20
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
20
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
@ -1199,6 +1199,26 @@ label1:
|
|||||||
CALL foo(SB)
|
CALL foo(SB)
|
||||||
RET 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
|
// END
|
||||||
//
|
//
|
||||||
// LEND comma // asm doesn't support the trailing comma.
|
// LEND comma // asm doesn't support the trailing comma.
|
||||||
|
14
src/cmd/asm/internal/asm/testdata/ppc64enc.s
vendored
14
src/cmd/asm/internal/asm/testdata/ppc64enc.s
vendored
@ -84,4 +84,18 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
|||||||
XOR $1234567, R5 // 641f001263ffd6877fe52a78
|
XOR $1234567, R5 // 641f001263ffd6877fe52a78
|
||||||
XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78
|
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
|
RET
|
||||||
|
@ -519,6 +519,7 @@ const (
|
|||||||
AISEL
|
AISEL
|
||||||
AMOVMW
|
AMOVMW
|
||||||
ALBAR
|
ALBAR
|
||||||
|
ALHAR
|
||||||
ALSW
|
ALSW
|
||||||
ALWAR
|
ALWAR
|
||||||
ALWSYNC
|
ALWSYNC
|
||||||
|
@ -126,6 +126,7 @@ var Anames = []string{
|
|||||||
"ISEL",
|
"ISEL",
|
||||||
"MOVMW",
|
"MOVMW",
|
||||||
"LBAR",
|
"LBAR",
|
||||||
|
"LHAR",
|
||||||
"LSW",
|
"LSW",
|
||||||
"LWAR",
|
"LWAR",
|
||||||
"LWSYNC",
|
"LWSYNC",
|
||||||
|
@ -581,6 +581,8 @@ var optab = []Optab{
|
|||||||
{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
|
{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
|
||||||
{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 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},
|
{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},
|
{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_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
|
||||||
{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 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(AFMOVS, r0)
|
||||||
opset(AFMOVSU, r0)
|
opset(AFMOVSU, r0)
|
||||||
|
|
||||||
case AECIWX:
|
case ALDAR:
|
||||||
opset(ALBAR, r0)
|
opset(ALBAR, r0)
|
||||||
|
opset(ALHAR, r0)
|
||||||
opset(ALWAR, r0)
|
opset(ALWAR, r0)
|
||||||
opset(ALDAR, r0)
|
|
||||||
|
|
||||||
case ASYSCALL: /* just the op; flow of control */
|
case ASYSCALL: /* just the op; flow of control */
|
||||||
opset(ARFI, r0)
|
opset(ARFI, r0)
|
||||||
@ -1861,6 +1863,7 @@ func buildop(ctxt *obj.Link) {
|
|||||||
AVMSUMUDM,
|
AVMSUMUDM,
|
||||||
AADDEX,
|
AADDEX,
|
||||||
ACMPEQB,
|
ACMPEQB,
|
||||||
|
AECIWX,
|
||||||
obj.ANOP,
|
obj.ANOP,
|
||||||
obj.ATEXT,
|
obj.ATEXT,
|
||||||
obj.AUNDEF,
|
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
|
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 {
|
func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
|
||||||
return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
|
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))
|
o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 45: /* indexed load */
|
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 */
|
case 46: /* plain op */
|
||||||
o1 = c.oprrr(p.As)
|
o1 = c.oprrr(p.As)
|
||||||
|
|
||||||
@ -4765,10 +4789,12 @@ func (c *ctxt9) oploadx(a obj.As) uint32 {
|
|||||||
return OPVCC(31, 310, 0, 0) /* eciwx */
|
return OPVCC(31, 310, 0, 0) /* eciwx */
|
||||||
case ALBAR:
|
case ALBAR:
|
||||||
return OPVCC(31, 52, 0, 0) /* lbarx */
|
return OPVCC(31, 52, 0, 0) /* lbarx */
|
||||||
|
case ALHAR:
|
||||||
|
return OPVCC(31, 116, 0, 0) /* lharx */
|
||||||
case ALWAR:
|
case ALWAR:
|
||||||
return OPVCC(31, 20, 0, 0) /* lwarx */
|
return OPVCC(31, 20, 0, 0) /* lwarx */
|
||||||
case ALDAR:
|
case ALDAR:
|
||||||
return OPVCC(31, 84, 0, 0)
|
return OPVCC(31, 84, 0, 0) /* ldarx */
|
||||||
case ALSW:
|
case ALSW:
|
||||||
return OPVCC(31, 533, 0, 0) /* lswx */
|
return OPVCC(31, 533, 0, 0) /* lswx */
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
|
Loading…
Reference in New Issue
Block a user