mirror of https://github.com/golang/go.git
cmd/asm: add new classification for index memory operands on PPC64
When a base+displacement kind of operand is given in an index-mode instruction, the assembler does not flag it as an invalid instruction causing the user to get an incorrect encoding of that instruction leading to incorrect execution of the program. Enable assembler to recognize valid and invalid operands used in index mode instructions by classifying SOREG type into two further types XOREG (used uniquely in index addressing mode instructions) and SOREG for instructions working on base+displacement operands. Also cleaned up usage of obj.Addr.Scale on PPC64. Change-Id: Ib4d84343ae57477c6c074f44c4c2749496e11b91 Reviewed-on: https://go-review.googlesource.com/c/go/+/405542 Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Archana Ravindar <aravind5@in.ibm.com>
This commit is contained in:
parent
4381c61c58
commit
67d85ad00f
|
|
@ -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)"},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ var cnames9 = []string{
|
|||
"ZOREG",
|
||||
"SOREG",
|
||||
"LOREG",
|
||||
"XOREG",
|
||||
"FPSCR",
|
||||
"XER",
|
||||
"LR",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
Loading…
Reference in New Issue