mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 15:00:17 +02:00
ArmEmitter: Adds sized Scalar 1 source and 2 source helpers
Removes the need for an annoying switch statement with scalar operations for the most part.
This commit is contained in:
1 parent
fc70fc3506
commit
a1eb571630
2 files changed
+111
No files matched your search
@@ -1384,6 +1384,12 @@ public:
|
||||
}
|
||||
|
||||
// SVE predicate initialize
|
||||
void ptrue(SubRegSize size, PRegister pd, PredicatePattern pattern) {
|
||||
SVEPredicateMisc(0b1000, 0b10000, FEXCore::ToUnderlying(pattern), size, pd);
|
||||
}
|
||||
void ptrues(SubRegSize size, PRegister pd, PredicatePattern pattern) {
|
||||
SVEPredicateMisc(0b1001, 0b10000, FEXCore::ToUnderlying(pattern), size, pd);
|
||||
}
|
||||
template <SubRegSize size>
|
||||
void ptrue(PRegister pd, PredicatePattern pattern) {
|
||||
SVEPredicateMisc(0b1000, 0b10000, FEXCore::ToUnderlying(pattern), size, pd);
|
||||
|
||||
@@ -798,6 +798,52 @@ public:
|
||||
// XXX:
|
||||
//
|
||||
// Floating-point data-processing (1 source)
|
||||
void fmov(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b000000, rd, rn);
|
||||
}
|
||||
void fabs(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b000001, rd, rn);
|
||||
}
|
||||
void fneg(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b000010, rd, rn);
|
||||
}
|
||||
void fsqrt(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b000011, rd, rn);
|
||||
}
|
||||
void frintn(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001000, rd, rn);
|
||||
}
|
||||
void frintp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001001, rd, rn);
|
||||
}
|
||||
void frintm(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001010, rd, rn);
|
||||
}
|
||||
void frintz(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001011, rd, rn);
|
||||
}
|
||||
void frinta(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001100, rd, rn);
|
||||
}
|
||||
void frintx(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001110, rd, rn);
|
||||
}
|
||||
void frinti(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b001111, rd, rn);
|
||||
}
|
||||
void frint32z(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b010000, rd, rn);
|
||||
}
|
||||
void frint32x(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b010001, rd, rn);
|
||||
}
|
||||
void frint64z(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b010010, rd, rn);
|
||||
}
|
||||
void frint64x(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b010011, rd, rn);
|
||||
}
|
||||
|
||||
void fmov(SRegister rd, SRegister rn) {
|
||||
Float1Source(0, 0, 0b00, 0b000000, rd.V(), rn.V());
|
||||
}
|
||||
@@ -1065,6 +1111,34 @@ public:
|
||||
}
|
||||
|
||||
// Floating-point data-processing (2 source)
|
||||
void fmul(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0000, rd, rn, rm);
|
||||
}
|
||||
void fdiv(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0001, rd, rn, rm);
|
||||
}
|
||||
void fadd(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0010, rd, rn, rm);
|
||||
}
|
||||
void fsub(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0011, rd, rn, rm);
|
||||
}
|
||||
void fmax(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0100, rd, rn, rm);
|
||||
}
|
||||
void fmin(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0101, rd, rn, rm);
|
||||
}
|
||||
void fmaxnm(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0110, rd, rn, rm);
|
||||
}
|
||||
void fminnm(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0111, rd, rn, rm);
|
||||
}
|
||||
void fnmul(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b1000, rd, rn, rm);
|
||||
}
|
||||
|
||||
void fmul(SRegister rd, SRegister rn, SRegister rm) {
|
||||
Float2Source(0, 0, 0b00, 0b0000, rd.V(), rn.V(), rm.V());
|
||||
}
|
||||
@@ -1150,6 +1224,16 @@ public:
|
||||
}
|
||||
|
||||
// Floating-point conditional select
|
||||
void fcsel(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, Condition Cond) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
FloatConditionalSelect(0, 0, ConvertedSize, rd, rn, rm, Cond);
|
||||
}
|
||||
|
||||
void fcsel(SRegister rd, SRegister rn, SRegister rm, Condition Cond) {
|
||||
FloatConditionalSelect(0, 0, 0b00, rd.V(), rn.V(), rm.V(), Cond);
|
||||
}
|
||||
@@ -1305,6 +1389,16 @@ private:
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
void Float1Source(ScalarRegSize size, uint32_t M, uint32_t S, uint32_t opcode, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
Float1Source(M, S, ConvertedSize, opcode, rd, rn);
|
||||
}
|
||||
|
||||
// Floating-point compare
|
||||
void FloatCompare(uint32_t M, uint32_t S, uint32_t ftype, uint32_t op, uint32_t opcode2, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0010'0000'0000'0000;
|
||||
@@ -1337,6 +1431,7 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
// Floating-point data-processing (2 source)
|
||||
|
||||
void Float2Source(uint32_t M, uint32_t S, uint32_t ptype, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0000'1000'0000'0000;
|
||||
|
||||
@@ -1351,6 +1446,16 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void Float2Source(ScalarRegSize size, uint32_t M, uint32_t S, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
Float2Source(M, S, ConvertedSize, opcode, rd, rn, rm);
|
||||
}
|
||||
|
||||
// Floating-point conditional select
|
||||
void FloatConditionalSelect(uint32_t M, uint32_t S, uint32_t ptype, VRegister rd, VRegister rn, VRegister rm, Condition Cond) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0000'1100'0000'0000;
|
||||
|
||||
Reference in new issue
Block a user