target/ppc: Move add and subf type fixed-point arithmetic instructions to decodetree
This patch moves the below instructions to decodetree specification: {add, subf}[c,e,me,ze][o][.] : XO-form addic[.], subfic : D-form addex : Z23-form This patch introduces XO form instructions into decode tree specification, for which all the four variations([o][.]) have been handled with a single pattern. The changes were verified by validating that the tcg ops generated by those instructions remain the same, which were captured with the '-d in_asm,op' flag. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com> Signed-off-by: Chinmay Rath <rathc@linux.ibm.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
parent
623d9065b6
commit
a9bd40d937
@ -187,6 +187,12 @@
|
||||
&X_a ra
|
||||
@X_a ...... ra:3 .. ..... ..... .......... . &X_a
|
||||
|
||||
&XO rt ra rb oe:bool rc:bool
|
||||
@XO ...... rt:5 ra:5 rb:5 oe:1 ......... rc:1 &XO
|
||||
|
||||
&XO_ta rt ra oe:bool rc:bool
|
||||
@XO_ta ...... rt:5 ra:5 ..... oe:1 ......... rc:1 &XO_ta
|
||||
|
||||
%xx_xt 0:1 21:5
|
||||
%xx_xb 1:1 11:5
|
||||
%xx_xa 2:1 16:5
|
||||
@ -322,10 +328,30 @@ CMPLI 001010 ... - . ..... ................ @D_bfu
|
||||
|
||||
### Fixed-Point Arithmetic Instructions
|
||||
|
||||
ADD 011111 ..... ..... ..... . 100001010 . @XO
|
||||
ADDC 011111 ..... ..... ..... . 000001010 . @XO
|
||||
ADDE 011111 ..... ..... ..... . 010001010 . @XO
|
||||
|
||||
# ADDEX is Z23-form, with CY=0; all other values for CY are reserved.
|
||||
# This works out the same as X-form.
|
||||
ADDEX 011111 ..... ..... ..... 00 10101010 - @X
|
||||
|
||||
ADDI 001110 ..... ..... ................ @D
|
||||
ADDIS 001111 ..... ..... ................ @D
|
||||
ADDIC 001100 ..... ..... ................ @D
|
||||
ADDIC_ 001101 ..... ..... ................ @D
|
||||
|
||||
ADDPCIS 010011 ..... ..... .......... 00010 . @DX
|
||||
ADDME 011111 ..... ..... ----- . 011101010 . @XO_ta
|
||||
ADDZE 011111 ..... ..... ----- . 011001010 . @XO_ta
|
||||
|
||||
SUBF 011111 ..... ..... ..... . 000101000 . @XO
|
||||
SUBFIC 001000 ..... ..... ................ @D
|
||||
SUBFC 011111 ..... ..... ..... . 000001000 . @XO
|
||||
SUBFE 011111 ..... ..... ..... . 010001000 . @XO
|
||||
|
||||
SUBFME 011111 ..... ..... ----- . 011101000 . @XO_ta
|
||||
SUBFZE 011111 ..... ..... ----- . 011001000 . @XO_ta
|
||||
|
||||
## Fixed-Point Logical Instructions
|
||||
|
||||
|
@ -1735,61 +1735,6 @@ static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
|
||||
tcg_gen_mov_tl(ret, t0);
|
||||
}
|
||||
}
|
||||
/* Add functions with two operands */
|
||||
#define GEN_INT_ARITH_ADD(name, opc3, ca, add_ca, compute_ca, compute_ov) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
|
||||
cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
|
||||
ca, glue(ca, 32), \
|
||||
add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
|
||||
}
|
||||
/* Add functions with one operand and one immediate */
|
||||
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, ca, \
|
||||
add_ca, compute_ca, compute_ov) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv t0 = tcg_constant_tl(const_val); \
|
||||
gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
|
||||
cpu_gpr[rA(ctx->opcode)], t0, \
|
||||
ca, glue(ca, 32), \
|
||||
add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
|
||||
}
|
||||
|
||||
/* add add. addo addo. */
|
||||
GEN_INT_ARITH_ADD(add, 0x08, cpu_ca, 0, 0, 0)
|
||||
GEN_INT_ARITH_ADD(addo, 0x18, cpu_ca, 0, 0, 1)
|
||||
/* addc addc. addco addco. */
|
||||
GEN_INT_ARITH_ADD(addc, 0x00, cpu_ca, 0, 1, 0)
|
||||
GEN_INT_ARITH_ADD(addco, 0x10, cpu_ca, 0, 1, 1)
|
||||
/* adde adde. addeo addeo. */
|
||||
GEN_INT_ARITH_ADD(adde, 0x04, cpu_ca, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD(addeo, 0x14, cpu_ca, 1, 1, 1)
|
||||
/* addme addme. addmeo addmeo. */
|
||||
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, cpu_ca, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, cpu_ca, 1, 1, 1)
|
||||
/* addex */
|
||||
GEN_INT_ARITH_ADD(addex, 0x05, cpu_ov, 1, 1, 0);
|
||||
/* addze addze. addzeo addzeo.*/
|
||||
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, cpu_ca, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, cpu_ca, 1, 1, 1)
|
||||
/* addic addic.*/
|
||||
static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
|
||||
{
|
||||
TCGv c = tcg_constant_tl(SIMM(ctx->opcode));
|
||||
gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
|
||||
c, cpu_ca, cpu_ca32, 0, 1, 0, compute_rc0);
|
||||
}
|
||||
|
||||
static void gen_addic(DisasContext *ctx)
|
||||
{
|
||||
gen_op_addic(ctx, 0);
|
||||
}
|
||||
|
||||
static void gen_addic_(DisasContext *ctx)
|
||||
{
|
||||
gen_op_addic(ctx, 1);
|
||||
}
|
||||
|
||||
static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
|
||||
TCGv arg2, int sign, int compute_ov)
|
||||
@ -2210,47 +2155,6 @@ static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
|
||||
tcg_gen_mov_tl(ret, t0);
|
||||
}
|
||||
}
|
||||
/* Sub functions with Two operands functions */
|
||||
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
|
||||
cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
|
||||
add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
|
||||
}
|
||||
/* Sub functions with one operand and one immediate */
|
||||
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
|
||||
add_ca, compute_ca, compute_ov) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv t0 = tcg_constant_tl(const_val); \
|
||||
gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
|
||||
cpu_gpr[rA(ctx->opcode)], t0, \
|
||||
add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
|
||||
}
|
||||
/* subf subf. subfo subfo. */
|
||||
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
|
||||
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
|
||||
/* subfc subfc. subfco subfco. */
|
||||
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
|
||||
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
|
||||
/* subfe subfe. subfeo subfo. */
|
||||
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
|
||||
/* subfme subfme. subfmeo subfmeo. */
|
||||
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
|
||||
/* subfze subfze. subfzeo subfzeo.*/
|
||||
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
|
||||
|
||||
/* subfic */
|
||||
static void gen_subfic(DisasContext *ctx)
|
||||
{
|
||||
TCGv c = tcg_constant_tl(SIMM(ctx->opcode));
|
||||
gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
|
||||
c, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
/* neg neg. nego nego. */
|
||||
static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
|
||||
@ -6524,8 +6428,6 @@ GEN_HANDLER_E(cmpeqb, 0x1F, 0x00, 0x07, 0x00600000, PPC_NONE, PPC2_ISA300),
|
||||
GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
|
||||
GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
|
||||
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
|
||||
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
|
||||
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
|
||||
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
|
||||
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
|
||||
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
|
||||
@ -6536,7 +6438,6 @@ GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
|
||||
#endif
|
||||
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
|
||||
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
|
||||
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
|
||||
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
|
||||
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
|
||||
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
|
||||
@ -6747,25 +6648,6 @@ GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE,
|
||||
GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
|
||||
#endif
|
||||
|
||||
#undef GEN_INT_ARITH_ADD
|
||||
#undef GEN_INT_ARITH_ADD_CONST
|
||||
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
|
||||
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
|
||||
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
|
||||
add_ca, compute_ca, compute_ov) \
|
||||
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
|
||||
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
|
||||
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
|
||||
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
|
||||
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
|
||||
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
|
||||
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
|
||||
GEN_HANDLER_E(addex, 0x1F, 0x0A, 0x05, 0x00000000, PPC_NONE, PPC2_ISA300),
|
||||
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
|
||||
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
|
||||
|
||||
#undef GEN_INT_ARITH_DIVW
|
||||
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
|
||||
GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
|
||||
@ -6804,24 +6686,6 @@ GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
|
||||
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
|
||||
#endif
|
||||
|
||||
#undef GEN_INT_ARITH_SUBF
|
||||
#undef GEN_INT_ARITH_SUBF_CONST
|
||||
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
|
||||
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
|
||||
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
|
||||
add_ca, compute_ca, compute_ov) \
|
||||
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
|
||||
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
|
||||
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
|
||||
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
|
||||
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
|
||||
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
|
||||
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
|
||||
|
||||
#undef GEN_LOGICAL1
|
||||
#undef GEN_LOGICAL2
|
||||
#define GEN_LOGICAL2(name, tcg_op, opc, type) \
|
||||
|
@ -325,6 +325,76 @@ static bool trans_ADDPCIS(DisasContext *ctx, arg_DX *a)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_ADDEX(DisasContext *ctx, arg_X *a)
|
||||
{
|
||||
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
|
||||
gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
|
||||
cpu_ov, cpu_ov32, true, true, false, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_add_D(DisasContext *ctx, arg_D *a, bool add_ca, bool compute_ca,
|
||||
bool compute_ov, bool compute_rc0)
|
||||
{
|
||||
gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
|
||||
tcg_constant_tl(a->si), cpu_ca, cpu_ca32,
|
||||
add_ca, compute_ca, compute_ov, compute_rc0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_add_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
|
||||
bool compute_ca)
|
||||
{
|
||||
gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
|
||||
cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_add_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
|
||||
bool add_ca, bool compute_ca)
|
||||
{
|
||||
gen_op_arith_add(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
|
||||
cpu_ca, cpu_ca32, add_ca, compute_ca, a->oe, a->rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRANS(ADD, do_add_XO, false, false);
|
||||
TRANS(ADDC, do_add_XO, false, true);
|
||||
TRANS(ADDE, do_add_XO, true, true);
|
||||
TRANS(ADDME, do_add_const_XO, tcg_constant_tl(-1LL), true, true);
|
||||
TRANS(ADDZE, do_add_const_XO, tcg_constant_tl(0), true, true);
|
||||
TRANS(ADDIC, do_add_D, false, true, false, false);
|
||||
TRANS(ADDIC_, do_add_D, false, true, false, true);
|
||||
|
||||
static bool trans_SUBFIC(DisasContext *ctx, arg_D *a)
|
||||
{
|
||||
gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
|
||||
tcg_constant_tl(a->si), false, true, false, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_subf_XO(DisasContext *ctx, arg_XO *a, bool add_ca,
|
||||
bool compute_ca)
|
||||
{
|
||||
gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], cpu_gpr[a->rb],
|
||||
add_ca, compute_ca, a->oe, a->rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_subf_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
|
||||
bool add_ca, bool compute_ca)
|
||||
{
|
||||
gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra], const_val,
|
||||
add_ca, compute_ca, a->oe, a->rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRANS(SUBF, do_subf_XO, false, false)
|
||||
TRANS(SUBFC, do_subf_XO, false, true)
|
||||
TRANS(SUBFE, do_subf_XO, true, true)
|
||||
TRANS(SUBFME, do_subf_const_XO, tcg_constant_tl(-1LL), true, true)
|
||||
TRANS(SUBFZE, do_subf_const_XO, tcg_constant_tl(0), true, true)
|
||||
|
||||
static bool trans_INVALID(DisasContext *ctx, arg_INVALID *a)
|
||||
{
|
||||
gen_invalid(ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user