Skip to content

Commit d257b7d

Browse files
committed
Add AArch64 instructions: FCVTZU, UCVTF, SQXTN, UQXTN.
1 parent 9e70aac commit d257b7d

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/aarch64/AArch64ASIMDAssembler.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,16 +625,20 @@ public enum ASIMDInstruction {
625625
CMLT_ZERO(0b01010 << 12),
626626
ABS(0b01011 << 12),
627627
XTN(0b10010 << 12),
628+
SQXTN(0b10100 << 12),
629+
UQXTN(UBit | 0b10100 << 12),
628630
/* size 0x */
629631
FCVTN(0b10110 << 12),
630632
FCVTL(0b10111 << 12),
631633
SCVTF(0b11101 << 12),
634+
UCVTF(UBit | 0b11101 << 12),
632635
/* size 1x */
633636
FCMGT_ZERO(0b01100 << 12),
634637
FCMEQ_ZERO(0b01101 << 12),
635638
FCMLT_ZERO(0b01110 << 12),
636639
FABS(0b01111 << 12),
637640
FCVTZS(0b11011 << 12),
641+
FCVTZU(UBit | 0b11011 << 12),
638642
/* UBit 1, size xx */
639643
REV32(UBit | 0b00000 << 12),
640644
CMGE_ZERO(UBit | 0b01000 << 12),
@@ -1979,6 +1983,25 @@ public void fcvtzsVV(ASIMDSize size, ElementSize eSize, Register dst, Register s
19791983
twoRegMiscEncoding(ASIMDInstruction.FCVTZS, size, elemSize1X(eSize), dst, src);
19801984
}
19811985

1986+
/**
1987+
* Floating-point convert to unsigned integer, rounding toward zero.<br>
1988+
*
1989+
* @param size register size.
1990+
* @param eSize source element size. Must be ElementSize.Word or ElementSize.DoubleWord.
1991+
* ElementSize.DoubleWord is only applicable when size is 128 (i.e. the operation is
1992+
* performed on more than one element).
1993+
* @param dst SIMD register.
1994+
* @param src SIMD register.
1995+
*/
1996+
public void fcvtzuVV(ASIMDSize size, ElementSize eSize, Register dst, Register src) {
1997+
assert usesMultipleLanes(size, eSize) : "Must use multiple lanes " + size + " " + eSize;
1998+
assert dst.getRegisterCategory().equals(SIMD) : dst;
1999+
assert src.getRegisterCategory().equals(SIMD) : src;
2000+
assert eSize == ElementSize.Word || eSize == ElementSize.DoubleWord : eSize;
2001+
2002+
twoRegMiscEncoding(ASIMDInstruction.FCVTZU, size, elemSize1X(eSize), dst, src);
2003+
}
2004+
19822005
/**
19832006
* C7.2.97 floating point divide vector.<br>
19842007
*
@@ -2734,6 +2757,25 @@ public void scvtfVV(ASIMDSize size, ElementSize eSize, Register dst, Register sr
27342757
twoRegMiscEncoding(ASIMDInstruction.SCVTF, size, elemSize0X(eSize), dst, src);
27352758
}
27362759

2760+
/**
2761+
* Unsigned integer convert to floating-point.<br>
2762+
*
2763+
* @param size register size.
2764+
* @param eSize source element size. Must be ElementSize.Word or ElementSize.DoubleWord.
2765+
* ElementSize.DoubleWord is only applicable when size is 128 (i.e. the operation is
2766+
* performed on more than one element).
2767+
* @param dst SIMD register.
2768+
* @param src SIMD register.
2769+
*/
2770+
public void ucvtfVV(ASIMDSize size, ElementSize eSize, Register dst, Register src) {
2771+
assert usesMultipleLanes(size, eSize) : "Must use multiple lanes " + size + " " + eSize;
2772+
assert dst.getRegisterCategory().equals(SIMD) : dst;
2773+
assert src.getRegisterCategory().equals(SIMD) : src;
2774+
assert eSize == ElementSize.Word || eSize == ElementSize.DoubleWord : eSize;
2775+
2776+
twoRegMiscEncoding(ASIMDInstruction.UCVTF, size, elemSize0X(eSize), dst, src);
2777+
}
2778+
27372779
/**
27382780
* C7.2.239 SHA1 hash update.<br>
27392781
*
@@ -4096,6 +4138,48 @@ public void xtn2VV(ElementSize dstESize, Register dst, Register src) {
40964138
twoRegMiscEncoding(ASIMDInstruction.XTN, true, elemSizeXX(dstESize), dst, src);
40974139
}
40984140

4141+
/**
4142+
* Signed saturating extract Narrow.<br>
4143+
* <p>
4144+
* From the manual: "This instruction reads each vector element from the source SIMD register,
4145+
* saturates each value to half the original width, places the result into a vector, and writes
4146+
* the vector to the destination SIMD register. All the values in this instruction are signed
4147+
* integer values."
4148+
*
4149+
* @param dstESize destination element size. Cannot be ElementSize.DoubleWord. The source
4150+
* element size is twice this width.
4151+
* @param dst SIMD register.
4152+
* @param src SIMD register.
4153+
*/
4154+
public void sqxtnVV(ElementSize dstESize, Register dst, Register src) {
4155+
assert dst.getRegisterCategory().equals(SIMD) : dst;
4156+
assert src.getRegisterCategory().equals(SIMD) : src;
4157+
assert dstESize != ElementSize.DoubleWord : dstESize;
4158+
4159+
twoRegMiscEncoding(ASIMDInstruction.SQXTN, false, elemSizeXX(dstESize), dst, src);
4160+
}
4161+
4162+
/**
4163+
* Unsigned saturating extract Narrow.<br>
4164+
* <p>
4165+
* From the manual: "This instruction reads each vector element from the source SIMD register,
4166+
* saturates each value to half the original width, places the result into a vector, and writes
4167+
* the vector to the destination SIMD register. All the values in this instruction are unsigned
4168+
* integer values."
4169+
*
4170+
* @param dstESize destination element size. Cannot be ElementSize.DoubleWord. The source
4171+
* element size is twice this width.
4172+
* @param dst SIMD register.
4173+
* @param src SIMD register.
4174+
*/
4175+
public void uqxtnVV(ElementSize dstESize, Register dst, Register src) {
4176+
assert dst.getRegisterCategory().equals(SIMD) : dst;
4177+
assert src.getRegisterCategory().equals(SIMD) : src;
4178+
assert dstESize != ElementSize.DoubleWord : dstESize;
4179+
4180+
twoRegMiscEncoding(ASIMDInstruction.UQXTN, false, elemSizeXX(dstESize), dst, src);
4181+
}
4182+
40994183
/**
41004184
* C7.2.403 Zip vectors (primary).
41014185
* <p>

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/aarch64/AArch64Assembler.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FCVTAS;
9898
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FCVTMS;
9999
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FCVTZS;
100+
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FCVTZU;
100101
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FDIV;
101102
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FMADD;
102103
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.FMAX;
@@ -151,6 +152,7 @@
151152
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.TBNZ;
152153
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.TBZ;
153154
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.UBFM;
155+
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.UCVTF;
154156
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.Instruction.UDIV;
155157
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.InstructionType.FP32;
156158
import static jdk.graal.compiler.asm.aarch64.AArch64Assembler.InstructionType.FP64;
@@ -1013,7 +1015,9 @@ public enum Instruction {
10131015
FCVTMS(0x00100000),
10141016

10151017
FCVTZS(0x00180000),
1018+
FCVTZU(0x00190000),
10161019
SCVTF(0x00020000),
1020+
UCVTF(0x00030000),
10171021

10181022
FABS(0x00008000),
10191023
FSQRT(0x00018000),
@@ -3524,6 +3528,20 @@ public void fcvtzs(int dstSize, int srcSize, Register dst, Register src) {
35243528
fcvtCpuFpuInstruction(FCVTZS, dst, src, generalFromSize(dstSize), floatFromSize(srcSize));
35253529
}
35263530

3531+
/**
3532+
* Floating-point Convert to Unsigned integer, rounding toward Zero.
3533+
*
3534+
* @param dstSize size of integer register. 32 or 64.
3535+
* @param srcSize size of floating point register. 32 or 64.
3536+
* @param dst general purpose register. May not be null, the zero-register or the stackpointer.
3537+
* @param src floating point register. May not be null.
3538+
*/
3539+
public void fcvtzu(int dstSize, int srcSize, Register dst, Register src) {
3540+
assert verifySizesAndRegistersRF(dstSize, srcSize, dst, src);
3541+
3542+
fcvtCpuFpuInstruction(FCVTZU, dst, src, generalFromSize(dstSize), floatFromSize(srcSize));
3543+
}
3544+
35273545
/* Convert from Integer (5.7.4.2) */
35283546
/**
35293547
* C7.2.236 Signed integer Convert to Floating-point (scalar).
@@ -3539,6 +3557,20 @@ public void scvtf(int dstSize, int srcSize, Register dst, Register src) {
35393557
fcvtCpuFpuInstruction(SCVTF, dst, src, floatFromSize(dstSize), generalFromSize(srcSize));
35403558
}
35413559

3560+
/**
3561+
* Unsigned integer Convert to Floating-point (scalar).
3562+
*
3563+
* @param dstSize size of floating point register. 32 or 64.
3564+
* @param srcSize size of integer register. 32 or 64.
3565+
* @param dst floating point register. May not be null.
3566+
* @param src general purpose register. May not be null or the stackpointer.
3567+
*/
3568+
public void ucvtf(int dstSize, int srcSize, Register dst, Register src) {
3569+
assert verifySizesAndRegistersFZ(dstSize, srcSize, dst, src);
3570+
3571+
fcvtCpuFpuInstruction(UCVTF, dst, src, floatFromSize(dstSize), generalFromSize(srcSize));
3572+
}
3573+
35423574
private void fcvtCpuFpuInstruction(Instruction instr, Register dst, Register src, InstructionType type1, InstructionType type2) {
35433575
emitInt(type1.encoding | type2.encoding | instr.encoding | FpConvertOp | rd(dst) | rs1(src));
35443576
}

0 commit comments

Comments
 (0)