mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[a64] Implement OPCODE_{SHR,SHA}
This commit is contained in:
parent
67706824c6
commit
10cba8e166
|
|
@ -2440,36 +2440,52 @@ EMITTER_OPCODE_TABLE(OPCODE_SHL, SHL_I8, SHL_I16, SHL_I32, SHL_I64, SHL_V128);
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// OPCODE_SHR
|
// OPCODE_SHR
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TODO(benvanik): optimize common shifts.
|
struct SHR_I8 : Sequence<SHR_I8, I<OPCODE_SHR, I8Op, I8Op, I8Op>> {
|
||||||
template <typename SEQ, typename REG, typename ARGS>
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
void EmitShrXX(A64Emitter& e, const ARGS& i) {
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
SEQ::EmitAssociativeBinaryOp(
|
|
||||||
e, i,
|
e, i,
|
||||||
[](A64Emitter& e, REG dest_src, REG src) {
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
e.LSR(dest_src, dest_src, src);
|
e.LSR(dest_src, dest_src, src);
|
||||||
},
|
},
|
||||||
[](A64Emitter& e, REG dest_src, int8_t constant) {
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
e.LSR(dest_src, dest_src, constant);
|
e.LSR(dest_src, dest_src, constant);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
struct SHR_I8 : Sequence<SHR_I8, I<OPCODE_SHR, I8Op, I8Op, I8Op>> {
|
};
|
||||||
|
struct SHR_I16 : Sequence<SHR_I16, I<OPCODE_SHR, I16Op, I16Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitShrXX<SHR_I8, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
|
e.LSR(dest_src, dest_src, src);
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
|
e.LSR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHR_I16 : Sequence<SHR_I16, I<OPCODE_SHR, I16Op, I16Op, I16Op>> {
|
struct SHR_I32 : Sequence<SHR_I32, I<OPCODE_SHR, I32Op, I32Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitShrXX<SHR_I16, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
|
e.LSR(dest_src, dest_src, src);
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
|
e.LSR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHR_I32 : Sequence<SHR_I32, I<OPCODE_SHR, I32Op, I32Op, I32Op>> {
|
struct SHR_I64 : Sequence<SHR_I64, I<OPCODE_SHR, I64Op, I64Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitShrXX<SHR_I32, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
}
|
e, i,
|
||||||
};
|
[](A64Emitter& e, XReg dest_src, WReg src) {
|
||||||
struct SHR_I64 : Sequence<SHR_I64, I<OPCODE_SHR, I64Op, I64Op, I64Op>> {
|
e.LSR(dest_src, dest_src, src.toX());
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
},
|
||||||
EmitShrXX<SHR_I64, XReg>(e, i);
|
[](A64Emitter& e, XReg dest_src, int8_t constant) {
|
||||||
|
e.LSR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHR_V128 : Sequence<SHR_V128, I<OPCODE_SHR, V128Op, V128Op, I8Op>> {
|
struct SHR_V128 : Sequence<SHR_V128, I<OPCODE_SHR, V128Op, V128Op, I8Op>> {
|
||||||
|
|
@ -2503,36 +2519,55 @@ EMITTER_OPCODE_TABLE(OPCODE_SHR, SHR_I8, SHR_I16, SHR_I32, SHR_I64, SHR_V128);
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// OPCODE_SHA
|
// OPCODE_SHA
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TODO(benvanik): optimize common shifts.
|
|
||||||
template <typename SEQ, typename REG, typename ARGS>
|
|
||||||
void EmitSarXX(A64Emitter& e, const ARGS& i) {
|
|
||||||
SEQ::EmitAssociativeBinaryOp(
|
|
||||||
e, i,
|
|
||||||
[](A64Emitter& e, REG dest_src, REG src) {
|
|
||||||
e.ASR(dest_src, dest_src, src);
|
|
||||||
},
|
|
||||||
[](A64Emitter& e, REG dest_src, int8_t constant) {
|
|
||||||
e.ASR(dest_src, dest_src, constant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
struct SHA_I8 : Sequence<SHA_I8, I<OPCODE_SHA, I8Op, I8Op, I8Op>> {
|
struct SHA_I8 : Sequence<SHA_I8, I<OPCODE_SHA, I8Op, I8Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitSarXX<SHA_I8, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
|
e.SXTB(dest_src, dest_src);
|
||||||
|
e.ASR(dest_src, dest_src, src);
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
|
e.SXTB(dest_src, dest_src);
|
||||||
|
e.ASR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHA_I16 : Sequence<SHA_I16, I<OPCODE_SHA, I16Op, I16Op, I8Op>> {
|
struct SHA_I16 : Sequence<SHA_I16, I<OPCODE_SHA, I16Op, I16Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitSarXX<SHA_I16, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
|
e.SXTH(dest_src, dest_src);
|
||||||
|
e.ASR(dest_src, dest_src, src);
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
|
e.ASR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHA_I32 : Sequence<SHA_I32, I<OPCODE_SHA, I32Op, I32Op, I8Op>> {
|
struct SHA_I32 : Sequence<SHA_I32, I<OPCODE_SHA, I32Op, I32Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitSarXX<SHA_I32, WReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, WReg dest_src, WReg src) {
|
||||||
|
e.ASR(dest_src, dest_src, src);
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, WReg dest_src, int8_t constant) {
|
||||||
|
e.ASR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SHA_I64 : Sequence<SHA_I64, I<OPCODE_SHA, I64Op, I64Op, I64Op>> {
|
struct SHA_I64 : Sequence<SHA_I64, I<OPCODE_SHA, I64Op, I64Op, I8Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
EmitSarXX<SHA_I64, XReg>(e, i);
|
Sequence::EmitAssociativeBinaryOp(
|
||||||
|
e, i,
|
||||||
|
[](A64Emitter& e, XReg dest_src, WReg src) {
|
||||||
|
e.ASR(dest_src, dest_src, src.toX());
|
||||||
|
},
|
||||||
|
[](A64Emitter& e, XReg dest_src, int8_t constant) {
|
||||||
|
e.ASR(dest_src, dest_src, constant);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
EMITTER_OPCODE_TABLE(OPCODE_SHA, SHA_I8, SHA_I16, SHA_I32, SHA_I64);
|
EMITTER_OPCODE_TABLE(OPCODE_SHA, SHA_I8, SHA_I16, SHA_I32, SHA_I64);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue