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 --- |