142
gen_helper_mtvscr(tcg_env, val);
143
}
144
145
-static void gen_vx_vmul10(DisasContext *ctx, bool add_cin, bool ret_carry)
145
+static bool do_vx_vmul10(DisasContext *ctx, arg_VX *a,
146
+ bool add_cin, bool ret_carry)
147
{
148
TCGv_i64 t0;
149
TCGv_i64 t1;
151
TCGv_i64 avr;
152
TCGv_i64 ten, z;
153
153
- if (unlikely(!ctx->altivec_enabled)) {
154
- gen_exception(ctx, POWERPC_EXCP_VPU);
155
- return;
156
- }
154
+ REQUIRE_VECTOR(ctx);
155
156
t0 = tcg_temp_new_i64();
157
t1 = tcg_temp_new_i64();
161
z = tcg_constant_i64(0);
162
163
if (add_cin) {
166
- get_avr64(avr, rA(ctx->opcode), false);
164
+ get_avr64(avr, a->vra, false);
165
tcg_gen_mulu2_i64(t0, t1, avr, ten);
168
- get_avr64(avr, rB(ctx->opcode), false);
166
+ get_avr64(avr, a->vrb, false);
167
tcg_gen_andi_i64(t2, avr, 0xF);
168
tcg_gen_add2_i64(avr, t2, t0, t1, t2, z);
171
- set_avr64(rD(ctx->opcode), avr, false);
169
+ set_avr64(a->vrt, avr, false);
170
} else {
173
- get_avr64(avr, rA(ctx->opcode), false);
171
+ get_avr64(avr, a->vra, false);
172
tcg_gen_mulu2_i64(avr, t2, avr, ten);
175
- set_avr64(rD(ctx->opcode), avr, false);
173
+ set_avr64(a->vrt, avr, false);
174
}
175
176
if (ret_carry) {
179
- get_avr64(avr, rA(ctx->opcode), true);
177
+ get_avr64(avr, a->vra, true);
178
tcg_gen_mulu2_i64(t0, t1, avr, ten);
179
tcg_gen_add2_i64(t0, avr, t0, t1, t2, z);
182
- set_avr64(rD(ctx->opcode), avr, false);
183
- set_avr64(rD(ctx->opcode), z, true);
180
+ set_avr64(a->vrt, avr, false);
181
+ set_avr64(a->vrt, z, true);
182
} else {
185
- get_avr64(avr, rA(ctx->opcode), true);
183
+ get_avr64(avr, a->vra, true);
184
tcg_gen_mul_i64(t0, avr, ten);
185
tcg_gen_add_i64(avr, t0, t2);
188
- set_avr64(rD(ctx->opcode), avr, true);
186
+ set_avr64(a->vrt, avr, true);
187
}
190
-}
191
-
192
-#define GEN_VX_VMUL10(name, add_cin, ret_carry) \
193
- static void glue(gen_, name)(DisasContext *ctx) \
194
- { gen_vx_vmul10(ctx, add_cin, ret_carry); }
195
-
196
-GEN_VX_VMUL10(vmul10uq, 0, 0);
197
-GEN_VX_VMUL10(vmul10euq, 1, 0);
198
-GEN_VX_VMUL10(vmul10cuq, 0, 1);
199
-GEN_VX_VMUL10(vmul10ecuq, 1, 1);
188
201
-#define GEN_VXFORM_V(name, vece, tcg_op, opc2, opc3) \
202
-static void glue(gen_, name)(DisasContext *ctx) \
203
-{ \
204
- if (unlikely(!ctx->altivec_enabled)) { \
205
- gen_exception(ctx, POWERPC_EXCP_VPU); \
206
- return; \
207
- } \
208
- \
209
- tcg_op(vece, \
210
- avr_full_offset(rD(ctx->opcode)), \
211
- avr_full_offset(rA(ctx->opcode)), \
212
- avr_full_offset(rB(ctx->opcode)), \
213
- 16, 16); \
189
+ return true;
190
}
191
192
#define GEN_VXFORM(name, opc2, opc3) \
314
gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], rb); \
315
}
316
341
-GEN_VXFORM_V(vaddubm, MO_8, tcg_gen_gvec_add, 0, 0);
342
-GEN_VXFORM_DUAL_EXT(vaddubm, PPC_ALTIVEC, PPC_NONE, 0, \
343
- vmul10cuq, PPC_NONE, PPC2_ISA300, 0x0000F800)
344
-GEN_VXFORM_V(vadduhm, MO_16, tcg_gen_gvec_add, 0, 1);
345
-GEN_VXFORM_DUAL(vadduhm, PPC_ALTIVEC, PPC_NONE, \
346
- vmul10ecuq, PPC_NONE, PPC2_ISA300)
347
-GEN_VXFORM_V(vadduwm, MO_32, tcg_gen_gvec_add, 0, 2);
348
-GEN_VXFORM_V(vaddudm, MO_64, tcg_gen_gvec_add, 0, 3);
349
-GEN_VXFORM_V(vsububm, MO_8, tcg_gen_gvec_sub, 0, 16);
350
-GEN_VXFORM_V(vsubuhm, MO_16, tcg_gen_gvec_sub, 0, 17);
351
-GEN_VXFORM_V(vsubuwm, MO_32, tcg_gen_gvec_sub, 0, 18);
352
-GEN_VXFORM_V(vsubudm, MO_64, tcg_gen_gvec_sub, 0, 19);
353
-
317
static bool do_vmrg(DisasContext *ctx, arg_VX *a,
318
void (*helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr))
319
{
333
TRANS_FLAGS(ALTIVEC, VMRGLH, do_vmrg, gen_helper_VMRGLH);
334
TRANS_FLAGS(ALTIVEC, VMRGLW, do_vmrg, gen_helper_VMRGLW);
335
336
+static bool do_vx_vaddsubm(DisasContext *ctx, arg_VX *a, MemOp vece,
337
+ void (*gen_op)(unsigned, uint32_t, uint32_t,
338
+ uint32_t, uint32_t, uint32_t))
339
+{
340
+ REQUIRE_VECTOR(ctx);
341
+
342
+ gen_op(vece,
343
+ avr_full_offset(a->vrt),
344
+ avr_full_offset(a->vra),
345
+ avr_full_offset(a->vrb),
346
+ 16, 16);
347
+
348
+ return true;
349
+}
350
+
351
+TRANS_FLAGS(ALTIVEC, VADDUBM, do_vx_vaddsubm, MO_8, tcg_gen_gvec_add)
352
+TRANS_FLAGS(ALTIVEC, VADDUHM, do_vx_vaddsubm, MO_16, tcg_gen_gvec_add)
353
+TRANS_FLAGS(ALTIVEC, VADDUWM, do_vx_vaddsubm, MO_32, tcg_gen_gvec_add)
354
+TRANS_FLAGS2(ALTIVEC_207, VADDUDM, do_vx_vaddsubm, MO_64, tcg_gen_gvec_add)
355
+
356
+TRANS_FLAGS(ALTIVEC, VSUBUBM, do_vx_vaddsubm, MO_8, tcg_gen_gvec_sub)
357
+TRANS_FLAGS(ALTIVEC, VSUBUHM, do_vx_vaddsubm, MO_16, tcg_gen_gvec_sub)
358
+TRANS_FLAGS(ALTIVEC, VSUBUWM, do_vx_vaddsubm, MO_32, tcg_gen_gvec_sub)
359
+TRANS_FLAGS2(ALTIVEC_207, VSUBUDM, do_vx_vaddsubm, MO_64, tcg_gen_gvec_sub)
360
+
361
+TRANS_FLAGS2(ALTIVEC_207, VMULUWM, do_vx_vaddsubm, MO_32, tcg_gen_gvec_mul)
362
+
363
+TRANS_FLAGS2(ISA300, VMUL10CUQ, do_vx_vmul10, false, true)
364
+TRANS_FLAGS2(ISA300, VMUL10ECUQ, do_vx_vmul10, true, true)
365
+TRANS_FLAGS2(ISA300, VMUL10UQ, do_vx_vmul10, false, false)
366
+TRANS_FLAGS2(ISA300, VMUL10EUQ, do_vx_vmul10, true, false)
367
+
368
static void trans_vmrgew(DisasContext *ctx)
369
{
370
int VT = rD(ctx->opcode);
679
set_avr64(VT, avr, false);
680
}
681
687
-GEN_VXFORM_V(vmuluwm, MO_32, tcg_gen_gvec_mul, 4, 2);
682
GEN_VXFORM(vsrv, 2, 28);
683
GEN_VXFORM(vslv, 2, 29);
684
GEN_VXFORM(vslo, 6, 16);
2517
GEN_VXFORM(vpmsumh, 4, 17)
2518
GEN_VXFORM(vpmsumw, 4, 18)
2519
2526
-#define GEN_BCD(op) \
2527
-static void gen_##op(DisasContext *ctx) \
2528
-{ \
2529
- TCGv_ptr ra, rb, rd; \
2530
- TCGv_i32 ps; \
2531
- \
2532
- if (unlikely(!ctx->altivec_enabled)) { \
2533
- gen_exception(ctx, POWERPC_EXCP_VPU); \
2534
- return; \
2535
- } \
2536
- \
2537
- ra = gen_avr_ptr(rA(ctx->opcode)); \
2538
- rb = gen_avr_ptr(rB(ctx->opcode)); \
2539
- rd = gen_avr_ptr(rD(ctx->opcode)); \
2540
- \
2541
- ps = tcg_constant_i32((ctx->opcode & 0x200) != 0); \
2542
- \
2543
- gen_helper_##op(cpu_crf[6], rd, ra, rb, ps); \
2544
-}
2545
-
2546
-#define GEN_BCD2(op) \
2547
-static void gen_##op(DisasContext *ctx) \
2548
-{ \
2549
- TCGv_ptr rd, rb; \
2550
- TCGv_i32 ps; \
2551
- \
2552
- if (unlikely(!ctx->altivec_enabled)) { \
2553
- gen_exception(ctx, POWERPC_EXCP_VPU); \
2554
- return; \
2555
- } \
2556
- \
2557
- rb = gen_avr_ptr(rB(ctx->opcode)); \
2558
- rd = gen_avr_ptr(rD(ctx->opcode)); \
2559
- \
2560
- ps = tcg_constant_i32((ctx->opcode & 0x200) != 0); \
2561
- \
2562
- gen_helper_##op(cpu_crf[6], rd, rb, ps); \
2563
-}
2564
-
2565
-GEN_BCD(bcdadd)
2566
-GEN_BCD(bcdsub)
2567
-GEN_BCD2(bcdcfn)
2568
-GEN_BCD2(bcdctn)
2569
-GEN_BCD2(bcdcfz)
2570
-GEN_BCD2(bcdctz)
2571
-GEN_BCD2(bcdcfsq)
2572
-GEN_BCD2(bcdctsq)
2573
-GEN_BCD2(bcdsetsgn)
2574
-GEN_BCD(bcdcpsgn);
2575
-GEN_BCD(bcds);
2576
-GEN_BCD(bcdus);
2577
-GEN_BCD(bcdsr);
2578
-GEN_BCD(bcdtrunc);
2579
-GEN_BCD(bcdutrunc);
2580
-
2581
-static void gen_xpnd04_1(DisasContext *ctx)
2582
-{
2583
- switch (opc4(ctx->opcode)) {
2584
- case 0:
2585
- gen_bcdctsq(ctx);
2586
- break;
2587
- case 2:
2588
- gen_bcdcfsq(ctx);
2589
- break;
2590
- case 4:
2591
- gen_bcdctz(ctx);
2592
- break;
2593
- case 5:
2594
- gen_bcdctn(ctx);
2595
- break;
2596
- case 6:
2597
- gen_bcdcfz(ctx);
2598
- break;
2599
- case 7:
2600
- gen_bcdcfn(ctx);
2601
- break;
2602
- case 31:
2603
- gen_bcdsetsgn(ctx);
2604
- break;
2605
- default:
2606
- gen_invalid(ctx);
2607
- break;
2608
- }
2520
+static bool do_bcd_ps(DisasContext *ctx, arg_VX_ps *a,
2521
+ void (*helper)(TCGv_i32, TCGv_ptr, TCGv_ptr,
2522
+ TCGv_ptr, TCGv_i32))
2523
+{
2524
+ TCGv_ptr ra, rb, rd;
2525
+ TCGv_i32 ps;
2526
+
2527
+ REQUIRE_VECTOR(ctx);
2528
+
2529
+ ra = gen_avr_ptr(a->vra);
2530
+ rb = gen_avr_ptr(a->vrb);
2531
+ rd = gen_avr_ptr(a->vrt);
2532
+ ps = tcg_constant_i32(a->ps);
2533
+
2534
+ helper(cpu_crf[6], rd, ra, rb, ps);
2535
+ return true;
2536
}
2537
2611
-static void gen_xpnd04_2(DisasContext *ctx)
2612
-{
2613
- switch (opc4(ctx->opcode)) {
2614
- case 0:
2615
- gen_bcdctsq(ctx);
2616
- break;
2617
- case 2:
2618
- gen_bcdcfsq(ctx);
2619
- break;
2620
- case 4:
2621
- gen_bcdctz(ctx);
2622
- break;
2623
- case 6:
2624
- gen_bcdcfz(ctx);
2625
- break;
2626
- case 7:
2627
- gen_bcdcfn(ctx);
2628
- break;
2629
- case 31:
2630
- gen_bcdsetsgn(ctx);
2631
- break;
2632
- default:
2633
- gen_invalid(ctx);
2634
- break;
2635
- }
2538
+static bool do_bcd(DisasContext *ctx, arg_VX *a,
2539
+ void (*helper)(TCGv_i32, TCGv_ptr, TCGv_ptr,
2540
+ TCGv_ptr, TCGv_i32))
2541
+{
2542
+ TCGv_ptr ra, rb, rd;
2543
+ TCGv_i32 ps;
2544
+
2545
+ REQUIRE_VECTOR(ctx);
2546
+
2547
+ ra = gen_avr_ptr(a->vra);
2548
+ rb = gen_avr_ptr(a->vrb);
2549
+ rd = gen_avr_ptr(a->vrt);
2550
+ ps = tcg_constant_i32(0);
2551
+
2552
+ helper(cpu_crf[6], rd, ra, rb, ps);
2553
+ return true;
2554
}
2555
2638
-GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
2639
- bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
2640
-GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
2641
- bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
2642
-GEN_VXFORM_DUAL(vsubudm, PPC2_ALTIVEC_207, PPC_NONE, \
2643
- bcds, PPC_NONE, PPC2_ISA300)
2644
-GEN_VXFORM_DUAL(vsubuwm, PPC_ALTIVEC, PPC_NONE, \
2645
- bcdus, PPC_NONE, PPC2_ISA300)
2556
+static bool do_bcd_tb(DisasContext *ctx, arg_VX_tb *a,
2557
+ void (*helper)(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32))
2558
+{
2559
+ TCGv_ptr rd, rb;
2560
+ TCGv_i32 ps;
2561
+
2562
+ REQUIRE_VECTOR(ctx);
2563
+
2564
+ rb = gen_avr_ptr(a->vrb);
2565
+ rd = gen_avr_ptr(a->vrt);
2566
+
2567
+ ps = tcg_constant_i32(0);
2568
+
2569
+ helper(cpu_crf[6], rd, rb, ps);
2570
+
2571
+ return true;
2572
+}
2573
+
2574
+static bool do_bcd_tb_ps(DisasContext *ctx, arg_VX_tb_ps *a,
2575
+ void (*helper)(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32))
2576
+{
2577
+ TCGv_ptr rd, rb;
2578
+ TCGv_i32 ps;
2579
+
2580
+ REQUIRE_VECTOR(ctx);
2581
+
2582
+ rb = gen_avr_ptr(a->vrb);
2583
+ rd = gen_avr_ptr(a->vrt);
2584
+
2585
+ ps = tcg_constant_i32(a->ps);
2586
+
2587
+ helper(cpu_crf[6], rd, rb, ps);
2588
+
2589
+ return true;
2590
+}
2591
+
2592
+TRANS_FLAGS2(ALTIVEC_207, BCDADD, do_bcd_ps, gen_helper_BCDADD)
2593
+TRANS_FLAGS2(ALTIVEC_207, BCDSUB, do_bcd_ps, gen_helper_BCDSUB)
2594
+TRANS_FLAGS2(ISA300, BCDUS, do_bcd, gen_helper_BCDUS)
2595
+TRANS_FLAGS2(ISA300, BCDS, do_bcd_ps, gen_helper_BCDS)
2596
+TRANS_FLAGS2(ISA300, BCDCFN, do_bcd_tb_ps, gen_helper_BCDCFN)
2597
+TRANS_FLAGS2(ISA300, BCDCTN, do_bcd_tb, gen_helper_BCDCTN)
2598
+TRANS_FLAGS2(ISA300, BCDCFZ, do_bcd_tb_ps, gen_helper_BCDCFZ)
2599
+TRANS_FLAGS2(ISA300, BCDCTZ, do_bcd_tb_ps, gen_helper_BCDCTZ)
2600
+TRANS_FLAGS2(ISA300, BCDCFSQ, do_bcd_tb_ps, gen_helper_BCDCFSQ)
2601
+TRANS_FLAGS2(ISA300, BCDCTSQ, do_bcd_tb, gen_helper_BCDCTSQ)
2602
+TRANS_FLAGS2(ISA300, BCDSETSGN, do_bcd_tb_ps, gen_helper_BCDSETSGN)
2603
+TRANS_FLAGS2(ISA300, BCDCPSGN, do_bcd, gen_helper_BCDCPSGN)
2604
+TRANS_FLAGS2(ISA300, BCDTRUNC, do_bcd_ps, gen_helper_BCDTRUNC)
2605
+TRANS_FLAGS2(ISA300, BCDUTRUNC, do_bcd, gen_helper_BCDUTRUNC)
2606
+TRANS_FLAGS2(ISA300, BCDSR, do_bcd_ps, gen_helper_BCDSR)
2607
2608
static void gen_vsbox(DisasContext *ctx)
2609
{
3463
#undef GEN_VXFORM_NOA
3464
#undef GEN_VXFORM_UIMM
3465
#undef GEN_VAFORM_PAIRED
3505
-
3506
-#undef GEN_BCD2