diff --git a/src/backend/A64/emitter/a64_emitter.cpp b/src/backend/A64/emitter/a64_emitter.cpp index d7edba46..12963a73 100644 --- a/src/backend/A64/emitter/a64_emitter.cpp +++ b/src/backend/A64/emitter/a64_emitter.cpp @@ -1992,6 +1992,17 @@ void ARM64FloatEmitter::EmitThreeSame(bool U, u32 size, u32 opcode, ARM64Reg Rd, (opcode << 11) | (1 << 10) | (Rn << 5) | Rd); } +void ARM64FloatEmitter::EmitScalarThreeSame(bool U, u32 size, u32 opcode, ARM64Reg Rd, ARM64Reg Rn, + ARM64Reg Rm) { + ASSERT_MSG(!IsQuad(Rd), "%s doesn't support quads!", __func__); + Rd = DecodeReg(Rd); + Rn = DecodeReg(Rn); + Rm = DecodeReg(Rm); + + Write32((U << 29) | (0b1011110001 << 21) | (size << 22) | (Rm << 16) | + (opcode << 11) | (1 << 10) | (Rn << 5) | Rd); +} + void ARM64FloatEmitter::EmitCopy(bool Q, u32 op, u32 imm5, u32 imm4, ARM64Reg Rd, ARM64Reg Rn) { Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2787,6 +2798,20 @@ void ARM64FloatEmitter::EmitScalar3Source(bool isDouble, ARM64Reg Rd, ARM64Reg R (Ra << 10) | (Rn << 5) | Rd); } +// Scalar three same +void ARM64FloatEmitter::SQADD(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { + EmitScalarThreeSame(0, static_cast(esize), 0b000011, Rd, Rn, Rm); +} +void ARM64FloatEmitter::SQSUB(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { + EmitScalarThreeSame(0, static_cast(esize), 0b001011, Rd, Rn, Rm); +} +void ARM64FloatEmitter::UQADD(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { + EmitScalarThreeSame(1, static_cast(esize), 0b000011, Rd, Rn, Rm); +} +void ARM64FloatEmitter::UQSUB(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { + EmitScalarThreeSame(1, static_cast(esize), 0b001011, Rd, Rn, Rm); +} + // Scalar floating point immediate void ARM64FloatEmitter::FMOV(ARM64Reg Rd, uint8_t imm8) { EmitScalarImm(0, 0, 0, 0, Rd, imm8); diff --git a/src/backend/A64/emitter/a64_emitter.h b/src/backend/A64/emitter/a64_emitter.h index d5ea1b4d..f4b99436 100644 --- a/src/backend/A64/emitter/a64_emitter.h +++ b/src/backend/A64/emitter/a64_emitter.h @@ -295,6 +295,14 @@ enum RoundingMode { ROUND_Z, // round towards zero }; +// Size of each element in the Vector +enum ESize { + B, // Byte + H, // Half Word + S, // Single Word + D, // Double Word +}; + struct FixupBranch { u8* ptr; // Type defines @@ -945,6 +953,12 @@ public: void FNMADD(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra); void FNMSUB(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra); + // Scalar three same + void SQADD(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); + void UQADD(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); + void SQSUB(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); + void UQSUB(ESize esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); + // Scalar floating point immediate void FMOV(ARM64Reg Rd, uint8_t imm8);