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:
Richard Henderson 2018-02-12 15:54:33 -08:00
parent 0588e061dc
commit 740038d7f5
2 changed files with 99 additions and 165 deletions

View file

@ -24,7 +24,9 @@
%assemble_sr3 13:1 14:2 %assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x %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_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_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 %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 %sm_imm 16:10 !function=expand_sm_imm
%rm64 1:1 16:5
%im5_0 0:s1 1:4 %im5_0 0:s1 1:4
%im5_16 16:s1 17:4 %im5_16 16:s1 17:4
%ma_to_m 5:1 13:1 !function=ma_to_m %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 # Argument set definitions
@ -187,6 +195,47 @@ 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
####
# 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 # Floating-point Multiply Add
#### ####

View file

@ -303,12 +303,29 @@ static int ma_to_m(int val)
return val & 2 ? (val & 1 ? -1 : 1) : 0; 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) static int expand_shl2(int val)
{ {
return val << 2; return val << 2;
} }
/* Used for fp memory ops. */
static int expand_shl3(int val)
{
return val << 3;
}
/* Used for assemble_21. */ /* Used for assemble_21. */
static int expand_shl11(int val) static int expand_shl11(int val)
{ {
@ -883,24 +900,6 @@ static inline unsigned assemble_sr3(uint32_t insn)
return s2 * 4 + s0; 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 parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation. The the conditions, without describing their exact implementation. The
interpretations do not stand up well when considering ADD,C and SUB,B. 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); 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 rx, int scale, target_sreg disp,
unsigned sp, int modify) unsigned sp, int modify)
{ {
@ -1611,10 +1610,16 @@ static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env); 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 rx, int scale, target_sreg disp,
unsigned sp, int modify) unsigned sp, int modify)
{ {
@ -1631,7 +1636,13 @@ static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env); 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, 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); 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 rx, int scale, target_sreg disp,
unsigned sp, int modify) 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); do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
tcg_temp_free_i32(tmp); 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 rx, int scale, target_sreg disp,
unsigned sp, int modify) 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); do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
tcg_temp_free_i64(tmp); 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, 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; 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) static bool trans_copr_w(DisasContext *ctx, uint32_t insn)
{ {
unsigned t0 = extract32(insn, 0, 5); 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); translate_table(ctx, insn, table_float_0e);
return; 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: case 0x2E:
translate_table(ctx, insn, table_fp_fused); translate_table(ctx, insn, table_fp_fused);
return; return;