Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arm64: implement SIMD Integer arithmetics #641

Merged
merged 2 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/asm/amd64/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ func (a *AssemblerImpl) EncodeNoneToRegister(n *NodeImpl) (err error) {
modRM := 0b11_000_000 | // Specifying that opeand is register.
regBits
if n.Instruction == JMP {
// JMP's Opcode is defined as "FF /4" meaning that we have to have "4"
// JMP's opcode is defined as "FF /4" meaning that we have to have "4"
// in 4-6th bits in the ModRM byte. https://www.felixcloutier.com/x86/jmp
modRM |= 0b00_100_000
} else if n.Instruction == NEGQ {
Expand Down
15 changes: 0 additions & 15 deletions internal/asm/arm64/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,6 @@ type Assembler interface {
srcReg, dstReg asm.Register,
)

// CompileSIMDByteToSIMDByte adds an instruction where source and destination operand is the SIMD register
// specified as `srcReg.B8` and `dstReg.B8` where `.B8` part of register is called "arrangement".
// See https://stackoverflow.com/questions/57294672/what-is-arrangement-specifier-16b-8b-in-arm-assembly-language-instructions
//
// TODO: implement this in CompileVectorRegisterToVectorRegister.
CompileSIMDByteToSIMDByte(instruction asm.Instruction, srcReg, dstReg asm.Register)

// CompileTwoSIMDBytesToSIMDByteRegister adds an instruction where source operand is two SIMD registers specified as `srcReg1.B8`,
// and `srcReg2.B8` and the destination is the one SIMD register `dstReg.B8`.
CompileTwoSIMDBytesToSIMDByteRegister(instruction asm.Instruction, srcReg1, srcReg2, dstReg asm.Register)

// CompileSIMDByteToRegister adds an instruction where source operand is the SIMD register specified as `srcReg.B8`,
// and the destination is the register `dstReg`.
CompileSIMDByteToRegister(instruction asm.Instruction, srcReg, dstReg asm.Register)

// CompileConditionalRegisterSet adds an instruction to set 1 on dstReg if the condition satisfies,
// otherwise set 0.
CompileConditionalRegisterSet(cond asm.ConditionalRegisterState, dstReg asm.Register)
Expand Down
82 changes: 77 additions & 5 deletions internal/asm/arm64/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ const (
FCVTSD
// FCVTZSD is the FCVTZS instruction, for double precision. https://developer.arm.com/documentation/dui0802/a/A64-Floating-point-Instructions/FCVTZS--scalar--integer-
FCVTZSD
// FCVTZSD is the FCVTZS instruction, for double precision in 64-bit mode. https://developer.arm.com/documentation/dui0802/a/A64-Floating-point-Instructions/FCVTZS--scalar--integer-
// FCVTZSDW is the FCVTZS instruction, for double precision in 64-bit mode. https://developer.arm.com/documentation/dui0802/a/A64-Floating-point-Instructions/FCVTZS--scalar--integer-
FCVTZSDW
// FCVTZSS is the FCVTZS instruction, for single precision. https://developer.arm.com/documentation/dui0802/a/A64-Floating-point-Instructions/FCVTZS--scalar--integer-
FCVTZSS
Expand Down Expand Up @@ -702,8 +702,8 @@ const (
INSGEN
// INSELEM is the INS(element) instruction https://developer.arm.com/documentation/ddi0596/2020-12/SIMD-FP-Instructions/INS--element---Insert-vector-element-from-another-vector-element-?lang=en
INSELEM
// VUADDLV is the UADDLV(vector) instruction. https://developer.arm.com/documentation/dui0802/a/A64-Advanced-SIMD-Vector-Instructions/UADDLV--vector-
VUADDLV
// UADDLV is the UADDLV(vector) instruction. https://developer.arm.com/documentation/dui0802/a/A64-Advanced-SIMD-Vector-Instructions/UADDLV--vector-
UADDLV
// VADD is the ADD(vector) instruction. https://developer.arm.com/documentation/dui0802/a/A64-Advanced-SIMD-Vector-Instructions/ADD--vector-
VADD
// VFADDS is the FADD(vector) instruction, for single precision. https://developer.arm.com/documentation/dui0802/a/A64-Advanced-SIMD-Vector-Instructions/FADD--vector-
Expand Down Expand Up @@ -816,6 +816,46 @@ const (
// VFRINTN is the FRINTN(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/FRINTN--vector---Floating-point-Round-to-Integral--to-nearest-with-ties-to-even--vector--?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VFRINTN
// VMUL is the MUL(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/MUL--vector---Multiply--vector--?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VMUL
// VNEG is the NEG(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/NEG--vector---Negate--vector--?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VNEG
// VABS is the ABS(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/ABS--Absolute-value--vector--?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VABS
// VSQADD is the SQADD(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SQADD--Signed-saturating-Add-?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VSQADD
// VUQADD is the UQADD(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/UQADD--Unsigned-saturating-Add-?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VUQADD
// VSQSUB is the SQSUB(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SQSUB--Signed-saturating-Subtract-?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VSQSUB
// VUQSUB is the UQSUB(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/UQSUB--Unsigned-saturating-Subtract-?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VUQSUB
// SMIN is the SMIN instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SMIN--Signed-Minimum--vector--?lang=en
SMIN
// SMAX is the SMAX instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SMAX--Signed-Maximum--vector--?lang=en
SMAX
// UMIN is the UMIN instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/UMIN--Unsigned-Minimum--vector--?lang=en
UMIN
// UMAX is the UMAX instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/UMAX--Unsigned-Maximum--vector--?lang=en
UMAX
// URHADD is the URHADD instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/URHADD--Unsigned-Rounding-Halving-Add-?lang=en
URHADD
// REV64 is the REV64 instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/REV64--Reverse-elements-in-64-bit-doublewords--vector--?lang=en
REV64
// XTN is the XTN instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/XTN--XTN2--Extract-Narrow-?lang=en
XTN
// VUMLAL is the UMLAL(vector) instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/UMLAL--UMLAL2--vector---Unsigned-Multiply-Add-Long--vector--?lang=en
// Note: prefixed by V to distinguish from the non-vector variant.
VUMLAL
// SHLL is the SHLL instruction https://developer.arm.com/documentation/ddi0596/2021-12/SIMD-FP-Instructions/SHLL--SHLL2--Shift-Left-Long--by-element-size--?lang=en
SHLL

// instructionEnd is always placed at the bottom of this iota definition to be used in the test.
instructionEnd
Expand Down Expand Up @@ -1146,8 +1186,8 @@ func InstructionName(i asm.Instruction) string {
return "VBIT"
case VCNT:
return "VCNT"
case VUADDLV:
return "VUADDLV"
case UADDLV:
return "UADDLV"
case VMOV:
return "VMOV"
case INSELEM:
Expand Down Expand Up @@ -1254,6 +1294,38 @@ func InstructionName(i asm.Instruction) string {
return "VFRINTZ"
case VFRINTN:
return "VFRINTN"
case VMUL:
return "VMUL"
case VNEG:
return "VNEG"
case VABS:
return "VABS"
case VSQADD:
return "VSQADD"
case VUQADD:
return "VUQADD"
case SMIN:
return "SMIN"
case SMAX:
return "SMAX"
case UMIN:
return "UMIN"
case UMAX:
return "UMAX"
case URHADD:
return "URHADD"
case VSQSUB:
return "VSQSUB"
case VUQSUB:
return "VUQSUB"
case REV64:
return "REV64"
case XTN:
return "XTN"
case VUMLAL:
return "VUMLAL"
case SHLL:
return "SHLL"
}
panic(fmt.Errorf("unknown instruction %d", i))
}
Loading