aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/asm/internal/asm/operand_test.go2
-rw-r--r--src/cmd/asm/internal/asm/parse.go11
-rw-r--r--src/cmd/asm/internal/asm/testdata/ppc64.s171
-rw-r--r--src/cmd/internal/obj/ppc64/a.out.go3
-rw-r--r--src/cmd/internal/obj/ppc64/anames9.go1
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go147
-rw-r--r--src/cmd/internal/obj/ppc64/asm_test.go1
7 files changed, 268 insertions, 68 deletions
diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go
index b47c7e10a5..29371d6199 100644
--- a/src/cmd/asm/internal/asm/operand_test.go
+++ b/src/cmd/asm/internal/asm/operand_test.go
@@ -473,7 +473,7 @@ var ppc64OperandTests = []operandTest{
{"(R4)", "(R4)"},
{"(R5)", "(R5)"},
{"(R5)(R6*1)", "(R5)(R6*1)"},
- {"(R5+R6)", "(R5)(R6*1)"}, // Old syntax.
+ {"(R5+R6)", "(R5)(R6)"},
{"-1(R4)", "-1(R4)"},
{"-1(R5)", "-1(R5)"},
{"6(PC)", "6(PC)"},
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index 6445e01bde..b42178798e 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -975,13 +975,13 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
return
}
if p.arch.Family == sys.PPC64 {
- // Special form for PPC64: (R1+R2); alias for (R1)(R2*1).
+ // Special form for PPC64: (R1+R2); alias for (R1)(R2).
if prefix != 0 || scale != 0 {
p.errorf("illegal address mode for register+register")
return
}
a.Type = obj.TYPE_MEM
- a.Scale = 1
+ a.Scale = 0
a.Index = r2
// Nothing may follow.
return
@@ -1014,9 +1014,12 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
p.errorf("unimplemented two-register form")
}
a.Index = r1
- if scale != 0 && scale != 1 && p.arch.Family == sys.ARM64 {
+ if scale != 0 && scale != 1 && (p.arch.Family == sys.ARM64 ||
+ p.arch.Family == sys.PPC64) {
// Support (R1)(R2) (no scaling) and (R1)(R2*1).
- p.errorf("arm64 doesn't support scaled register format")
+ if p.arch.Family != sys.PPC64 {
+ p.errorf("%s doesn't support scaled register format", p.arch.Name)
+ }
} else {
a.Scale = int16(scale)
}
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s
index f307db30da..8f03a3afa6 100644
--- a/src/cmd/asm/internal/asm/testdata/ppc64.s
+++ b/src/cmd/asm/internal/asm/testdata/ppc64.s
@@ -8,6 +8,10 @@
#include "../../../../../runtime/textflag.h"
+// In case of index mode instructions, usage of
+// (Rx)(R0) is equivalent to (Rx+R0)
+// In case of base+displacement mode instructions if
+// the offset is 0, usage of (Rx) is equivalent to 0(Rx)
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
// move constants
MOVD $1, R3 // 38600001
@@ -26,58 +30,113 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVW $1234567, R5 // 6405001260a5d687
MOVD 8(R3), R4 // e8830008
MOVD (R3)(R4), R5 // 7ca4182a
+ MOVD (R3)(R0), R5 // 7ca0182a
+ MOVD (R3), R5 // e8a30000
MOVW 4(R3), R4 // e8830006
MOVW (R3)(R4), R5 // 7ca41aaa
+ MOVW (R3)(R0), R5 // 7ca01aaa
+ MOVW (R3), R5 // e8a30002
MOVWZ 4(R3), R4 // 80830004
MOVWZ (R3)(R4), R5 // 7ca4182e
+ MOVWZ (R3)(R0), R5 // 7ca0182e
+ MOVWZ (R3), R5 // 80a30000
MOVH 4(R3), R4 // a8830004
MOVH (R3)(R4), R5 // 7ca41aae
+ MOVH (R3)(R0), R5 // 7ca01aae
+ MOVH (R3), R5 // a8a30000
+
MOVHZ 2(R3), R4 // a0830002
MOVHZ (R3)(R4), R5 // 7ca41a2e
+ MOVHZ (R3)(R0), R5 // 7ca01a2e
+ MOVHZ (R3), R5 // a0a30000
MOVB 1(R3), R4 // 888300017c840774
MOVB (R3)(R4), R5 // 7ca418ae7ca50774
+ MOVB (R3)(R0), R5 // 7ca018ae7ca50774
+ MOVB (R3), R5 // 88a300007ca50774
MOVBZ 1(R3), R4 // 88830001
MOVBZ (R3)(R4), R5 // 7ca418ae
+ MOVBZ (R3)(R0), R5 // 7ca018ae
+ MOVBZ (R3), R5 // 88a30000
MOVDBR (R3)(R4), R5 // 7ca41c28
+ MOVDBR (R3)(R0), R5 // 7ca01c28
+ MOVDBR (R3), R5 // 7ca01c28
MOVWBR (R3)(R4), R5 // 7ca41c2c
+ MOVWBR (R3)(R0), R5 // 7ca01c2c
+ MOVWBR (R3), R5 // 7ca01c2c
MOVHBR (R3)(R4), R5 // 7ca41e2c
+ MOVHBR (R3)(R0), R5 // 7ca01e2c
+ MOVHBR (R3), R5 // 7ca01e2c
MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40
MOVD $foo(SB), R5 // 3ca0000038a50000
MOVDU 8(R3), R4 // e8830009
MOVDU (R3)(R4), R5 // 7ca4186a
+ MOVDU (R3)(R0), R5 // 7ca0186a
+ MOVDU (R3), R5 // e8a30001
MOVWU (R3)(R4), R5 // 7ca41aea
+ MOVWU (R3)(R0), R5 // 7ca01aea
MOVWZU 4(R3), R4 // 84830004
MOVWZU (R3)(R4), R5 // 7ca4186e
+ MOVWZU (R3)(R0), R5 // 7ca0186e
+ MOVWZU (R3), R5 // 84a30000
MOVHU 2(R3), R4 // ac830002
MOVHU (R3)(R4), R5 // 7ca41aee
+ MOVHU (R3)(R0), R5 // 7ca01aee
+ MOVHU (R3), R5 // aca30000
MOVHZU 2(R3), R4 // a4830002
MOVHZU (R3)(R4), R5 // 7ca41a6e
+ MOVHZU (R3)(R0), R5 // 7ca01a6e
+ MOVHZU (R3), R5 // a4a30000
MOVBU 1(R3), R4 // 8c8300017c840774
MOVBU (R3)(R4), R5 // 7ca418ee7ca50774
+ MOVBU (R3)(R0), R5 // 7ca018ee7ca50774
+ MOVBU (R3), R5 // 8ca300007ca50774
MOVBZU 1(R3), R4 // 8c830001
MOVBZU (R3)(R4), R5 // 7ca418ee
+ MOVBZU (R3)(R0), R5 // 7ca018ee
+ MOVBZU (R3), R5 // 8ca30000
MOVD R4, 8(R3) // f8830008
MOVD R5, (R3)(R4) // 7ca4192a
+ MOVD R5, (R3)(R0) // 7ca0192a
+ MOVD R5, (R3) // f8a30000
MOVW R4, 4(R3) // 90830004
MOVW R5, (R3)(R4) // 7ca4192e
+ MOVW R5, (R3)(R0) // 7ca0192e
+ MOVW R5, (R3) // 90a30000
MOVH R4, 2(R3) // b0830002
MOVH R5, (R3)(R4) // 7ca41b2e
+ MOVH R5, (R3)(R0) // 7ca01b2e
+ MOVH R5, (R3) // b0a30000
MOVB R4, 1(R3) // 98830001
MOVB R5, (R3)(R4) // 7ca419ae
+ MOVB R5, (R3)(R0) // 7ca019ae
+ MOVB R5, (R3) // 98a30000
MOVDBR R5, (R3)(R4) // 7ca41d28
+ MOVDBR R5, (R3)(R0) // 7ca01d28
+ MOVDBR R5, (R3) // 7ca01d28
MOVWBR R5, (R3)(R4) // 7ca41d2c
+ MOVWBR R5, (R3)(R0) // 7ca01d2c
+ MOVWBR R5, (R3) // 7ca01d2c
MOVHBR R5, (R3)(R4) // 7ca41f2c
+ MOVHBR R5, (R3)(R0) // 7ca01f2c
+ MOVHBR R5, (R3) // 7ca01f2c
MOVDU R4, 8(R3) // f8830009
MOVDU R5, (R3)(R4) // 7ca4196a
+ MOVDU R5, (R3)(R0) // 7ca0196a
+ MOVDU R5, (R3) // f8a30001
MOVWU R4, 4(R3) // 94830004
MOVWU R5, (R3)(R4) // 7ca4196e
+ MOVWU R5, (R3)(R0) // 7ca0196e
MOVHU R4, 2(R3) // b4830002
MOVHU R5, (R3)(R4) // 7ca41b6e
+ MOVHU R5, (R3)(R0) // 7ca01b6e
+ MOVHU R5, (R3) // b4a30000
MOVBU R4, 1(R3) // 9c830001
MOVBU R5, (R3)(R4) // 7ca419ee
+ MOVBU R5, (R3)(R0) // 7ca019ee
+ MOVBU R5, (R3) // 9ca30000
MOVB $0, R4 // 38800000
MOVBZ $0, R4 // 38800000
@@ -372,23 +431,41 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
// load-and-reserve
LBAR (R4)(R3*1),$1,R5 // 7ca32069
+ LBAR (R4)(R0),$1,R5 // 7ca02069
LBAR (R4),$0,R5 // 7ca02068
LBAR (R3),R5 // 7ca01868
LHAR (R4)(R3*1),$1,R5 // 7ca320e9
+ LHAR (R4)(R0),$1,R5 // 7ca020e9
LHAR (R4),$0,R5 // 7ca020e8
LHAR (R3),R5 // 7ca018e8
LWAR (R4)(R3*1),$1,R5 // 7ca32029
+ LWAR (R4)(R0),$1,R5 // 7ca02029
LWAR (R4),$0,R5 // 7ca02028
LWAR (R3),R5 // 7ca01828
LDAR (R4)(R3*1),$1,R5 // 7ca320a9
+ LDAR (R4)(R0),$1,R5 // 7ca020a9
LDAR (R4),$0,R5 // 7ca020a8
LDAR (R3),R5 // 7ca018a8
+ LSW (R3)(R4), R5 // 7ca41c2a
+ LSW (R3)(R0), R5 // 7ca01c2a
+ LSW (R3), R5 // 7ca01c2a
+
STBCCC R3, (R4)(R5) // 7c65256d
+ STBCCC R3, (R4)(R0) // 7c60256d
+ STBCCC R3, (R4) // 7c60256d
STWCCC R3, (R4)(R5) // 7c65212d
+ STWCCC R3, (R4)(R0) // 7c60212d
+ STWCCC R3, (R4) // 7c60212d
STDCCC R3, (R4)(R5) // 7c6521ad
- STHCCC R3, (R4)(R5)
- STSW R3, (R4)(R5)
+ STDCCC R3, (R4)(R0) // 7c6021ad
+ STDCCC R3, (R4) // 7c6021ad
+ STHCCC R3, (R4)(R5) // 7c6525ad
+ STHCCC R3, (R4)(R0) // 7c6025ad
+ STHCCC R3, (R4) // 7c6025ad
+ STSW R3, (R4)(R5) // 7c65252a
+ STSW R3, (R4)(R0) // 7c60252a
+ STSW R3, (R4) // 7c60252a
SYNC // 7c0004ac
ISYNC // 4c00012c
@@ -397,11 +474,21 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
DARN $1, R5 // 7ca105e6
DCBF (R3)(R4) // 7c0418ac
- DCBI (R3)(R4) // 7c041bac
+ DCBF (R3)(R0) // 7c0018ac
+ DCBF (R3) // 7c0018ac
+
DCBST (R3)(R4) // 7c04186c
+ DCBST (R3)(R0) // 7c00186c
+ DCBST (R3) // 7c00186c
DCBZ (R3)(R4) // 7c041fec
+ DCBZ (R3)(R0) // 7c001fec
+ DCBZ (R3) // 7c001fec
DCBT (R3)(R4) // 7c041a2c
+ DCBT (R3)(R0) // 7c001a2c
+ DCBT (R3) // 7c001a2c
ICBI (R3)(R4) // 7c041fac
+ ICBI (R3)(R0) // 7c001fac
+ ICBI (R3) // 7c001fac
// float constants
FMOVD $(0.0), F1 // f0210cd0
@@ -409,21 +496,46 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
FMOVD 8(R3), F1 // c8230008
FMOVD (R3)(R4), F1 // 7c241cae
+ FMOVD (R3)(R0), F1 // 7c201cae
+ FMOVD (R3), F1 // c8230000
FMOVDU 8(R3), F1 // cc230008
FMOVDU (R3)(R4), F1 // 7c241cee
+ FMOVDU (R3)(R0), F1 // 7c201cee
+ FMOVDU (R3), F1 // cc230000
FMOVS 4(R3), F1 // c0230004
FMOVS (R3)(R4), F1 // 7c241c2e
+ FMOVS (R3)(R0), F1 // 7c201c2e
+ FMOVS (R3), F1 // c0230000
FMOVSU 4(R3), F1 // c4230004
FMOVSU (R3)(R4), F1 // 7c241c6e
+ FMOVSU (R3)(R0), F1 // 7c201c6e
+ FMOVSU (R3), F1 // c4230000
+ FMOVSX (R3)(R4), F1 // 7c241eae
+ FMOVSX (R3)(R0), F1 // 7c201eae
+ FMOVSX (R3), F1 // 7c201eae
+ FMOVSZ (R3)(R4), F1 // 7c241eee
+ FMOVSZ (R3)(R0), F1 // 7c201eee
+ FMOVSZ (R3), F1 // 7c201eee
FMOVD F1, 8(R3) // d8230008
FMOVD F1, (R3)(R4) // 7c241dae
+ FMOVD F1, (R3)(R0) // 7c201dae
+ FMOVD F1, (R3) // d8230000
FMOVDU F1, 8(R3) // dc230008
FMOVDU F1, (R3)(R4) // 7c241dee
+ FMOVDU F1, (R3)(R0) // 7c201dee
+ FMOVDU F1, (R3) // dc230000
FMOVS F1, 4(R3) // d0230004
FMOVS F1, (R3)(R4) // 7c241d2e
+ FMOVS F1, (R3)(R0) // 7c201d2e
+ FMOVS F1, (R3) // d0230000
FMOVSU F1, 4(R3) // d4230004
FMOVSU F1, (R3)(R4) // 7c241d6e
+ FMOVSU F1, (R3)(R0) // 7c201d6e
+ FMOVSU F1, (R3) // d4230000
+ FMOVSX F1, (R3)(R4) // 7c241fae
+ FMOVSX F1, (R3)(R0) // 7c201fae
+ FMOVSX F1, (R3) // 7c201fae
FADD F1, F2 // fc42082a
FADD F1, F2, F3 // fc62082a
FADDCC F1, F2, F3 // fc62082b
@@ -507,17 +619,41 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
FCMPO F1, F2 // fc011040
FCMPU F1, F2 // fc011000
LVX (R3)(R4), V1 // 7c2418ce
+ LVX (R3)(R0), V1 // 7c2018ce
+ LVX (R3), V1 // 7c2018ce
LVXL (R3)(R4), V1 // 7c241ace
+ LVXL (R3)(R0), V1 // 7c201ace
+ LVXL (R3), V1 // 7c201ace
LVSL (R3)(R4), V1 // 7c24180c
+ LVSL (R3)(R0), V1 // 7c20180c
+ LVSL (R3), V1 // 7c20180c
LVSR (R3)(R4), V1 // 7c24184c
+ LVSR (R3)(R0), V1 // 7c20184c
+ LVSR (R3), V1 // 7c20184c
LVEBX (R3)(R4), V1 // 7c24180e
+ LVEBX (R3)(R0), V1 // 7c20180e
+ LVEBX (R3), V1 // 7c20180e
LVEHX (R3)(R4), V1 // 7c24184e
+ LVEHX (R3)(R0), V1 // 7c20184e
+ LVEHX (R3), V1 // 7c20184e
LVEWX (R3)(R4), V1 // 7c24188e
+ LVEWX (R3)(R0), V1 // 7c20188e
+ LVEWX (R3), V1 // 7c20188e
STVX V1, (R3)(R4) // 7c2419ce
+ STVX V1, (R3)(R0) // 7c2019ce
+ STVX V1, (R3) // 7c2019ce
STVXL V1, (R3)(R4) // 7c241bce
+ STVXL V1, (R3)(R0) // 7c201bce
+ STVXL V1, (R3) // 7c201bce
STVEBX V1, (R3)(R4) // 7c24190e
+ STVEBX V1, (R3)(R0) // 7c20190e
+ STVEBX V1, (R3) // 7c20190e
STVEHX V1, (R3)(R4) // 7c24194e
+ STVEHX V1, (R3)(R0) // 7c20194e
+ STVEHX V1, (R3) // 7c20194e
STVEWX V1, (R3)(R4) // 7c24198e
+ STVEWX V1, (R3)(R0) // 7c20198e
+ STVEWX V1, (R3) // 7c20198e
VAND V1, V2, V3 // 10611404
VANDC V1, V2, V3 // 10611444
@@ -651,28 +787,55 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
VSHASIGMAD $2, V1, $15, V2 // 104196c2
LXVD2X (R3)(R4), VS1 // 7c241e98
+ LXVD2X (R3)(R0), VS1 // 7c201e98
+ LXVD2X (R3), VS1 // 7c201e98
LXVDSX (R3)(R4), VS1 // 7c241a98
+ LXVDSX (R3)(R0), VS1 // 7c201a98
+ LXVDSX (R3), VS1 // 7c201a98
LXVH8X (R3)(R4), VS1 // 7c241e58
+ LXVH8X (R3)(R0), VS1 // 7c201e58
+ LXVH8X (R3), VS1 // 7c201e58
LXVB16X (R3)(R4), VS1 // 7c241ed8
+ LXVB16X (R3)(R0), VS1 // 7c201ed8
+ LXVB16X (R3), VS1 // 7c201ed8
LXVW4X (R3)(R4), VS1 // 7c241e18
+ LXVW4X (R3)(R0), VS1 // 7c201e18
+ LXVW4X (R3), VS1 // 7c201e18
LXV 16(R3), VS1 // f4230011
+ LXV (R3), VS1 // f4230001
LXV 16(R3), VS33 // f4230019
+ LXV (R3), VS33 // f4230009
LXV 16(R3), V1 // f4230019
+ LXV (R3), V1 // f4230009
LXVL R3, R4, VS1 // 7c23221a
LXVLL R3, R4, VS1 // 7c23225a
LXVX R3, R4, VS1 // 7c232218
LXSDX (R3)(R4), VS1 // 7c241c98
+ LXSDX (R3)(R0), VS1 // 7c201c98
+ LXSDX (R3), VS1 // 7c201c98
STXVD2X VS1, (R3)(R4) // 7c241f98
+ STXVD2X VS1, (R3)(R0) // 7c201f98
+ STXVD2X VS1, (R3) // 7c201f98
STXV VS1,16(R3) // f4230015
+ STXV VS1,(R3) // f4230005
STXVL VS1, R3, R4 // 7c23231a
STXVLL VS1, R3, R4 // 7c23235a
STXVX VS1, R3, R4 // 7c232318
STXVB16X VS1, (R4)(R5) // 7c2527d8
+ STXVB16X VS1, (R4)(R0) // 7c2027d8
+ STXVB16X VS1, (R4) // 7c2027d8
STXVH8X VS1, (R4)(R5) // 7c252758
-
+ STXVH8X VS1, (R4)(R0) // 7c202758
+ STXVH8X VS1, (R4) // 7c202758
STXSDX VS1, (R3)(R4) // 7c241d98
+ STXSDX VS1, (R4)(R0) // 7c202598
+ STXSDX VS1, (R4) // 7c202598
LXSIWAX (R3)(R4), VS1 // 7c241898
+ LXSIWAX (R3)(R0), VS1 // 7c201898
+ LXSIWAX (R3), VS1 // 7c201898
STXSIWX VS1, (R3)(R4) // 7c241918
+ STXSIWX VS1, (R3)(R0) // 7c201918
+ STXSIWX VS1, (R3) // 7c201918
MFVSRD VS1, R3 // 7c230066
MTFPRD R3, F0 // 7c030166
MFVRD V0, R3 // 7c030067
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go
index 30eba4339a..6b6e498fd2 100644
--- a/src/cmd/internal/obj/ppc64/a.out.go
+++ b/src/cmd/internal/obj/ppc64/a.out.go
@@ -419,9 +419,10 @@ const (
C_SBRA /* A short offset argument to a branching instruction */
C_LBRA /* A long offset argument to a branching instruction */
C_LBRAPIC /* Like C_LBRA, but requires an extra NOP for potential TOC restore by the linker. */
- C_ZOREG /* An reg+reg memory arg, or a $0+reg memory op */
+ C_ZOREG /* An $0+reg memory op */
C_SOREG /* An $n+reg memory arg where n is a 16 bit signed offset */
C_LOREG /* An $n+reg memory arg where n is a 32 bit signed offset */
+ C_XOREG /* An reg+reg memory arg */
C_FPSCR /* The fpscr register */
C_XER /* The xer, holds the carry bit */
C_LR /* The link register */
diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go
index 05bfd944d1..c6cc923b80 100644
--- a/src/cmd/internal/obj/ppc64/anames9.go
+++ b/src/cmd/internal/obj/ppc64/anames9.go
@@ -39,6 +39,7 @@ var cnames9 = []string{
"ZOREG",
"SOREG",
"LOREG",
+ "XOREG",
"FPSCR",
"XER",
"LR",
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index 94ad7a173b..ecd108e117 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -197,28 +197,36 @@ var optab = []Optab{
{as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4},
{as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+ {as: AMOVBU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
+ {as: AMOVBU, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
{as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+ {as: AMOVBZU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+ {as: AMOVBZU, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
- {as: AMOVHBR, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
- {as: AMOVHBR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+ {as: AMOVHBR, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
+ {as: AMOVHBR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
{as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 75, size: 12},
{as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 36, size: 12},
{as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
+ {as: AMOVB, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+ {as: AMOVB, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4},
{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
{as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+ {as: AMOVBZ, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
{as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
{as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+ {as: AMOVBZ, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
{as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
@@ -229,6 +237,7 @@ var optab = []Optab{
{as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
{as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
{as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+ {as: AMOVD, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
{as: AMOVD, a1: C_SOREG, a6: C_SPR, type_: 107, size: 8},
{as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
{as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8},
@@ -236,6 +245,7 @@ var optab = []Optab{
{as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+ {as: AMOVD, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVD, a1: C_SPR, a6: C_SOREG, type_: 106, size: 8},
{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
@@ -251,28 +261,33 @@ var optab = []Optab{
{as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
{as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
{as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
+ {as: AMOVW, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
{as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
{as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
{as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+ {as: AMOVW, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
{as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
{as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4},
{as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
{as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
+ {as: AFMOVD, a1: C_XOREG, a6: C_FREG, type_: 109, size: 4},
{as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8},
{as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
{as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8},
{as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
{as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
+ {as: AFMOVD, a1: C_FREG, a6: C_XOREG, type_: 108, size: 4},
{as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8},
{as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8},
- {as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
- {as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4},
+ {as: AFMOVSX, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
+ {as: AFMOVSX, a1: C_FREG, a6: C_XOREG, type_: 44, size: 4},
{as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
+ {as: AFMOVSZ, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
{as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
{as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
@@ -325,7 +340,7 @@ var optab = []Optab{
{as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4}, /* floating test for sw square root, x-form */
{as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4}, /* copy/paste facility, x-form */
{as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4}, /* deliver random number, x-form */
- {as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */
+ {as: ALDMX, a1: C_XOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */
{as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */
{as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */
{as: ACRAND, a1: C_CRBIT, a2: C_CRBIT, a6: C_CRBIT, type_: 2, size: 4}, /* logical ops for condition register bits xl-form */
@@ -333,10 +348,10 @@ var optab = []Optab{
/* Vector instructions */
/* Vector load */
- {as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
+ {as: ALV, a1: C_XOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
/* Vector store */
- {as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */
+ {as: ASTV, a1: C_VREG, a6: C_XOREG, type_: 44, size: 4}, /* vector store, x-form */
/* Vector logical */
{as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
@@ -405,26 +420,26 @@ var optab = []Optab{
{as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
/* VSX vector load */
- {as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */
+ {as: ALXVD2X, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */
{as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4}, /* vsx vector load, dq-form */
{as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
/* VSX vector store */
- {as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */
+ {as: ASTXVD2X, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */
{as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4}, /* vsx vector store, dq-form */
{as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
/* VSX scalar load */
- {as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
+ {as: ALXSDX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
/* VSX scalar store */
- {as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
+ {as: ASTXSDX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
/* VSX scalar as integer load */
- {as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
+ {as: ALXSIWAX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
/* VSX scalar store as integer */
- {as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
+ {as: ASTXSIWX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
/* VSX move from VSR */
{as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4},
@@ -488,24 +503,25 @@ var optab = []Optab{
{as: AFCMPO, a1: C_FREG, a2: C_CREG, a6: C_FREG, type_: 70, size: 4},
{as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
{as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
- {as: ADCBF, a1: C_ZOREG, type_: 43, size: 4},
{as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
- {as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
+ {as: ADCBF, a1: C_XOREG, type_: 43, size: 4},
+ {as: ADCBF, a1: C_XOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
{as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
- {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4},
- {as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
- {as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
- {as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
- {as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
- {as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
+ {as: ADCBF, a1: C_XOREG, a6: C_SCON, type_: 43, size: 4},
+ {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_XOREG, type_: 44, size: 4},
+ {as: AECIWX, a1: C_XOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
+ {as: AECOWX, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
+ {as: AECIWX, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
+ {as: ALDAR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
+ {as: ALDAR, a1: C_XOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
{as: AEIEIO, type_: 46, size: 4},
{as: ATLBIE, a1: C_REG, type_: 49, size: 4},
{as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
{as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
{as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
- {as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+ {as: ASTSW, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
{as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
- {as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+ {as: ALSW, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
{as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
{as: APNOP, type_: 105, size: 8, ispfx: true},
@@ -583,7 +599,7 @@ func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
switch class {
case C_SACON, C_LACON:
return REGSP
- case C_LOREG, C_SOREG, C_ZOREG:
+ case C_LOREG, C_SOREG, C_ZOREG, C_XOREG:
switch a.Name {
case obj.NAME_EXTERN, obj.NAME_STATIC:
return REGSB
@@ -881,6 +897,13 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
return c.aclassreg(a.Reg)
case obj.TYPE_MEM:
+ if a.Index != 0 {
+ if a.Name != obj.NAME_NONE || a.Offset != 0 {
+ c.ctxt.Logf("Unexpected Instruction operand index %d offset %d class %d \n", a.Index, a.Offset, a.Class)
+
+ }
+ return C_XOREG
+ }
switch a.Name {
case obj.NAME_GOTREF, obj.NAME_TOCREF:
return C_ADDR
@@ -903,6 +926,7 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
case obj.NAME_AUTO:
c.instoffset = int64(c.autosize) + a.Offset
+
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SOREG
}
@@ -917,13 +941,13 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
case obj.NAME_NONE:
c.instoffset = a.Offset
- if c.instoffset == 0 {
+ if a.Offset == 0 && a.Index == 0 {
return C_ZOREG
- }
- if c.instoffset >= -BIG && c.instoffset < BIG {
+ } else if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SOREG
+ } else {
+ return C_LOREG
}
- return C_LOREG
}
return C_GOK
@@ -1160,6 +1184,9 @@ func cmp(a int, b int) bool {
case C_LOREG:
return cmp(C_SOREG, b)
+ case C_XOREG:
+ return cmp(C_REG, b) || cmp(C_ZOREG, b)
+
// An even/odd register input always matches the regular register types.
case C_REG:
return cmp(C_REGP, b) || (b == C_ZCON && r0iszero != 0)
@@ -2562,22 +2589,15 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
r = c.getimpliedreg(&p.To, p)
}
v := c.regoff(&p.To)
- if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
- if v != 0 {
- c.ctxt.Diag("illegal indexed instruction\n%v", p)
- }
- o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
- } else {
- if int32(int16(v)) != v {
- log.Fatalf("mishandled instruction %v", p)
- }
- // Offsets in DS form stores must be a multiple of 4
- inst := c.opstore(p.As)
- if c.opform(inst) == DS_FORM && v&0x3 != 0 {
- log.Fatalf("invalid offset for DS form load/store %v", p)
- }
- o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
+ if int32(int16(v)) != v {
+ log.Fatalf("mishandled instruction %v", p)
}
+ // Offsets in DS form stores must be a multiple of 4
+ inst := c.opstore(p.As)
+ if c.opform(inst) == DS_FORM && v&0x3 != 0 {
+ log.Fatalf("invalid offset for DS form load/store %v", p)
+ }
+ o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */
r := int(p.From.Reg)
@@ -2586,22 +2606,15 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
r = c.getimpliedreg(&p.From, p)
}
v := c.regoff(&p.From)
- if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
- if v != 0 {
- c.ctxt.Diag("illegal indexed instruction\n%v", p)
- }
- o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
- } else {
- if int32(int16(v)) != v {
- log.Fatalf("mishandled instruction %v", p)
- }
- // Offsets in DS form loads must be a multiple of 4
- inst := c.opload(p.As)
- if c.opform(inst) == DS_FORM && v&0x3 != 0 {
- log.Fatalf("invalid offset for DS form load/store %v", p)
- }
- o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
+ if int32(int16(v)) != v {
+ log.Fatalf("mishandled instruction %v", p)
+ }
+ // Offsets in DS form loads must be a multiple of 4
+ inst := c.opload(p.As)
+ if c.opform(inst) == DS_FORM && v&0x3 != 0 {
+ log.Fatalf("invalid offset for DS form load/store %v", p)
}
+ o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
// Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
@@ -3141,9 +3154,16 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
o1 = uint32(c.regoff(&p.From))
case 41: /* stswi */
+ if p.To.Type == obj.TYPE_MEM && p.To.Index == 0 && p.To.Offset != 0 {
+ c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
+ }
+
o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
case 42: /* lswi */
+ if p.From.Type == obj.TYPE_MEM && p.From.Index == 0 && p.From.Offset != 0 {
+ c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
+ }
o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
@@ -3772,6 +3792,17 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
if so&0x3 != 0 {
log.Fatalf("invalid offset for DS form load/store %v", p)
}
+
+ case 108: /* mov r, xoreg ==> stwx rx,ry */
+ r := int(p.To.Reg)
+ o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
+
+ case 109: /* mov xoreg, r ==> lbzx/lhzx/lwzx rx,ry, lbzx rx,ry + extsb r,r */
+ r := int(p.From.Reg)
+
+ o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
+ // Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
+ o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
}
out[0] = o1
diff --git a/src/cmd/internal/obj/ppc64/asm_test.go b/src/cmd/internal/obj/ppc64/asm_test.go
index c16d4a6e73..15dde3a952 100644
--- a/src/cmd/internal/obj/ppc64/asm_test.go
+++ b/src/cmd/internal/obj/ppc64/asm_test.go
@@ -482,6 +482,7 @@ func TestAddrClassifier(t *testing.T) {
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: BIG}, C_LOREG},
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LOREG}, // 33 is FixedFrameSize-1
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE}, C_ZOREG},
+ {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Index: REG_R4}, C_XOREG},
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: 1}, C_SOREG},
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: BIG}, C_LOREG},
{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: -BIG - 33}, C_LOREG},