mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
ARM64: Fuse FP multiply-add/sub.
Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
This commit is contained in:
parent
bfeb1167cd
commit
2772cbc36e
@ -327,6 +327,27 @@ static void asm_fusexref(ASMState *as, A64Ins ai, Reg rd, IRRef ref,
|
|||||||
emit_lso(as, ai, (rd & 31), base, ofs);
|
emit_lso(as, ai, (rd & 31), base, ofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fuse FP multiply-add/sub. */
|
||||||
|
static int asm_fusemadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air)
|
||||||
|
{
|
||||||
|
IRRef lref = ir->op1, rref = ir->op2;
|
||||||
|
IRIns *irm;
|
||||||
|
if (lref != rref &&
|
||||||
|
((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
|
||||||
|
ra_noreg(irm->r)) ||
|
||||||
|
(mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
|
||||||
|
(rref = lref, ai = air, ra_noreg(irm->r))))) {
|
||||||
|
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||||
|
Reg add = ra_hintalloc(as, rref, dest, RSET_FPR);
|
||||||
|
Reg left = ra_alloc2(as, irm,
|
||||||
|
rset_exclude(rset_exclude(RSET_FPR, dest), add));
|
||||||
|
Reg right = (left >> 8); left &= 255;
|
||||||
|
emit_dnma(as, ai, (dest & 31), (left & 31), (right & 31), (add & 31));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* -- Calls --------------------------------------------------------------- */
|
/* -- Calls --------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Generate a call to a C function. */
|
/* Generate a call to a C function. */
|
||||||
@ -1308,6 +1329,7 @@ static void asm_intmul(ASMState *as, IRIns *ir)
|
|||||||
static void asm_add(ASMState *as, IRIns *ir)
|
static void asm_add(ASMState *as, IRIns *ir)
|
||||||
{
|
{
|
||||||
if (irt_isnum(ir->t)) {
|
if (irt_isnum(ir->t)) {
|
||||||
|
if (!asm_fusemadd(as, ir, A64I_FMADDd, A64I_FMADDd))
|
||||||
asm_fparith(as, ir, A64I_FADDd);
|
asm_fparith(as, ir, A64I_FADDd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1317,6 +1339,7 @@ static void asm_add(ASMState *as, IRIns *ir)
|
|||||||
static void asm_sub(ASMState *as, IRIns *ir)
|
static void asm_sub(ASMState *as, IRIns *ir)
|
||||||
{
|
{
|
||||||
if (irt_isnum(ir->t)) {
|
if (irt_isnum(ir->t)) {
|
||||||
|
if (!asm_fusemadd(as, ir, A64I_FNMSUBd, A64I_FMSUBd))
|
||||||
asm_fparith(as, ir, A64I_FSUBd);
|
asm_fparith(as, ir, A64I_FSUBd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,11 @@ static uint32_t emit_isfpk64(uint64_t n)
|
|||||||
|
|
||||||
/* -- Emit basic instructions --------------------------------------------- */
|
/* -- Emit basic instructions --------------------------------------------- */
|
||||||
|
|
||||||
|
static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra)
|
||||||
|
{
|
||||||
|
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_M(rm) | A64F_A(ra);
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_dnm(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm)
|
static void emit_dnm(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm)
|
||||||
{
|
{
|
||||||
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_M(rm);
|
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_M(rm);
|
||||||
|
Loading…
Reference in New Issue
Block a user