@@ -315,12 +315,29 @@ static int ma_to_m(int val)
return val & 2 ? (val & 1 ? -1 : 1) : 0;
}
-/* Used for branch targets. */
+/* Covert 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)
{
@@ -889,24 +906,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.
@@ -1620,6 +1619,11 @@ static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_end(ctx);
}
+static void trans_fldw(DisasContext *ctx, arg_ldst *a, uint32_t insn)
+{
+ do_floadw(ctx, a->t, a->b, a->x, a->scale * 4, a->disp, a->sp, a->m);
+}
+
static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
@@ -1640,6 +1644,11 @@ static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_end(ctx);
}
+static void trans_fldd(DisasContext *ctx, arg_ldst *a, uint32_t insn)
+{
+ do_floadd(ctx, a->t, a->b, a->x, a->scale * 8, a->disp, a->sp, a->m);
+}
+
static void do_store(DisasContext *ctx, unsigned rt, unsigned rb,
target_sreg disp, unsigned sp,
int modify, TCGMemOp mop)
@@ -1664,6 +1673,11 @@ static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_end(ctx);
}
+static void trans_fstw(DisasContext *ctx, arg_ldst *a, uint32_t insn)
+{
+ do_fstorew(ctx, a->t, a->b, a->x, a->scale * 4, a->disp, a->sp, a->m);
+}
+
static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
@@ -1679,6 +1693,11 @@ static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_end(ctx);
}
+static void trans_fstd(DisasContext *ctx, arg_ldst *a, uint32_t insn)
+{
+ do_fstored(ctx, a->t, a->b, a->x, a->scale * 8, a->disp, a->sp, a->m);
+}
+
static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
@@ -2846,7 +2865,7 @@ static void trans_ld(DisasContext *ctx, arg_ldst *a, uint32_t insn)
static void trans_st(DisasContext *ctx, arg_ldst *a, uint32_t insn)
{
- assert(a->scale == 0);
+ assert(a->x == 0 && a->scale == 0);
do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size | MO_TE);
}
@@ -2963,103 +2982,6 @@ static void trans_ldo(DisasContext *ctx, arg_ldo *a, uint32_t insn)
cond_free(&ctx->null_cond);
}
-static void 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);
-}
-
-static void 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:
- gen_illegal(ctx);
- break;
- }
-}
-
-static void 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));
-}
-
-static void 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);
-}
-
-static void 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:
- gen_illegal(ctx);
- break;
- }
-}
-
-static void 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));
-}
-
static void trans_copr_w(DisasContext *ctx, uint32_t insn)
{
unsigned t0 = extract32(insn, 0, 5);
@@ -4294,43 +4216,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;
@@ -24,7 +24,9 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
+%assemble_11a 0:s1 4:10 !function=expand_shl3
%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
+%assemble_12a 0:s1 3:11 !function=expand_shl2
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
@@ -35,9 +37,15 @@
%sm_imm 16:10 !function=expand_sm_imm
+%rm64 1:1 16:5
+
%im5_0 0:s1 1:4
%im5_16 16:s1 17:4
%ma_to_m 5:1 13:1 !function=ma_to_m
+%ma2_to_m 2:2 !function=ma_to_m
+%pos_to_m 0:1 !function=pos_to_m
+%neg_to_m 0:1 !function=neg_to_m
+%a_to_m 2:1 !function=neg_to_m
####
# Argument set definitions
@@ -185,6 +193,47 @@ lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx 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
+####
+# Offset Mem
+####
+
+@ldstim14 ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%lowsign_14 x=0 scale=0 m=0
+@ldstim14m ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%lowsign_14 x=0 scale=0 m=%neg_to_m
+@ldstim12m ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%assemble_12a x=0 scale=0 m=%pos_to_m
+
+# LDB, LDH, LDW, LDWM
+ld 010000 ..... ..... .. .............. @ldstim14 size=0
+ld 010001 ..... ..... .. .............. @ldstim14 size=1
+ld 010010 ..... ..... .. .............. @ldstim14 size=2
+ld 010011 ..... ..... .. .............. @ldstim14m size=2
+ld 010111 ..... ..... .. ...........10. @ldstim12m size=2
+
+# STB, STH, STW, STWM
+st 011000 ..... ..... .. .............. @ldstim14 size=0
+st 011001 ..... ..... .. .............. @ldstim14 size=1
+st 011010 ..... ..... .. .............. @ldstim14 size=2
+st 011011 ..... ..... .. .............. @ldstim14m size=2
+st 011111 ..... ..... .. ...........10. @ldstim12m size=2
+
+fldw 010110 b:5 ..... sp:2 .............. \
+ &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fldw 010111 b:5 ..... sp:2 ...........0.. \
+ &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+
+fstw 011110 b:5 ..... sp:2 .............. \
+ &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fstw 011111 b:5 ..... sp:2 ...........0.. \
+ &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+
+fldd 010100 b:5 t:5 sp:2 .......... .. 1 . \
+ &ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+
+fstd 011100 b:5 t:5 sp:2 .......... .. 1 . \
+ &ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+
####
# Floating-point Multiply Add
####
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/hppa/translate.c | 193 ++++++++++------------------------------------- target/hppa/insns.decode | 49 ++++++++++++ 2 files changed, 88 insertions(+), 154 deletions(-) -- 2.14.3