translate.c (dd7dbfcc00dc4cc349fc8f4588cecc88dd149ca5) translate.c (c8507ebf74fc5991cd822a5a34c8d653a6225a9b)
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 166 unchanged lines hidden (view full) ---

175 int fprs_dirty;
176 int asi;
177#endif
178 DisasDelayException *delay_excp_list;
179} DisasContext;
180
181typedef struct {
182 TCGCond cond;
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 166 unchanged lines hidden (view full) ---

175 int fprs_dirty;
176 int asi;
177#endif
178 DisasDelayException *delay_excp_list;
179} DisasContext;
180
181typedef struct {
182 TCGCond cond;
183 TCGv c1, c2;
183 TCGv c1;
184 int c2;
184} DisasCompare;
185
186// This function uses non-native bit order
187#define GET_FIELD(X, FROM, TO) \
188 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
189
190// This function uses the order in the manuals, i.e. bit 0 is 2^0
191#define GET_FIELD_SP(X, FROM, TO) \

--- 842 unchanged lines hidden (view full) ---

1034}
1035
1036static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
1037 DisasContext *dc)
1038{
1039 TCGv t1;
1040
1041 cmp->c1 = t1 = tcg_temp_new();
185} DisasCompare;
186
187// This function uses non-native bit order
188#define GET_FIELD(X, FROM, TO) \
189 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
190
191// This function uses the order in the manuals, i.e. bit 0 is 2^0
192#define GET_FIELD_SP(X, FROM, TO) \

--- 842 unchanged lines hidden (view full) ---

1035}
1036
1037static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
1038 DisasContext *dc)
1039{
1040 TCGv t1;
1041
1042 cmp->c1 = t1 = tcg_temp_new();
1042 cmp->c2 = tcg_constant_tl(0);
1043 cmp->c2 = 0;
1043
1044 switch (cond & 7) {
1045 case 0x0: /* never */
1046 cmp->cond = TCG_COND_NEVER;
1044
1045 switch (cond & 7) {
1046 case 0x0: /* never */
1047 cmp->cond = TCG_COND_NEVER;
1047 cmp->c1 = cmp->c2;
1048 cmp->c1 = tcg_constant_tl(0);
1048 break;
1049
1050 case 0x1: /* eq: Z */
1051 cmp->cond = TCG_COND_EQ;
1052 if (TARGET_LONG_BITS == 32 || xcc) {
1053 tcg_gen_mov_tl(t1, cpu_cc_Z);
1054 } else {
1055 tcg_gen_ext32u_tl(t1, cpu_icc_Z);

--- 79 unchanged lines hidden (view full) ---

1135static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
1136{
1137 unsigned int offset;
1138 TCGv r_dst;
1139
1140 /* For now we still generate a straight boolean result. */
1141 cmp->cond = TCG_COND_NE;
1142 cmp->c1 = r_dst = tcg_temp_new();
1049 break;
1050
1051 case 0x1: /* eq: Z */
1052 cmp->cond = TCG_COND_EQ;
1053 if (TARGET_LONG_BITS == 32 || xcc) {
1054 tcg_gen_mov_tl(t1, cpu_cc_Z);
1055 } else {
1056 tcg_gen_ext32u_tl(t1, cpu_icc_Z);

--- 79 unchanged lines hidden (view full) ---

1136static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
1137{
1138 unsigned int offset;
1139 TCGv r_dst;
1140
1141 /* For now we still generate a straight boolean result. */
1142 cmp->cond = TCG_COND_NE;
1143 cmp->c1 = r_dst = tcg_temp_new();
1143 cmp->c2 = tcg_constant_tl(0);
1144 cmp->c2 = 0;
1144
1145 switch (cc) {
1146 default:
1147 case 0x0:
1148 offset = 0;
1149 break;
1150 case 0x1:
1151 offset = 32 - 10;

--- 69 unchanged lines hidden (view full) ---

1221 TCG_COND_LE,
1222 TCG_COND_LT,
1223};
1224
1225static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
1226{
1227 cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
1228 cmp->c1 = r_src;
1145
1146 switch (cc) {
1147 default:
1148 case 0x0:
1149 offset = 0;
1150 break;
1151 case 0x1:
1152 offset = 32 - 10;

--- 69 unchanged lines hidden (view full) ---

1222 TCG_COND_LE,
1223 TCG_COND_LT,
1224};
1225
1226static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
1227{
1228 cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
1229 cmp->c1 = r_src;
1229 cmp->c2 = tcg_constant_tl(0);
1230 cmp->c2 = 0;
1230}
1231
1232static void gen_op_clear_ieee_excp_and_FTT(void)
1233{
1234 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1235}
1236
1237static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)

--- 989 unchanged lines hidden (view full) ---

2227#ifdef TARGET_SPARC64
2228 TCGv_i32 c32, zero, dst, s1, s2;
2229 TCGv_i64 c64 = tcg_temp_new_i64();
2230
2231 /* We have two choices here: extend the 32 bit data and use movcond_i64,
2232 or fold the comparison down to 32 bits and use movcond_i32. Choose
2233 the later. */
2234 c32 = tcg_temp_new_i32();
1231}
1232
1233static void gen_op_clear_ieee_excp_and_FTT(void)
1234{
1235 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1236}
1237
1238static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)

--- 989 unchanged lines hidden (view full) ---

2228#ifdef TARGET_SPARC64
2229 TCGv_i32 c32, zero, dst, s1, s2;
2230 TCGv_i64 c64 = tcg_temp_new_i64();
2231
2232 /* We have two choices here: extend the 32 bit data and use movcond_i64,
2233 or fold the comparison down to 32 bits and use movcond_i32. Choose
2234 the later. */
2235 c32 = tcg_temp_new_i32();
2235 tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
2236 tcg_gen_setcondi_i64(cmp->cond, c64, cmp->c1, cmp->c2);
2236 tcg_gen_extrl_i64_i32(c32, c64);
2237
2238 s1 = gen_load_fpr_F(dc, rs);
2239 s2 = gen_load_fpr_F(dc, rd);
2240 dst = gen_dest_fpr_F(dc);
2241 zero = tcg_constant_i32(0);
2242
2243 tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
2244
2245 gen_store_fpr_F(dc, rd, dst);
2246#else
2247 qemu_build_not_reached();
2248#endif
2249}
2250
2251static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2252{
2253#ifdef TARGET_SPARC64
2254 TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
2237 tcg_gen_extrl_i64_i32(c32, c64);
2238
2239 s1 = gen_load_fpr_F(dc, rs);
2240 s2 = gen_load_fpr_F(dc, rd);
2241 dst = gen_dest_fpr_F(dc);
2242 zero = tcg_constant_i32(0);
2243
2244 tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
2245
2246 gen_store_fpr_F(dc, rd, dst);
2247#else
2248 qemu_build_not_reached();
2249#endif
2250}
2251
2252static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2253{
2254#ifdef TARGET_SPARC64
2255 TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
2255 tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
2256 tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, tcg_constant_tl(cmp->c2),
2256 gen_load_fpr_D(dc, rs),
2257 gen_load_fpr_D(dc, rd));
2258 gen_store_fpr_D(dc, rd, dst);
2259#else
2260 qemu_build_not_reached();
2261#endif
2262}
2263
2264static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2265{
2266#ifdef TARGET_SPARC64
2267 int qd = QFPREG(rd);
2268 int qs = QFPREG(rs);
2257 gen_load_fpr_D(dc, rs),
2258 gen_load_fpr_D(dc, rd));
2259 gen_store_fpr_D(dc, rd, dst);
2260#else
2261 qemu_build_not_reached();
2262#endif
2263}
2264
2265static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2266{
2267#ifdef TARGET_SPARC64
2268 int qd = QFPREG(rd);
2269 int qs = QFPREG(rs);
2270 TCGv c2 = tcg_constant_tl(cmp->c2);
2269
2271
2270 tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, cmp->c2,
2272 tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, c2,
2271 cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
2273 cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
2272 tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
2274 tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, c2,
2273 cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
2274
2275 gen_update_fprs_dirty(dc, qd);
2276#else
2277 qemu_build_not_reached();
2278#endif
2279}
2280

--- 123 unchanged lines hidden (view full) ---

2404static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
2405 bool annul, target_ulong dest)
2406{
2407 target_ulong npc = dc->npc;
2408
2409 if (annul) {
2410 TCGLabel *l1 = gen_new_label();
2411
2275 cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
2276
2277 gen_update_fprs_dirty(dc, qd);
2278#else
2279 qemu_build_not_reached();
2280#endif
2281}
2282

--- 123 unchanged lines hidden (view full) ---

2406static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
2407 bool annul, target_ulong dest)
2408{
2409 target_ulong npc = dc->npc;
2410
2411 if (annul) {
2412 TCGLabel *l1 = gen_new_label();
2413
2412 tcg_gen_brcond_tl(tcg_invert_cond(cmp->cond), cmp->c1, cmp->c2, l1);
2414 tcg_gen_brcondi_tl(tcg_invert_cond(cmp->cond), cmp->c1, cmp->c2, l1);
2413 gen_goto_tb(dc, 0, npc, dest);
2414 gen_set_label(l1);
2415 gen_goto_tb(dc, 1, npc + 4, npc + 8);
2416
2417 dc->base.is_jmp = DISAS_NORETURN;
2418 } else {
2419 if (npc & 3) {
2420 switch (npc) {
2421 case DYNAMIC_PC:
2422 case DYNAMIC_PC_LOOKUP:
2423 tcg_gen_mov_tl(cpu_pc, cpu_npc);
2424 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
2425 tcg_gen_movcond_tl(cmp->cond, cpu_npc,
2415 gen_goto_tb(dc, 0, npc, dest);
2416 gen_set_label(l1);
2417 gen_goto_tb(dc, 1, npc + 4, npc + 8);
2418
2419 dc->base.is_jmp = DISAS_NORETURN;
2420 } else {
2421 if (npc & 3) {
2422 switch (npc) {
2423 case DYNAMIC_PC:
2424 case DYNAMIC_PC_LOOKUP:
2425 tcg_gen_mov_tl(cpu_pc, cpu_npc);
2426 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
2427 tcg_gen_movcond_tl(cmp->cond, cpu_npc,
2426 cmp->c1, cmp->c2,
2428 cmp->c1, tcg_constant_tl(cmp->c2),
2427 tcg_constant_tl(dest), cpu_npc);
2428 dc->pc = npc;
2429 break;
2430 default:
2431 g_assert_not_reached();
2432 }
2433 } else {
2434 dc->pc = npc;
2435 dc->jump_pc[0] = dest;
2436 dc->jump_pc[1] = npc + 4;
2437 dc->npc = JUMP_PC;
2438
2439 /* The condition for cpu_cond is always NE -- normalize. */
2440 if (cmp->cond == TCG_COND_NE) {
2429 tcg_constant_tl(dest), cpu_npc);
2430 dc->pc = npc;
2431 break;
2432 default:
2433 g_assert_not_reached();
2434 }
2435 } else {
2436 dc->pc = npc;
2437 dc->jump_pc[0] = dest;
2438 dc->jump_pc[1] = npc + 4;
2439 dc->npc = JUMP_PC;
2440
2441 /* The condition for cpu_cond is always NE -- normalize. */
2442 if (cmp->cond == TCG_COND_NE) {
2441 tcg_gen_xor_tl(cpu_cond, cmp->c1, cmp->c2);
2443 tcg_gen_xori_tl(cpu_cond, cmp->c1, cmp->c2);
2442 } else {
2444 } else {
2443 tcg_gen_setcond_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
2445 tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
2444 }
2445 }
2446 }
2447 return true;
2448}
2449
2450static bool raise_priv(DisasContext *dc)
2451{

--- 155 unchanged lines hidden (view full) ---

2607 dc->base.is_jmp = DISAS_NORETURN;
2608 return true;
2609 }
2610
2611 /* Conditional trap. */
2612 flush_cond(dc);
2613 lab = delay_exceptionv(dc, trap);
2614 gen_compare(&cmp, cc, cond, dc);
2446 }
2447 }
2448 }
2449 return true;
2450}
2451
2452static bool raise_priv(DisasContext *dc)
2453{

--- 155 unchanged lines hidden (view full) ---

2609 dc->base.is_jmp = DISAS_NORETURN;
2610 return true;
2611 }
2612
2613 /* Conditional trap. */
2614 flush_cond(dc);
2615 lab = delay_exceptionv(dc, trap);
2616 gen_compare(&cmp, cc, cond, dc);
2615 tcg_gen_brcond_tl(cmp.cond, cmp.c1, cmp.c2, lab);
2617 tcg_gen_brcondi_tl(cmp.cond, cmp.c1, cmp.c2, lab);
2616
2617 return advance_pc(dc);
2618}
2619
2620static bool trans_Tcc_r(DisasContext *dc, arg_Tcc_r *a)
2621{
2622 if (avail_32(dc) && a->cc) {
2623 return false;

--- 1220 unchanged lines hidden (view full) ---

3844 } else {
3845 return cpu_regs[rs2_or_imm];
3846 }
3847}
3848
3849static bool do_mov_cond(DisasContext *dc, DisasCompare *cmp, int rd, TCGv src2)
3850{
3851 TCGv dst = gen_load_gpr(dc, rd);
2618
2619 return advance_pc(dc);
2620}
2621
2622static bool trans_Tcc_r(DisasContext *dc, arg_Tcc_r *a)
2623{
2624 if (avail_32(dc) && a->cc) {
2625 return false;

--- 1220 unchanged lines hidden (view full) ---

3846 } else {
3847 return cpu_regs[rs2_or_imm];
3848 }
3849}
3850
3851static bool do_mov_cond(DisasContext *dc, DisasCompare *cmp, int rd, TCGv src2)
3852{
3853 TCGv dst = gen_load_gpr(dc, rd);
3854 TCGv c2 = tcg_constant_tl(cmp->c2);
3852
3855
3853 tcg_gen_movcond_tl(cmp->cond, dst, cmp->c1, cmp->c2, src2, dst);
3856 tcg_gen_movcond_tl(cmp->cond, dst, cmp->c1, c2, src2, dst);
3854 gen_store_gpr(dc, rd, dst);
3855 return advance_pc(dc);
3856}
3857
3858static bool trans_MOVcc(DisasContext *dc, arg_MOVcc *a)
3859{
3860 TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
3861 DisasCompare cmp;

--- 1424 unchanged lines hidden ---
3857 gen_store_gpr(dc, rd, dst);
3858 return advance_pc(dc);
3859}
3860
3861static bool trans_MOVcc(DisasContext *dc, arg_MOVcc *a)
3862{
3863 TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
3864 DisasCompare cmp;

--- 1424 unchanged lines hidden ---