mirror of
https://github.com/qemu/qemu.git
synced 2024-12-05 17:53:36 +08:00
target/hppa: Convert fp multiply-add
Tested-by: Helge Deller <deller@gmx.de> Tested-by: Sven Schnelle <svens@stackframe.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
1cd012a5f7
commit
b1e2af576a
@ -153,3 +153,15 @@ lda 000011 ..... ..... .. . 1 -- 0110 ...... @ldim5 size=2
|
|||||||
lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
|
lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
|
||||||
sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
|
sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
|
||||||
stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
|
stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
|
||||||
|
|
||||||
|
####
|
||||||
|
# Floating-point Multiply Add
|
||||||
|
####
|
||||||
|
|
||||||
|
&mpyadd rm1 rm2 ta ra tm
|
||||||
|
@mpyadd ...... rm1:5 rm2:5 ta:5 ra:5 . tm:5 &mpyadd
|
||||||
|
|
||||||
|
fmpyadd_f 000110 ..... ..... ..... ..... 0 ..... @mpyadd
|
||||||
|
fmpyadd_d 000110 ..... ..... ..... ..... 1 ..... @mpyadd
|
||||||
|
fmpysub_f 100110 ..... ..... ..... ..... 0 ..... @mpyadd
|
||||||
|
fmpysub_d 100110 ..... ..... ..... ..... 1 ..... @mpyadd
|
||||||
|
@ -4255,37 +4255,54 @@ static inline int fmpyadd_s_reg(unsigned r)
|
|||||||
return (r & 16) * 2 + 16 + (r & 15);
|
return (r & 16) * 2 + 16 + (r & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
|
static bool do_fmpyadd_s(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
|
||||||
{
|
{
|
||||||
unsigned tm = extract32(insn, 0, 5);
|
int tm = fmpyadd_s_reg(a->tm);
|
||||||
unsigned f = extract32(insn, 5, 1);
|
int ra = fmpyadd_s_reg(a->ra);
|
||||||
unsigned ra = extract32(insn, 6, 5);
|
int ta = fmpyadd_s_reg(a->ta);
|
||||||
unsigned ta = extract32(insn, 11, 5);
|
int rm2 = fmpyadd_s_reg(a->rm2);
|
||||||
unsigned rm2 = extract32(insn, 16, 5);
|
int rm1 = fmpyadd_s_reg(a->rm1);
|
||||||
unsigned rm1 = extract32(insn, 21, 5);
|
|
||||||
|
|
||||||
nullify_over(ctx);
|
nullify_over(ctx);
|
||||||
|
|
||||||
/* Independent multiply & add/sub, with undefined behaviour
|
do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
|
||||||
if outputs overlap inputs. */
|
do_fop_weww(ctx, ta, ta, ra,
|
||||||
if (f == 0) {
|
is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
|
||||||
tm = fmpyadd_s_reg(tm);
|
|
||||||
ra = fmpyadd_s_reg(ra);
|
|
||||||
ta = fmpyadd_s_reg(ta);
|
|
||||||
rm2 = fmpyadd_s_reg(rm2);
|
|
||||||
rm1 = fmpyadd_s_reg(rm1);
|
|
||||||
do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
|
|
||||||
do_fop_weww(ctx, ta, ta, ra,
|
|
||||||
is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
|
|
||||||
} else {
|
|
||||||
do_fop_dedd(ctx, tm, rm1, rm2, gen_helper_fmpy_d);
|
|
||||||
do_fop_dedd(ctx, ta, ta, ra,
|
|
||||||
is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullify_end(ctx);
|
return nullify_end(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool trans_fmpyadd_f(DisasContext *ctx, arg_mpyadd *a)
|
||||||
|
{
|
||||||
|
return do_fmpyadd_s(ctx, a, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fmpysub_f(DisasContext *ctx, arg_mpyadd *a)
|
||||||
|
{
|
||||||
|
return do_fmpyadd_s(ctx, a, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool do_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
|
||||||
|
{
|
||||||
|
nullify_over(ctx);
|
||||||
|
|
||||||
|
do_fop_dedd(ctx, a->tm, a->rm1, a->rm2, gen_helper_fmpy_d);
|
||||||
|
do_fop_dedd(ctx, a->ta, a->ta, a->ra,
|
||||||
|
is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
|
||||||
|
|
||||||
|
return nullify_end(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a)
|
||||||
|
{
|
||||||
|
return do_fmpyadd_d(ctx, a, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fmpysub_d(DisasContext *ctx, arg_mpyadd *a)
|
||||||
|
{
|
||||||
|
return do_fmpyadd_d(ctx, a, true);
|
||||||
|
}
|
||||||
|
|
||||||
static bool trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
|
static bool trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
|
||||||
const DisasInsn *di)
|
const DisasInsn *di)
|
||||||
{
|
{
|
||||||
@ -4376,9 +4393,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
|
|||||||
|
|
||||||
opc = extract32(insn, 26, 6);
|
opc = extract32(insn, 26, 6);
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case 0x06:
|
|
||||||
trans_fmpyadd(ctx, insn, false);
|
|
||||||
return;
|
|
||||||
case 0x08:
|
case 0x08:
|
||||||
trans_ldil(ctx, insn);
|
trans_ldil(ctx, insn);
|
||||||
return;
|
return;
|
||||||
@ -4456,9 +4470,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
|
|||||||
case 0x25:
|
case 0x25:
|
||||||
trans_subi(ctx, insn);
|
trans_subi(ctx, insn);
|
||||||
return;
|
return;
|
||||||
case 0x26:
|
|
||||||
trans_fmpyadd(ctx, insn, true);
|
|
||||||
return;
|
|
||||||
case 0x27:
|
case 0x27:
|
||||||
trans_cmpb(ctx, insn, true, false, true);
|
trans_cmpb(ctx, insn, true, false, true);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user