return val << 2;
}
+/* Used for assemble_21. */
+static int expand_shl11(int val)
+{
+ return val << 11;
+}
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
return x << 2;
}
-static target_sreg assemble_21(uint32_t insn)
-{
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 11) | extract32(insn, 1, 11);
- x = (x << 2) | extract32(insn, 14, 2);
- x = (x << 5) | extract32(insn, 16, 5);
- x = (x << 2) | extract32(insn, 12, 2);
- return x << 11;
-}
-
/* 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.
return nullify_end(ctx);
}
+static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
+ bool is_tsv, bool is_tc)
+{
+ TCGv_reg tcg_im, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, bool is_tsv, bool is_b,
bool is_tc, unsigned cf)
return nullify_end(ctx);
}
+static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv)
+{
+ TCGv_reg tcg_im, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, unsigned cf)
{
return nullify_end(ctx);
}
-static bool trans_addi(DisasContext *ctx, uint32_t insn)
+static bool trans_addi(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned e1 = extract32(insn, 11, 1);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
- unsigned o1 = extract32(insn, 26, 1);
- TCGv_reg tcg_im, tcg_r2;
-
- if (cf) {
- nullify_over(ctx);
- }
-
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_add(ctx, rt, tcg_im, tcg_r2, 0, false, e1, !o1, false, cf);
+ return do_add_imm(ctx, a, false, false);
+}
- return nullify_end(ctx);
+static bool trans_addi_tsv(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_add_imm(ctx, a, true, false);
}
-static bool trans_subi(DisasContext *ctx, uint32_t insn)
+static bool trans_addi_tc(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned e1 = extract32(insn, 11, 1);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
- TCGv_reg tcg_im, tcg_r2;
+ return do_add_imm(ctx, a, false, true);
+}
- if (cf) {
- nullify_over(ctx);
- }
+static bool trans_addi_tc_tsv(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_add_imm(ctx, a, true, true);
+}
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_sub(ctx, rt, tcg_im, tcg_r2, e1, false, false, cf);
+static bool trans_subi(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_sub_imm(ctx, a, false);
+}
- return nullify_end(ctx);
+static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_sub_imm(ctx, a, true);
}
-static bool trans_cmpiclr(DisasContext *ctx, uint32_t insn)
+static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
TCGv_reg tcg_im, tcg_r2;
- if (cf) {
+ if (a->cf) {
nullify_over(ctx);
}
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_cmpclr(ctx, rt, tcg_im, tcg_r2, cf);
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf);
return nullify_end(ctx);
}
return true;
}
-static bool trans_ldil(DisasContext *ctx, uint32_t insn)
+static bool trans_ldil(DisasContext *ctx, arg_ldil *a)
{
- unsigned rt = extract32(insn, 21, 5);
- target_sreg i = assemble_21(insn);
- TCGv_reg tcg_rt = dest_gpr(ctx, rt);
+ TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
- tcg_gen_movi_reg(tcg_rt, i);
- save_gpr(ctx, rt, tcg_rt);
+ tcg_gen_movi_reg(tcg_rt, a->i);
+ save_gpr(ctx, a->t, tcg_rt);
cond_free(&ctx->null_cond);
return true;
}
-static bool trans_addil(DisasContext *ctx, uint32_t insn)
+static bool trans_addil(DisasContext *ctx, arg_addil *a)
{
- unsigned rt = extract32(insn, 21, 5);
- target_sreg i = assemble_21(insn);
- TCGv_reg tcg_rt = load_gpr(ctx, rt);
+ TCGv_reg tcg_rt = load_gpr(ctx, a->r);
TCGv_reg tcg_r1 = dest_gpr(ctx, 1);
- tcg_gen_addi_reg(tcg_r1, tcg_rt, i);
+ tcg_gen_addi_reg(tcg_r1, tcg_rt, a->i);
save_gpr(ctx, 1, tcg_r1);
cond_free(&ctx->null_cond);
return true;
}
-static bool trans_ldo(DisasContext *ctx, uint32_t insn)
+static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- target_sreg i = assemble_16(insn);
- TCGv_reg tcg_rt = dest_gpr(ctx, rt);
+ TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
/* Special case rb == 0, for the LDI pseudo-op.
The COPY pseudo-op is handled for free within tcg_gen_addi_tl. */
- if (rb == 0) {
- tcg_gen_movi_reg(tcg_rt, i);
+ if (a->b == 0) {
+ tcg_gen_movi_reg(tcg_rt, a->i);
} else {
- tcg_gen_addi_reg(tcg_rt, cpu_gr[rb], i);
+ tcg_gen_addi_reg(tcg_rt, cpu_gr[a->b], a->i);
}
- save_gpr(ctx, rt, tcg_rt);
+ save_gpr(ctx, a->t, tcg_rt);
cond_free(&ctx->null_cond);
return true;
}
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x08:
- trans_ldil(ctx, insn);
- return;
case 0x09:
trans_copr_w(ctx, insn);
return;
- case 0x0A:
- trans_addil(ctx, insn);
- return;
case 0x0B:
trans_copr_dw(ctx, insn);
return;
case 0x0C:
translate_table(ctx, insn, table_float_0c);
return;
- case 0x0D:
- trans_ldo(ctx, insn);
- return;
case 0x0E:
translate_table(ctx, insn, table_float_0e);
return;
trans_store_w(ctx, insn);
return;
- case 0x24:
- trans_cmpiclr(ctx, insn);
- return;
- case 0x25:
- trans_subi(ctx, insn);
- return;
- case 0x2C:
- case 0x2D:
- trans_addi(ctx, insn);
- return;
case 0x2E:
translate_table(ctx, insn, table_fp_fused);
return;