mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
target/hppa: Convert offset memory insns
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
0588e061dc
commit
740038d7f5
2 changed files with 99 additions and 165 deletions
|
@ -303,12 +303,29 @@ static int ma_to_m(int val)
|
|||
return val & 2 ? (val & 1 ? -1 : 1) : 0;
|
||||
}
|
||||
|
||||
/* Used for branch targets. */
|
||||
/* Convert the sign of the displacement to a pre or post-modify. */
|
||||
static int pos_to_m(int val)
|
||||
{
|
||||
return val ? 1 : -1;
|
||||
}
|
||||
|
||||
static int neg_to_m(int val)
|
||||
{
|
||||
return val ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Used for branch targets and fp memory ops. */
|
||||
static int expand_shl2(int val)
|
||||
{
|
||||
return val << 2;
|
||||
}
|
||||
|
||||
/* Used for fp memory ops. */
|
||||
static int expand_shl3(int val)
|
||||
{
|
||||
return val << 3;
|
||||
}
|
||||
|
||||
/* Used for assemble_21. */
|
||||
static int expand_shl11(int val)
|
||||
{
|
||||
|
@ -883,24 +900,6 @@ static inline unsigned assemble_sr3(uint32_t insn)
|
|||
return s2 * 4 + s0;
|
||||
}
|
||||
|
||||
static target_sreg assemble_16(uint32_t insn)
|
||||
{
|
||||
/* Take the name from PA2.0, which produces a 16-bit number
|
||||
only with wide mode; otherwise a 14-bit number. Since we don't
|
||||
implement wide mode, this is always the 14-bit number. */
|
||||
return low_sextract(insn, 0, 14);
|
||||
}
|
||||
|
||||
static target_sreg assemble_16a(uint32_t insn)
|
||||
{
|
||||
/* Take the name from PA2.0, which produces a 14-bit shifted number
|
||||
only with wide mode; otherwise a 12-bit shifted number. Since we
|
||||
don't implement wide mode, this is always the 12-bit number. */
|
||||
target_ureg x = -(target_ureg)(insn & 1);
|
||||
x = (x << 11) | extract32(insn, 2, 11);
|
||||
return x << 2;
|
||||
}
|
||||
|
||||
/* The parisc documentation describes only the general interpretation of
|
||||
the conditions, without describing their exact implementation. The
|
||||
interpretations do not stand up well when considering ADD,C and SUB,B.
|
||||
|
@ -1594,7 +1593,7 @@ static bool do_load(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
static bool do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
unsigned rx, int scale, target_sreg disp,
|
||||
unsigned sp, int modify)
|
||||
{
|
||||
|
@ -1611,10 +1610,16 @@ static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
gen_helper_loaded_fr0(cpu_env);
|
||||
}
|
||||
|
||||
nullify_end(ctx);
|
||||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
static bool trans_fldw(DisasContext *ctx, arg_ldst *a)
|
||||
{
|
||||
return do_floadw(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
|
||||
a->disp, a->sp, a->m);
|
||||
}
|
||||
|
||||
static bool do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
unsigned rx, int scale, target_sreg disp,
|
||||
unsigned sp, int modify)
|
||||
{
|
||||
|
@ -1631,7 +1636,13 @@ static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
gen_helper_loaded_fr0(cpu_env);
|
||||
}
|
||||
|
||||
nullify_end(ctx);
|
||||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static bool trans_fldd(DisasContext *ctx, arg_ldst *a)
|
||||
{
|
||||
return do_floadd(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
|
||||
a->disp, a->sp, a->m);
|
||||
}
|
||||
|
||||
static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
|
@ -1643,7 +1654,7 @@ static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
static bool do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
unsigned rx, int scale, target_sreg disp,
|
||||
unsigned sp, int modify)
|
||||
{
|
||||
|
@ -1655,10 +1666,16 @@ static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
|
||||
tcg_temp_free_i32(tmp);
|
||||
|
||||
nullify_end(ctx);
|
||||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
static bool trans_fstw(DisasContext *ctx, arg_ldst *a)
|
||||
{
|
||||
return do_fstorew(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
|
||||
a->disp, a->sp, a->m);
|
||||
}
|
||||
|
||||
static bool do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
|
||||
unsigned rx, int scale, target_sreg disp,
|
||||
unsigned sp, int modify)
|
||||
{
|
||||
|
@ -1670,7 +1687,13 @@ static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
|
|||
do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
|
||||
tcg_temp_free_i64(tmp);
|
||||
|
||||
nullify_end(ctx);
|
||||
return nullify_end(ctx);
|
||||
}
|
||||
|
||||
static bool trans_fstd(DisasContext *ctx, arg_ldst *a)
|
||||
{
|
||||
return do_fstored(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
|
||||
a->disp, a->sp, a->m);
|
||||
}
|
||||
|
||||
static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
|
||||
|
@ -2958,107 +2981,6 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool trans_load(DisasContext *ctx, uint32_t insn,
|
||||
bool is_mod, TCGMemOp mop)
|
||||
{
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
unsigned rt = extract32(insn, 16, 5);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
target_sreg i = assemble_16(insn);
|
||||
|
||||
do_load(ctx, rt, rb, 0, 0, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_load_w(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
unsigned rt = extract32(insn, 16, 5);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
target_sreg i = assemble_16a(insn);
|
||||
unsigned ext2 = extract32(insn, 1, 2);
|
||||
|
||||
switch (ext2) {
|
||||
case 0:
|
||||
case 1:
|
||||
/* FLDW without modification. */
|
||||
do_floadw(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
|
||||
break;
|
||||
case 2:
|
||||
/* LDW with modification. Note that the sign of I selects
|
||||
post-dec vs pre-inc. */
|
||||
do_load(ctx, rt, rb, 0, 0, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
|
||||
break;
|
||||
default:
|
||||
return gen_illegal(ctx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_fload_mod(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
target_sreg i = assemble_16a(insn);
|
||||
unsigned t1 = extract32(insn, 1, 1);
|
||||
unsigned a = extract32(insn, 2, 1);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
unsigned t0 = extract32(insn, 16, 5);
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
|
||||
/* FLDW with modification. */
|
||||
do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_store(DisasContext *ctx, uint32_t insn,
|
||||
bool is_mod, TCGMemOp mop)
|
||||
{
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
unsigned rt = extract32(insn, 16, 5);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
target_sreg i = assemble_16(insn);
|
||||
|
||||
do_store(ctx, rt, rb, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_store_w(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
unsigned rt = extract32(insn, 16, 5);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
target_sreg i = assemble_16a(insn);
|
||||
unsigned ext2 = extract32(insn, 1, 2);
|
||||
|
||||
switch (ext2) {
|
||||
case 0:
|
||||
case 1:
|
||||
/* FSTW without modification. */
|
||||
do_fstorew(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
|
||||
break;
|
||||
case 2:
|
||||
/* STW with modification. */
|
||||
do_store(ctx, rt, rb, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
|
||||
break;
|
||||
default:
|
||||
return gen_illegal(ctx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_fstore_mod(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
target_sreg i = assemble_16a(insn);
|
||||
unsigned t1 = extract32(insn, 1, 1);
|
||||
unsigned a = extract32(insn, 2, 1);
|
||||
unsigned sp = extract32(insn, 14, 2);
|
||||
unsigned t0 = extract32(insn, 16, 5);
|
||||
unsigned rb = extract32(insn, 21, 5);
|
||||
|
||||
/* FSTW with modification. */
|
||||
do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_copr_w(DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
unsigned t0 = extract32(insn, 0, 5);
|
||||
|
@ -4302,43 +4224,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
|
|||
translate_table(ctx, insn, table_float_0e);
|
||||
return;
|
||||
|
||||
case 0x10:
|
||||
trans_load(ctx, insn, false, MO_UB);
|
||||
return;
|
||||
case 0x11:
|
||||
trans_load(ctx, insn, false, MO_TEUW);
|
||||
return;
|
||||
case 0x12:
|
||||
trans_load(ctx, insn, false, MO_TEUL);
|
||||
return;
|
||||
case 0x13:
|
||||
trans_load(ctx, insn, true, MO_TEUL);
|
||||
return;
|
||||
case 0x16:
|
||||
trans_fload_mod(ctx, insn);
|
||||
return;
|
||||
case 0x17:
|
||||
trans_load_w(ctx, insn);
|
||||
return;
|
||||
case 0x18:
|
||||
trans_store(ctx, insn, false, MO_UB);
|
||||
return;
|
||||
case 0x19:
|
||||
trans_store(ctx, insn, false, MO_TEUW);
|
||||
return;
|
||||
case 0x1A:
|
||||
trans_store(ctx, insn, false, MO_TEUL);
|
||||
return;
|
||||
case 0x1B:
|
||||
trans_store(ctx, insn, true, MO_TEUL);
|
||||
return;
|
||||
case 0x1E:
|
||||
trans_fstore_mod(ctx, insn);
|
||||
return;
|
||||
case 0x1F:
|
||||
trans_store_w(ctx, insn);
|
||||
return;
|
||||
|
||||
case 0x2E:
|
||||
translate_table(ctx, insn, table_fp_fused);
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue