aboutsummaryrefslogtreecommitdiff
path: root/target/hppa/translate.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2018-02-12 15:54:33 -0800
committerRichard Henderson <richard.henderson@linaro.org>2019-02-12 08:59:21 -0800
commit740038d7f537901d4f8aa0011b6dda098bd59193 (patch)
tree6241701e2e1e10d8363dd1327e64278f76870f8a /target/hppa/translate.c
parent0588e061dc30b267d300068af19edadd72242f93 (diff)
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>
Diffstat (limited to 'target/hppa/translate.c')
-rw-r--r--target/hppa/translate.c215
1 files changed, 50 insertions, 165 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7e4a65e0d5..4ce65bcc61 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -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 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 void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
+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 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 void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
+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;