mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
ARM64: Fix DUP disasm, INS disasm
This commit is contained in:
parent
a3db3ed5c1
commit
013bbc71af
4 changed files with 24 additions and 5 deletions
|
@ -3518,6 +3518,14 @@ void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Quite a few values could be generated easily using the MOVI instruction and friends.
|
||||
void ARM64FloatEmitter::MOVI2FDUP(ARM64Reg Rd, float value, ARM64Reg scratch) {
|
||||
// TODO: Make it work with more element sizes
|
||||
// TODO: Optimize - there are shorter solution for many values
|
||||
MOVI2F(Rd, value, scratch);
|
||||
DUP(32, Rd, Rd, 0);
|
||||
}
|
||||
|
||||
void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) {
|
||||
u32 val;
|
||||
bool shift;
|
||||
|
|
|
@ -883,6 +883,7 @@ public:
|
|||
void FMLA(u8 esize, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u8 index);
|
||||
|
||||
void MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch = INVALID_REG, bool negate = false);
|
||||
void MOVI2FDUP(ARM64Reg Rd, float value, ARM64Reg scratch = INVALID_REG);
|
||||
|
||||
// ABI related
|
||||
void ABI_PushRegisters(BitSet32 registers);
|
||||
|
|
|
@ -533,12 +533,20 @@ static void FPandASIMD1(uint32_t w, uint64_t addr, Instruction *instr) {
|
|||
int imm4 = (w >> 11) & 0xF;
|
||||
int dst_index = imm5 >> (size + 1);
|
||||
int src_index = imm4 >> size;
|
||||
int op = (w >> 29) & 1;
|
||||
char s = "bhsd"[size];
|
||||
if (op == 0 && imm4 == 0) {
|
||||
// DUP (element)
|
||||
int idxdsize = (imm5 & 8) ? 128 : 64;
|
||||
char r = "dq"[idxdsize == 128];
|
||||
snprintf(instr->text, sizeof(instr->text), "dup %c%d, %c%d.%c[%d]", r, Rd, r, Rn, s, dst_index);
|
||||
} else {
|
||||
int idxdsize = (imm4 & 8) ? 128 : 64;
|
||||
char s = "bhdx"[size];
|
||||
char r = "dq"[idxdsize == 128];
|
||||
snprintf(instr->text, sizeof(instr->text), "ins %c%d.%c[%d], %c%d.%c[%d]", r, Rd, s, dst_index, r, Rn, s, src_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (((w >> 21) & 0x4F8) == 0x78) {
|
||||
if ((w >> 10) & 1) {
|
||||
if (((w >> 19) & 0xf) == 0) {
|
||||
|
|
|
@ -39,6 +39,8 @@ bool TestArm64Emitter() {
|
|||
ARM64XEmitter emitter((u8 *)code);
|
||||
ARM64FloatEmitter fp(&emitter);
|
||||
|
||||
fp.DUP(32, Q1, Q30, 3);
|
||||
RET(CheckLast(emitter, "4e1c07c1 dup q1, q30.s[3]"));
|
||||
fp.UXTL(8, Q1, D8);
|
||||
RET(CheckLast(emitter, "2f08a501 uxtl.16.8 q1, d8"));
|
||||
fp.LDR(16, INDEX_UNSIGNED, Q1, X1, 64);
|
||||
|
@ -52,7 +54,7 @@ bool TestArm64Emitter() {
|
|||
fp.FMUL(32, D1, D13, D21);
|
||||
RET(CheckLast(emitter, "2e35dda1 fmul.32 d1, d13, d21"));
|
||||
fp.INS(32, Q3, 1, Q12, 3);
|
||||
RET(CheckLast(emitter, "6e0c6583 ins q3.d[1], q12.d[3]"));
|
||||
RET(CheckLast(emitter, "6e0c6583 ins q3.s[1], q12.s[3]"));
|
||||
fp.INS(8, D4, 5, D11, 2);
|
||||
RET(CheckLast(emitter, "6e0b1564 ins d4.b[5], d11.b[2]"));
|
||||
emitter.NEG(X1, X2);
|
||||
|
|
Loading…
Add table
Reference in a new issue