Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #11182 from JosJuice/aarch64-emit-shift-imm
Arm64Emitter: Combine immh and immb for Emit(Scalar)ShiftImm
  • Loading branch information
degasus committed Oct 22, 2022
2 parents 19e25e3 + 84375a9 commit bba38a3
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 69 deletions.
82 changes: 15 additions & 67 deletions Source/Core/Common/Arm64Emitter.cpp
Expand Up @@ -2344,20 +2344,18 @@ void ARM64FloatEmitter::EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64R
(1 << 12) | (imm5 << 5) | DecodeReg(Rd));
}

void ARM64FloatEmitter::EmitShiftImm(bool Q, bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd,
ARM64Reg Rn)
void ARM64FloatEmitter::EmitShiftImm(bool Q, bool U, u32 imm, u32 opcode, ARM64Reg Rd, ARM64Reg Rn)
{
ASSERT_MSG(DYNA_REC, immh != 0, "Can't have zero immh");
ASSERT_MSG(DYNA_REC, (imm & 0b1111000) != 0, "Can't have zero immh");

Write32((Q << 30) | (U << 29) | (0xF << 24) | (immh << 19) | (immb << 16) | (opcode << 11) |
(1 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd));
Write32((Q << 30) | (U << 29) | (0xF << 24) | (imm << 16) | (opcode << 11) | (1 << 10) |
(DecodeReg(Rn) << 5) | DecodeReg(Rd));
}

void ARM64FloatEmitter::EmitScalarShiftImm(bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd,
ARM64Reg Rn)
void ARM64FloatEmitter::EmitScalarShiftImm(bool U, u32 imm, u32 opcode, ARM64Reg Rd, ARM64Reg Rn)
{
Write32((2 << 30) | (U << 29) | (0x3E << 23) | (immh << 19) | (immb << 16) | (opcode << 11) |
(1 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd));
Write32((2 << 30) | (U << 29) | (0x3E << 23) | (imm << 16) | (opcode << 11) | (1 << 10) |
(DecodeReg(Rn) << 5) | DecodeReg(Rd));
}

void ARM64FloatEmitter::EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opcode, ARM64Reg Rt,
Expand Down Expand Up @@ -3207,13 +3205,11 @@ void ARM64FloatEmitter::UCVTF(u8 size, ARM64Reg Rd, ARM64Reg Rn)
}
void ARM64FloatEmitter::SCVTF(u8 size, ARM64Reg Rd, ARM64Reg Rn, int scale)
{
int imm = size * 2 - scale;
EmitShiftImm(IsQuad(Rd), 0, imm >> 3, imm & 7, 0x1C, Rd, Rn);
EmitShiftImm(IsQuad(Rd), 0, size * 2 - scale, 0x1C, Rd, Rn);
}
void ARM64FloatEmitter::UCVTF(u8 size, ARM64Reg Rd, ARM64Reg Rn, int scale)
{
int imm = size * 2 - scale;
EmitShiftImm(IsQuad(Rd), 1, imm >> 3, imm & 7, 0x1C, Rd, Rn);
EmitShiftImm(IsQuad(Rd), 1, size * 2 - scale, 0x1C, Rd, Rn);
}
void ARM64FloatEmitter::SQXTN(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn)
{
Expand Down Expand Up @@ -3588,71 +3584,23 @@ void ARM64FloatEmitter::UXTL2(u8 src_size, ARM64Reg Rd, ARM64Reg Rn)

void ARM64FloatEmitter::SSHLL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper)
{
ASSERT_MSG(DYNA_REC, shift < src_size, "Shift amount must less than the element size! {} {}",
ASSERT_MSG(DYNA_REC, shift < src_size, "Shift amount must be less than the element size! {} {}",
shift, src_size);
u32 immh = 0;
u32 immb = shift & 0xFFF;

if (src_size == 8)
{
immh = 1;
}
else if (src_size == 16)
{
immh = 2 | ((shift >> 3) & 1);
}
else if (src_size == 32)
{
immh = 4 | ((shift >> 3) & 3);
;
}
EmitShiftImm(upper, 0, immh, immb, 0b10100, Rd, Rn);
EmitShiftImm(upper, 0, src_size | shift, 0b10100, Rd, Rn);
}

void ARM64FloatEmitter::USHLL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper)
{
ASSERT_MSG(DYNA_REC, shift < src_size, "Shift amount must less than the element size! {} {}",
ASSERT_MSG(DYNA_REC, shift < src_size, "Shift amount must be less than the element size! {} {}",
shift, src_size);
u32 immh = 0;
u32 immb = shift & 0xFFF;

if (src_size == 8)
{
immh = 1;
}
else if (src_size == 16)
{
immh = 2 | ((shift >> 3) & 1);
}
else if (src_size == 32)
{
immh = 4 | ((shift >> 3) & 3);
;
}
EmitShiftImm(upper, 1, immh, immb, 0b10100, Rd, Rn);
EmitShiftImm(upper, 1, src_size | shift, 0b10100, Rd, Rn);
}

void ARM64FloatEmitter::SHRN(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper)
{
ASSERT_MSG(DYNA_REC, shift < dest_size, "Shift amount must less than the element size! {} {}",
ASSERT_MSG(DYNA_REC, shift < dest_size, "Shift amount must be less than the element size! {} {}",
shift, dest_size);
u32 immh = 0;
u32 immb = shift & 0xFFF;

if (dest_size == 8)
{
immh = 1;
}
else if (dest_size == 16)
{
immh = 2 | ((shift >> 3) & 1);
}
else if (dest_size == 32)
{
immh = 4 | ((shift >> 3) & 3);
;
}
EmitShiftImm(upper, 1, immh, immb, 0b10000, Rd, Rn);
EmitShiftImm(upper, 1, dest_size | shift, 0b10000, Rd, Rn);
}

void ARM64FloatEmitter::SXTL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, bool upper)
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Common/Arm64Emitter.h
Expand Up @@ -1282,8 +1282,8 @@ class ARM64FloatEmitter
void EmitCondSelect(bool M, bool S, CCFlags cond, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm);
void EmitPermute(u32 size, u32 op, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm);
void EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64Reg Rd, u32 imm8);
void EmitShiftImm(bool Q, bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
void EmitScalarShiftImm(bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
void EmitShiftImm(bool Q, bool U, u32 imm, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
void EmitScalarShiftImm(bool U, u32 imm, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
void EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opcode, ARM64Reg Rt, ARM64Reg Rn);
void EmitLoadStoreMultipleStructurePost(u32 size, bool L, u32 opcode, ARM64Reg Rt, ARM64Reg Rn,
ARM64Reg Rm);
Expand Down

0 comments on commit bba38a3

Please sign in to comment.