4298
4299
/*** Cache management ***/
4300
4301
-/* dcbf */
4302
-static void gen_dcbf(DisasContext *ctx)
4303
-{
4304
- /* XXX: specification says this is treated as a load by the MMU */
4305
- TCGv t0;
4306
- gen_set_access_type(ctx, ACCESS_CACHE);
4307
- t0 = tcg_temp_new();
4308
- gen_addr_reg_index(ctx, t0);
4309
- gen_qemu_ld8u(ctx, t0, t0);
4310
-}
4311
-
4312
-/* dcbfep (external PID dcbf) */
4313
-static void gen_dcbfep(DisasContext *ctx)
4314
-{
4315
- /* XXX: specification says this is treated as a load by the MMU */
4316
- TCGv t0;
4317
- CHK_SV(ctx);
4318
- gen_set_access_type(ctx, ACCESS_CACHE);
4319
- t0 = tcg_temp_new();
4320
- gen_addr_reg_index(ctx, t0);
4321
- tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4322
-}
4323
-
4324
-/* dcbi (Supervisor only) */
4325
-static void gen_dcbi(DisasContext *ctx)
4326
-{
4327
-#if defined(CONFIG_USER_ONLY)
4328
- GEN_PRIV(ctx);
4329
-#else
4330
- TCGv EA, val;
4331
-
4332
- CHK_SV(ctx);
4333
- EA = tcg_temp_new();
4334
- gen_set_access_type(ctx, ACCESS_CACHE);
4335
- gen_addr_reg_index(ctx, EA);
4336
- val = tcg_temp_new();
4337
- /* XXX: specification says this should be treated as a store by the MMU */
4338
- gen_qemu_ld8u(ctx, val, EA);
4339
- gen_qemu_st8(ctx, val, EA);
4340
-#endif /* defined(CONFIG_USER_ONLY) */
4341
-}
4342
-
4343
-/* dcdst */
4344
-static void gen_dcbst(DisasContext *ctx)
4345
-{
4346
- /* XXX: specification say this is treated as a load by the MMU */
4347
- TCGv t0;
4348
- gen_set_access_type(ctx, ACCESS_CACHE);
4349
- t0 = tcg_temp_new();
4350
- gen_addr_reg_index(ctx, t0);
4351
- gen_qemu_ld8u(ctx, t0, t0);
4352
-}
4353
-
4354
-/* dcbstep (dcbstep External PID version) */
4355
-static void gen_dcbstep(DisasContext *ctx)
4356
-{
4357
- /* XXX: specification say this is treated as a load by the MMU */
4358
- TCGv t0;
4359
- gen_set_access_type(ctx, ACCESS_CACHE);
4360
- t0 = tcg_temp_new();
4361
- gen_addr_reg_index(ctx, t0);
4362
- tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4363
-}
4364
-
4365
-/* dcbt */
4366
-static void gen_dcbt(DisasContext *ctx)
4367
-{
4368
- /*
4369
- * interpreted as no-op
4370
- * XXX: specification say this is treated as a load by the MMU but
4371
- * does not generate any exception
4372
- */
4373
-}
4374
-
4375
-/* dcbtep */
4376
-static void gen_dcbtep(DisasContext *ctx)
4377
-{
4378
- /*
4379
- * interpreted as no-op
4380
- * XXX: specification say this is treated as a load by the MMU but
4381
- * does not generate any exception
4382
- */
4383
-}
4384
-
4385
-/* dcbtst */
4386
-static void gen_dcbtst(DisasContext *ctx)
4387
-{
4388
- /*
4389
- * interpreted as no-op
4390
- * XXX: specification say this is treated as a load by the MMU but
4391
- * does not generate any exception
4392
- */
4393
-}
4394
-
4395
-/* dcbtstep */
4396
-static void gen_dcbtstep(DisasContext *ctx)
4397
-{
4398
- /*
4399
- * interpreted as no-op
4400
- * XXX: specification say this is treated as a load by the MMU but
4401
- * does not generate any exception
4402
- */
4403
-}
4404
-
4405
-/* dcbtls */
4406
-static void gen_dcbtls(DisasContext *ctx)
4407
-{
4408
- /* Always fails locking the cache */
4409
- TCGv t0 = tcg_temp_new();
4410
- gen_load_spr(t0, SPR_Exxx_L1CSR0);
4411
- tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4412
- gen_store_spr(SPR_Exxx_L1CSR0, t0);
4413
-}
4414
-
4415
-/* dcblc */
4416
-static void gen_dcblc(DisasContext *ctx)
4417
-{
4418
- /*
4419
- * interpreted as no-op
4420
- */
4421
-}
4422
-
4301
/* dcbz */
4302
static void gen_dcbz(DisasContext *ctx)
4303
{
4326
gen_helper_dcbz(tcg_env, tcgv_addr, tcg_constant_i32(PPC_TLB_EPID_STORE));
4327
}
4328
4451
-/* dst / dstt */
4452
-static void gen_dst(DisasContext *ctx)
4453
-{
4454
- if (rA(ctx->opcode) == 0) {
4455
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4456
- } else {
4457
- /* interpreted as no-op */
4458
- }
4459
-}
4460
-
4461
-/* dstst /dststt */
4462
-static void gen_dstst(DisasContext *ctx)
4463
-{
4464
- if (rA(ctx->opcode) == 0) {
4465
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4466
- } else {
4467
- /* interpreted as no-op */
4468
- }
4469
-
4470
-}
4471
-
4472
-/* dss / dssall */
4473
-static void gen_dss(DisasContext *ctx)
4474
-{
4475
- /* interpreted as no-op */
4476
-}
4477
-
4478
-/* icbi */
4479
-static void gen_icbi(DisasContext *ctx)
4480
-{
4481
- TCGv t0;
4482
- gen_set_access_type(ctx, ACCESS_CACHE);
4483
- t0 = tcg_temp_new();
4484
- gen_addr_reg_index(ctx, t0);
4485
- gen_helper_icbi(tcg_env, t0);
4486
-}
4487
-
4488
-/* icbiep */
4489
-static void gen_icbiep(DisasContext *ctx)
4490
-{
4491
- TCGv t0;
4492
- gen_set_access_type(ctx, ACCESS_CACHE);
4493
- t0 = tcg_temp_new();
4494
- gen_addr_reg_index(ctx, t0);
4495
- gen_helper_icbiep(tcg_env, t0);
4496
-}
4497
-
4498
-/* Optional: */
4499
-/* dcba */
4500
-static void gen_dcba(DisasContext *ctx)
4501
-{
4502
- /*
4503
- * interpreted as no-op
4504
- * XXX: specification say this is treated as a store by the MMU
4505
- * but does not generate any exception
4506
- */
4507
-}
4508
-
4329
/*** Segment register manipulation ***/
4330
/* Supervisor only: */
4331
5560
return true;
5561
}
5562
5563
+/*
5564
+ * Cache Management Instructions (decodetree)
5565
+ */
5566
+
5567
+static bool trans_DCBA(DisasContext *ctx, arg_X_ea *a)
5568
+{
5569
+ REQUIRE_INSNS_FLAGS(ctx, CACHE_DCBA);
5570
+ return true;
5571
+}
5572
+
5573
+static bool trans_DCBT(DisasContext *ctx, arg_X_th *a)
5574
+{
5575
+ REQUIRE_INSNS_FLAGS(ctx, CACHE);
5576
+ return true;
5577
+}
5578
+
5579
+static bool trans_DCBTEP(DisasContext *ctx, arg_X_ea *a)
5580
+{
5581
+ REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
5582
+ return true;
5583
+}
5584
+
5585
+static bool trans_DCBTST(DisasContext *ctx, arg_X_th *a)
5586
+{
5587
+ REQUIRE_INSNS_FLAGS(ctx, CACHE);
5588
+ return true;
5589
+}
5590
+
5591
+static bool trans_DCBTSTEP(DisasContext *ctx, arg_X_ea *a)
5592
+{
5593
+ REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
5594
+ return true;
5595
+}
5596
+
5597
+static bool trans_DCBLC(DisasContext *ctx, arg_X_th *a)
5598
+{
5599
+ /* Requires either PPC_BOOKE or PPC2_BOOKE206 */
5600
+ if (!(ctx->insns_flags & PPC_BOOKE) &&
5601
+ !(ctx->insns_flags2 & PPC2_BOOKE206)) {
5602
+ return false;
5603
+ }
5604
+ return true;
5605
+}
5606
+
5607
+static bool trans_DSS(DisasContext *ctx, arg_X_ea *a)
5608
+{
5609
+ REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
5610
+ return true;
5611
+}
5612
+
5613
+static bool trans_DCBTLS(DisasContext *ctx, arg_X_th *a)
5614
+{
5615
+ TCGv t0 = tcg_temp_new();
5616
+
5617
+ /* Requires either PPC_BOOKE or PPC2_BOOKE206 */
5618
+ if (!(ctx->insns_flags & PPC_BOOKE) &&
5619
+ !(ctx->insns_flags2 & PPC2_BOOKE206)) {
5620
+ return false;
5621
+ }
5622
+
5623
+ gen_load_spr(t0, SPR_Exxx_L1CSR0);
5624
+ tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
5625
+ gen_store_spr(SPR_Exxx_L1CSR0, t0);
5626
+
5627
+ return true;
5628
+}
5629
+
5630
+static bool trans_DST(DisasContext *ctx, arg_X_ea *a)
5631
+{
5632
+ REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
5633
+
5634
+ if (a->ra == 0) {
5635
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5636
+ }
5637
+
5638
+ return true;
5639
+}
5640
+
5641
+static bool trans_DSTST(DisasContext *ctx, arg_X_ea *a)
5642
+{
5643
+ REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
5644
+
5645
+ if (a->ra == 0) {
5646
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5647
+ }
5648
+
5649
+ return true;
5650
+}
5651
+
5652
+static bool trans_DCBF(DisasContext *ctx, arg_X_l *a)
5653
+{
5654
+ TCGv EA;
5655
+
5656
+ REQUIRE_INSNS_FLAGS(ctx, CACHE);
5657
+
5658
+ /*
5659
+ * As per PowerISA v3.1, the L field can have values 0, 1, 3, 4, or 6.
5660
+ * Other values are Undefined Behavior (UB).
5661
+ */
5662
+ switch (a->l) {
5663
+ case 0: /* dcbf */
5664
+ case 1: /* dcbfl */
5665
+ case 3: /* dcbflp */
5666
+ case 4: /* dcbfps */
5667
+ case 6: /* dcbstps */
5668
+ break;
5669
+ default:
5670
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5671
+ return true;
5672
+ }
5673
+
5674
+ gen_set_access_type(ctx, ACCESS_CACHE);
5675
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5676
+ gen_qemu_ld8u(ctx, EA, EA);
5677
+
5678
+ return true;
5679
+}
5680
+
5681
+static bool trans_DCBST(DisasContext *ctx, arg_X_ea *a)
5682
+{
5683
+ TCGv EA;
5684
+
5685
+ REQUIRE_INSNS_FLAGS(ctx, CACHE);
5686
+
5687
+ gen_set_access_type(ctx, ACCESS_CACHE);
5688
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5689
+ gen_qemu_ld8u(ctx, EA, EA);
5690
+
5691
+ return true;
5692
+}
5693
+
5694
+static bool trans_DCBFEP(DisasContext *ctx, arg_X_ea *a)
5695
+{
5696
+ TCGv EA;
5697
+
5698
+ REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
5699
+
5700
+ REQUIRE_SV(ctx);
5701
+
5702
+ gen_set_access_type(ctx, ACCESS_CACHE);
5703
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5704
+
5705
+ tcg_gen_qemu_ld_tl(EA, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
5706
+
5707
+ return true;
5708
+}
5709
+
5710
+static bool trans_DCBSTEP(DisasContext *ctx, arg_X_ea *a)
5711
+{
5712
+ TCGv EA;
5713
+
5714
+ REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
5715
+
5716
+ gen_set_access_type(ctx, ACCESS_CACHE);
5717
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5718
+
5719
+ tcg_gen_qemu_ld_tl(EA, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
5720
+
5721
+ return true;
5722
+}
5723
+
5724
+static bool trans_DCBI(DisasContext *ctx, arg_X_ea *a)
5725
+{
5726
+ REQUIRE_INSNS_FLAGS(ctx, CACHE);
5727
+
5728
+#if defined(CONFIG_USER_ONLY)
5729
+ gen_priv_opc(ctx);
5730
+ return true;
5731
+#else
5732
+ TCGv EA, val;
5733
+
5734
+ REQUIRE_SV(ctx);
5735
+
5736
+ gen_set_access_type(ctx, ACCESS_CACHE);
5737
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5738
+ val = tcg_temp_new();
5739
+
5740
+ gen_qemu_ld8u(ctx, val, EA);
5741
+ gen_qemu_st8(ctx, val, EA);
5742
+
5743
+ return true;
5744
+#endif
5745
+}
5746
+
5747
+static bool trans_ICBI(DisasContext *ctx, arg_X_ea *a)
5748
+{
5749
+ TCGv EA;
5750
+
5751
+ REQUIRE_INSNS_FLAGS(ctx, CACHE_ICBI);
5752
+
5753
+ gen_set_access_type(ctx, ACCESS_CACHE);
5754
+
5755
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5756
+ gen_helper_ICBI(tcg_env, EA);
5757
+
5758
+ return true;
5759
+}
5760
+
5761
+static bool trans_ICBIEP(DisasContext *ctx, arg_X_ea *a)
5762
+{
5763
+ TCGv EA;
5764
+
5765
+ REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
5766
+ REQUIRE_SV(ctx);
5767
+
5768
+ gen_set_access_type(ctx, ACCESS_CACHE);
5769
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5770
+
5771
+ gen_helper_ICBIEP(tcg_env, EA);
5772
+ return true;
5773
+}
5774
+
5775
#include "translate/fixedpoint-impl.c.inc"
5776
5777
#include "translate/fp-impl.c.inc"
5936
#endif
5937
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
5938
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
5907
-GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
5908
-GEN_HANDLER_E(dcbfep, 0x1F, 0x1F, 0x03, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
5909
-GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
5910
-GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
5911
-GEN_HANDLER_E(dcbstep, 0x1F, 0x1F, 0x01, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
5912
-GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
5913
-GEN_HANDLER_E(dcbtep, 0x1F, 0x1F, 0x09, 0x00000001, PPC_NONE, PPC2_BOOKE206),
5914
-GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
5915
-GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206),
5916
-GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
5917
-GEN_HANDLER_E(dcblc, 0x1F, 0x06, 0x0c, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
5939
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
5940
GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
5920
-GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
5921
-GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x01800001, PPC_ALTIVEC),
5922
-GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
5923
-GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
5924
-GEN_HANDLER_E(icbiep, 0x1F, 0x1F, 0x1E, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
5925
-GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
5941
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
5942
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
5943
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),