Commit f1973fca authored by Carlos Eduardo Seo's avatar Carlos Eduardo Seo Committed by David Chase

cmd/asm, cmd/internal/obj/ppc64: add ppc64 vector registers and instructions

The current implementation for Power architecture does not include the vector
(Altivec) registers.  This adds the 32 VMX registers and the most commonly used
instructions: X-form loads/stores; VX-form logical operations, add/sub,
rotate/shift, count, splat, SHA Sigma and AES cipher; VC-form compare; and
VA-form permute, shift, add/sub and select.

Fixes #15619

Change-Id: I544b990631726e8fdfcce8ecca0aeeb72faae9aa
Reviewed-on: https://go-review.googlesource.com/25600
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarLynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent 31ba8550
......@@ -319,6 +319,9 @@ func archPPC64() *Arch {
for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ {
register[obj.Rconv(i)] = int16(i)
}
for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
register[obj.Rconv(i)] = int16(i)
}
......
......@@ -77,6 +77,10 @@ func ppc64RegisterNumber(name string, n int16) (int16, bool) {
if 0 <= n && n <= 7 {
return ppc64.REG_CR0 + n, true
}
case "V":
if 0 <= n && n <= 31 {
return ppc64.REG_V0 + n, true
}
case "F":
if 0 <= n && n <= 31 {
return ppc64.REG_F0 + n, true
......
......@@ -665,9 +665,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
}
if p.arch.Family == sys.PPC64 {
if arch.IsPPC64RLD(op) {
// 2nd operand must always be a register.
// TODO: Do we need to guard this with the instruction type?
// That is, are there 4-operand instructions without this property?
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = newAddr(a[2])
......@@ -681,6 +678,27 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.To = a[3] // rt
break
}
// Else, it is a VA-form instruction
// reg reg reg reg
// imm reg reg reg
// Or a VX-form instruction
// imm imm reg reg
if a[1].Type == obj.TYPE_REG {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
} else if a[1].Type == obj.TYPE_CONST {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[2])
prog.From3 = newAddr(a[1])
prog.To = a[3]
break
} else {
p.errorf("invalid addressing modes for %s instruction", op)
return
}
}
if p.arch.Family == sys.S390X {
prog.From = a[1]
......
......@@ -340,6 +340,38 @@ var ppc64OperandTests = []operandTest{
{"6(PC)", "6(PC)"},
{"CR7", "CR7"},
{"CTR", "CTR"},
{"V0", "V0"},
{"V1", "V1"},
{"V2", "V2"},
{"V3", "V3"},
{"V4", "V4"},
{"V5", "V5"},
{"V6", "V6"},
{"V7", "V7"},
{"V8", "V8"},
{"V9", "V9"},
{"V10", "V10"},
{"V11", "V11"},
{"V12", "V12"},
{"V13", "V13"},
{"V14", "V14"},
{"V15", "V15"},
{"V16", "V16"},
{"V17", "V17"},
{"V18", "V18"},
{"V19", "V19"},
{"V20", "V20"},
{"V21", "V21"},
{"V22", "V22"},
{"V23", "V23"},
{"V24", "V24"},
{"V25", "V25"},
{"V26", "V26"},
{"V27", "V27"},
{"V28", "V28"},
{"V29", "V29"},
{"V30", "V30"},
{"V31", "V31"},
{"F14", "F14"},
{"F15", "F15"},
{"F16", "F16"},
......
......@@ -664,6 +664,213 @@ label1:
DCBF (R1)
DCBF (R1+R2) // DCBF (R1)(R2*1)
// VMX instructions
// Described as:
// <instruction type>, <instruction format>
// <golang asm operand order> produces
// <Power ISA operand order>
// Vector load, VX-form
// <MNEMONIC> (RB)(RA*1),VRT produces
// <mnemonic> VRT,RA,RB
LVEBX (R1)(R2*1), V0
LVEHX (R3)(R4*1), V1
LVEWX (R5)(R6*1), V2
LVX (R7)(R8*1), V3
LVXL (R9)(R10*1), V4
LVSL (R11)(R12*1), V5
LVSR (R14)(R15*1), V6
// Vector store, VX-form
// <MNEMONIC> VRT,(RB)(RA*1) produces
// <mnemonic> VRT,RA,RB
STVEBX V31, (R1)(R2*1)
STVEHX V30, (R2)(R3*1)
STVEWX V29, (R4)(R5*1)
STVX V28, (R6)(R7*1)
STVXL V27, (R9)(R9*1)
// Vector AND, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VANDL V10, V9, V8
VANDC V15, V14, V13
VNAND V19, V18, V17
// Vector OR, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VORL V26, V25, V24
VORC V23, V22, V21
VNOR V20, V19, V18
VXOR V17, V16, V15
VEQV V14, V13, V12
// Vector ADD, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VADDUBM V3, V2, V1
VADDUHM V3, V2, V1
VADDUWM V3, V2, V1
VADDUDM V3, V2, V1
VADDUQM V3, V2, V1
VADDCUQ V3, V2, V1
VADDCUW V3, V2, V1
VADDUBS V3, V2, V1
VADDUHS V3, V2, V1
VADDUWS V3, V2, V1
VADDSBS V3, V2, V1
VADDSHS V3, V2, V1
VADDSWS V3, V2, V1
// Vector ADD extended, VA-form
// <MNEMONIC> VRA,VRB,VRC,VRT produces
// <mnemonic> VRT,VRA,VRB,VRC
VADDEUQM V4, V3, V2, V1
VADDECUQ V4, V3, V2, V1
// Vector SUB, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VSUBUBM V3, V2, V1
VSUBUHM V3, V2, V1
VSUBUWM V3, V2, V1
VSUBUDM V3, V2, V1
VSUBUQM V3, V2, V1
VSUBCUQ V3, V2, V1
VSUBCUW V3, V2, V1
VSUBUBS V3, V2, V1
VSUBUHS V3, V2, V1
VSUBUWS V3, V2, V1
VSUBSBS V3, V2, V1
VSUBSHS V3, V2, V1
VSUBSWS V3, V2, V1
// Vector SUB extended, VA-form
// <MNEMONIC> VRA,VRB,VRC,VRT produces
// <mnemonic> VRT,VRA,VRB,VRC
VSUBEUQM V4, V3, V2, V1
VSUBECUQ V4, V3, V2, V1
// Vector rotate, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VRLB V2, V1, V0
VRLH V2, V1, V0
VRLW V2, V1, V0
VRLD V2, V1, V0
// Vector shift, VX-form
// <MNEMONIC> VRA,VRB,VRT
// <mnemonic> VRT,VRA,VRB
VSLB V2, V1, V0
VSLH V2, V1, V0
VSLW V2, V1, V0
VSL V2, V1, V0
VSLO V2, V1, V0
VSRB V2, V1, V0
VSRH V2, V1, V0
VSRW V2, V1, V0
VSR V2, V1, V0
VSRO V2, V1, V0
VSLD V2, V1, V0
VSRD V2, V1, V0
VSRAB V2, V1, V0
VSRAH V2, V1, V0
VSRAW V2, V1, V0
VSRAD V2, V1, V0
// Vector shift by octect immediate, VA-form with SHB 4-bit field
// <MNEMONIC> SHB,VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB,SHB
VSLDOI $4, V2, V1, V0
// Vector count, VX-form
// <MNEMONIC> VRB,VRT produces
// <mnemonic> VRT,VRB
VCLZB V4, V5
VCLZH V4, V5
VCLZW V4, V5
VCLZD V4, V5
VPOPCNTB V4, V5
VPOPCNTH V4, V5
VPOPCNTW V4, V5
VPOPCNTD V4, V5
// Vector compare, VC-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
// * Note: 'CC' suffix denotes Rc=1
// i.e. vcmpequb. v3,v1,v2 equals VCMPEQUBCC V1,V2,V3
VCMPEQUB V3, V2, V1
VCMPEQUBCC V3, V2, V1
VCMPEQUH V3, V2, V1
VCMPEQUHCC V3, V2, V1
VCMPEQUW V3, V2, V1
VCMPEQUWCC V3, V2, V1
VCMPEQUD V3, V2, V1
VCMPEQUDCC V3, V2, V1
VCMPGTUB V3, V2, V1
VCMPGTUBCC V3, V2, V1
VCMPGTUH V3, V2, V1
VCMPGTUHCC V3, V2, V1
VCMPGTUW V3, V2, V1
VCMPGTUWCC V3, V2, V1
VCMPGTUD V3, V2, V1
VCMPGTUDCC V3, V2, V1
VCMPGTSB V3, V2, V1
VCMPGTSBCC V3, V2, V1
VCMPGTSH V3, V2, V1
VCMPGTSHCC V3, V2, V1
VCMPGTSW V3, V2, V1
VCMPGTSWCC V3, V2, V1
VCMPGTSD V3, V2, V1
VCMPGTSDCC V3, V2, V1
// Vector permute, VA-form
// <MNEMONIC> VRA,VRB,VRC,VRT produces
// <mnemonic> VRT,VRA,VRB,VRC
VPERM V3, V2, V1, V0
// Vector select, VA-form
// <MNEMONIC> VRA,VRB,VRC,VRT produces
// <mnemonic> VRT,VRA,VRB,VRC
VSEL V3, V2, V1, V0
// Vector splat, VX-form with 4-bit UIM field
// <MNEMONIC> UIM,VRB,VRT produces
// <mnemonic> VRT,VRB,UIM
VSPLTB $15, V1, V0
VSPLTH $7, V1, V0
VSPLTW $3, V1, V0
// Vector splat immediate signed, VX-form with 5-bit SIM field
// <MNEMONIC> SIM,VRT produces
// <mnemonic> VRT,SIM
VSPLTISB $31, V4
VSPLTISH $31, V4
VSPLTISW $31, V4
// Vector AES cipher, VX-form
// <MNEMONIC> VRA,VRB,VRT produces
// <mnemonic> VRT,VRA,VRB
VCIPHER V3, V2, V1
VCIPHERLAST V3, V2, V1
VNCIPHER V3, V2, V1
VNCIPHERLAST V3, V2, V1
// Vector AES subbytes, VX-form
// <MNEMONIC> VRA,VRT produces
// <mnemonic> VRT,VRA
VSBOX V2, V1
// Vector SHA, VX-form with ST bit field and 4-bit SIX field
// <MNEMONIC> SIX,VRA,ST,VRT produces
// <mnemonic> VRT,VRA,ST,SIX
VSHASIGMAW $15, V1, $1, V0
VSHASIGMAD $15, V1, $1, V0
//
// NOP
//
......
......@@ -110,6 +110,39 @@ const (
REG_F30
REG_F31
REG_V0
REG_V1
REG_V2
REG_V3
REG_V4
REG_V5
REG_V6
REG_V7
REG_V8
REG_V9
REG_V10
REG_V11
REG_V12
REG_V13
REG_V14
REG_V15
REG_V16
REG_V17
REG_V18
REG_V19
REG_V20
REG_V21
REG_V22
REG_V23
REG_V24
REG_V25
REG_V26
REG_V27
REG_V28
REG_V29
REG_V30
REG_V31
REG_CR0
REG_CR1
REG_CR2
......@@ -193,6 +226,7 @@ const (
C_NONE = iota
C_REG
C_FREG
C_VREG
C_CREG
C_SPR /* special processor register */
C_ZCON
......@@ -550,6 +584,153 @@ const (
/* more 64-bit operations */
AHRFID
/* Vector */
ALV
ALVEBX
ALVEHX
ALVEWX
ALVX
ALVXL
ALVSL
ALVSR
ASTV
ASTVEBX
ASTVEHX
ASTVEWX
ASTVX
ASTVXL
AVAND
AVANDL
AVANDC
AVNAND
AVOR
AVORL
AVORC
AVNOR
AVXOR
AVEQV
AVADDUM
AVADDUBM
AVADDUHM
AVADDUWM
AVADDUDM
AVADDUQM
AVADDCU
AVADDCUQ
AVADDCUW
AVADDUS
AVADDUBS
AVADDUHS
AVADDUWS
AVADDSS
AVADDSBS
AVADDSHS
AVADDSWS
AVADDE
AVADDEUQM
AVADDECUQ
AVSUBUM
AVSUBUBM
AVSUBUHM
AVSUBUWM
AVSUBUDM
AVSUBUQM
AVSUBCU
AVSUBCUQ
AVSUBCUW
AVSUBUS
AVSUBUBS
AVSUBUHS
AVSUBUWS
AVSUBSS
AVSUBSBS
AVSUBSHS
AVSUBSWS
AVSUBE
AVSUBEUQM
AVSUBECUQ
AVR
AVRLB
AVRLH
AVRLW
AVRLD
AVS
AVSLB
AVSLH
AVSLW
AVSL
AVSLO
AVSRB
AVSRH
AVSRW
AVSR
AVSRO
AVSLD
AVSRD
AVSA
AVSRAB
AVSRAH
AVSRAW
AVSRAD
AVSOI
AVSLDOI
AVCLZ
AVCLZB
AVCLZH
AVCLZW
AVCLZD
AVPOPCNT
AVPOPCNTB
AVPOPCNTH
AVPOPCNTW
AVPOPCNTD
AVCMPEQ
AVCMPEQUB
AVCMPEQUBCC
AVCMPEQUH
AVCMPEQUHCC
AVCMPEQUW
AVCMPEQUWCC
AVCMPEQUD
AVCMPEQUDCC
AVCMPGT
AVCMPGTUB
AVCMPGTUBCC
AVCMPGTUH
AVCMPGTUHCC
AVCMPGTUW
AVCMPGTUWCC
AVCMPGTUD
AVCMPGTUDCC
AVCMPGTSB
AVCMPGTSBCC
AVCMPGTSH
AVCMPGTSHCC
AVCMPGTSW
AVCMPGTSWCC
AVCMPGTSD
AVCMPGTSDCC
AVPERM
AVSEL
AVSPLT
AVSPLTB
AVSPLTH
AVSPLTW
AVSPLTI
AVSPLTISB
AVSPLTISH
AVSPLTISW
AVCIPH
AVCIPHER
AVCIPHERLAST
AVNCIPH
AVNCIPHER
AVNCIPHERLAST
AVSBOX
AVSHASIGMA
AVSHASIGMAW
AVSHASIGMAD
ALAST
// aliases
......
......@@ -308,5 +308,150 @@ var Anames = []string{
"REMDUV",
"REMDUVCC",
"HRFID",
"LV",
"LVEBX",
"LVEHX",
"LVEWX",
"LVX",
"LVXL",
"LVSL",
"LVSR",
"STV",
"STVEBX",
"STVEHX",
"STVEWX",
"STVX",
"STVXL",
"VAND",
"VANDL",
"VANDC",
"VNAND",
"VOR",
"VORL",
"VORC",
"VNOR",
"VXOR",
"VEQV",
"VADDUM",
"VADDUBM",
"VADDUHM",
"VADDUWM",
"VADDUDM",
"VADDUQM",
"VADDCU",
"VADDCUQ",
"VADDCUW",
"VADDUS",
"VADDUBS",
"VADDUHS",
"VADDUWS",
"VADDSS",
"VADDSBS",
"VADDSHS",
"VADDSWS",
"VADDE",
"VADDEUQM",
"VADDECUQ",
"VSUBUM",
"VSUBUBM",
"VSUBUHM",
"VSUBUWM",
"VSUBUDM",
"VSUBUQM",
"VSUBCU",
"VSUBCUQ",
"VSUBCUW",
"VSUBUS",
"VSUBUBS",
"VSUBUHS",
"VSUBUWS",
"VSUBSS",
"VSUBSBS",
"VSUBSHS",
"VSUBSWS",
"VSUBE",
"VSUBEUQM",
"VSUBECUQ",
"VR",
"VRLB",
"VRLH",
"VRLW",
"VRLD",
"VS",
"VSLB",
"VSLH",
"VSLW",
"VSL",
"VSLO",
"VSRB",
"VSRH",
"VSRW",
"VSR",
"VSRO",
"VSLD",
"VSRD",
"VSA",
"VSRAB",
"VSRAH",
"VSRAW",
"VSRAD",
"VSOI",
"VSLDOI",
"VCLZ",
"VCLZB",
"VCLZH",
"VCLZW",
"VCLZD",
"VPOPCNT",
"VPOPCNTB",
"VPOPCNTH",
"VPOPCNTW",
"VPOPCNTD",
"VCMPEQ",
"VCMPEQUB",
"VCMPEQUBCC",
"VCMPEQUH",
"VCMPEQUHCC",
"VCMPEQUW",
"VCMPEQUWCC",
"VCMPEQUD",
"VCMPEQUDCC",
"VCMPGT",
"VCMPGTUB",
"VCMPGTUBCC",
"VCMPGTUH",
"VCMPGTUHCC",
"VCMPGTUW",
"VCMPGTUWCC",
"VCMPGTUD",
"VCMPGTUDCC",
"VCMPGTSB",
"VCMPGTSBCC",
"VCMPGTSH",
"VCMPGTSHCC",
"VCMPGTSW",
"VCMPGTSWCC",
"VCMPGTSD",
"VCMPGTSDCC",
"VPERM",
"VSEL",
"VSPLT",
"VSPLTB",
"VSPLTH",
"VSPLTW",
"VSPLTI",
"VSPLTISB",
"VSPLTISH",
"VSPLTISW",
"VCIPH",
"VCIPHER",
"VCIPHERLAST",
"VNCIPH",
"VNCIPHER",
"VNCIPHERLAST",
"VSBOX",
"VSHASIGMA",
"VSHASIGMAW",
"VSHASIGMAD",
"LAST",
}
......@@ -8,6 +8,7 @@ var cnames9 = []string{
"NONE",
"REG",
"FREG",
"VREG",
"CREG",
"SPR",
"ZCON",
......
This diff is collapsed.
......@@ -53,6 +53,9 @@ func Rconv(r int) string {
if REG_F0 <= r && r <= REG_F31 {
return fmt.Sprintf("F%d", r-REG_F0)
}
if REG_V0 <= r && r <= REG_V31 {
return fmt.Sprintf("V%d", r-REG_V0)
}
if REG_CR0 <= r && r <= REG_CR7 {
return fmt.Sprintf("CR%d", r-REG_CR0)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment