aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-01-07 10:05:56 -0600
committerAlexander Graf <agraf@suse.de>2014-03-05 03:06:40 +0100
commit5c77a786e21e9dc12efc0f0590221e67dd5143da (patch)
tree4bbb2bc96304ed9ea240656362c982429d09f974 /target-ppc
parent1fa6c533047b4447cef693a1f54babc6a69fe19d (diff)
target-ppc: Add ISA2.06 lbarx, lharx Instructions
This patch adds the byte and halfword variants of the Load and Reserve instructions. Since there is much commonality among all forms of Load and Reserve, a macro is provided and the existing implementations of lwarx and ldarx are refactoried to use this macro. Signed-off-by: Tom Musta <tommusta@gmail.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/translate.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fed957e844..de7de76fc6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3207,21 +3207,29 @@ static void gen_isync(DisasContext *ctx)
gen_stop_exception(ctx);
}
-/* lwarx */
-static void gen_lwarx(DisasContext *ctx)
-{
- TCGv t0;
- TCGv gpr = cpu_gpr[rD(ctx->opcode)];
- gen_set_access_type(ctx, ACCESS_RES);
- t0 = tcg_temp_local_new();
- gen_addr_reg_index(ctx, t0);
- gen_check_align(ctx, t0, 0x03);
- gen_qemu_ld32u(ctx, gpr, t0);
- tcg_gen_mov_tl(cpu_reserve, t0);
- tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
- tcg_temp_free(t0);
+#define LARX(name, len, loadop) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv t0; \
+ TCGv gpr = cpu_gpr[rD(ctx->opcode)]; \
+ gen_set_access_type(ctx, ACCESS_RES); \
+ t0 = tcg_temp_local_new(); \
+ gen_addr_reg_index(ctx, t0); \
+ if ((len) > 1) { \
+ gen_check_align(ctx, t0, (len)-1); \
+ } \
+ gen_qemu_##loadop(ctx, gpr, t0); \
+ tcg_gen_mov_tl(cpu_reserve, t0); \
+ tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
+ tcg_temp_free(t0); \
}
+/* lwarx */
+LARX(lbarx, 1, ld8u);
+LARX(lharx, 2, ld16u);
+LARX(lwarx, 4, ld32u);
+
+
#if defined(CONFIG_USER_ONLY)
static void gen_conditional_store (DisasContext *ctx, TCGv EA,
int reg, int size)
@@ -3268,19 +3276,7 @@ static void gen_stwcx_(DisasContext *ctx)
#if defined(TARGET_PPC64)
/* ldarx */
-static void gen_ldarx(DisasContext *ctx)
-{
- TCGv t0;
- TCGv gpr = cpu_gpr[rD(ctx->opcode)];
- gen_set_access_type(ctx, ACCESS_RES);
- t0 = tcg_temp_local_new();
- gen_addr_reg_index(ctx, t0);
- gen_check_align(ctx, t0, 0x07);
- gen_qemu_ld64(ctx, gpr, t0);
- tcg_gen_mov_tl(cpu_reserve, t0);
- tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
- tcg_temp_free(t0);
-}
+LARX(ldarx, 8, ld64);
/* stdcx. */
static void gen_stdcx_(DisasContext *ctx)
@@ -9513,6 +9509,8 @@ GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
+GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
+GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
#if defined(TARGET_PPC64)