Revision 47e4661c target-ppc/translate.c
b/target-ppc/translate.c | ||
---|---|---|
51 | 51 |
+ 10*4 + 22*5 /* SPE GPRh */ |
52 | 52 |
#endif |
53 | 53 |
+ 10*4 + 22*5 /* FPR */ |
54 |
+ 2*(10*6 + 22*7) /* AVRh, AVRl */]; |
|
54 |
+ 2*(10*6 + 22*7) /* AVRh, AVRl */ |
|
55 |
+ 8*5 /* CRF */]; |
|
55 | 56 |
static TCGv cpu_gpr[32]; |
56 | 57 |
#if !defined(TARGET_PPC64) |
57 | 58 |
static TCGv cpu_gprh[32]; |
58 | 59 |
#endif |
59 | 60 |
static TCGv cpu_fpr[32]; |
60 | 61 |
static TCGv cpu_avrh[32], cpu_avrl[32]; |
62 |
static TCGv cpu_crf[8]; |
|
61 | 63 |
|
62 | 64 |
/* dyngen register indexes */ |
63 | 65 |
static TCGv cpu_T[3]; |
... | ... | |
126 | 128 |
offsetof(CPUState, avr2.u64[1]), "AVR2L"); |
127 | 129 |
|
128 | 130 |
p = cpu_reg_names; |
131 |
|
|
132 |
for (i = 0; i < 8; i++) { |
|
133 |
sprintf(p, "crf%d", i); |
|
134 |
cpu_crf[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, |
|
135 |
offsetof(CPUState, crf[i]), p); |
|
136 |
p += 5; |
|
137 |
} |
|
138 |
|
|
129 | 139 |
for (i = 0; i < 32; i++) { |
130 | 140 |
sprintf(p, "r%d", i); |
131 | 141 |
cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, |
... | ... | |
167 | 177 |
static uint16_t **gen_fprf_ptr; |
168 | 178 |
#endif |
169 | 179 |
|
170 |
#define GEN8(func, NAME) \ |
|
171 |
static GenOpFunc *NAME ## _table [8] = { \ |
|
172 |
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ |
|
173 |
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ |
|
174 |
}; \ |
|
175 |
static always_inline void func (int n) \ |
|
176 |
{ \ |
|
177 |
NAME ## _table[n](); \ |
|
178 |
} |
|
179 |
|
|
180 | 180 |
#define GEN16(func, NAME) \ |
181 | 181 |
static GenOpFunc *NAME ## _table [16] = { \ |
182 | 182 |
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ |
... | ... | |
205 | 205 |
NAME ## _table[n](); \ |
206 | 206 |
} |
207 | 207 |
|
208 |
/* Condition register moves */ |
|
209 |
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf); |
|
210 |
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf); |
|
211 |
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf); |
|
212 |
#if 0 // Unused |
|
213 |
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf); |
|
214 |
#endif |
|
215 |
|
|
216 | 208 |
/* internal defines */ |
217 | 209 |
typedef struct DisasContext { |
218 | 210 |
struct TranslationBlock *tb; |
... | ... | |
278 | 270 |
#endif |
279 | 271 |
gen_op_compute_fprf(1); |
280 | 272 |
if (unlikely(set_rc)) |
281 |
gen_op_store_T0_crf(1);
|
|
273 |
tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
|
|
282 | 274 |
gen_op_float_check_status(); |
283 | 275 |
} else if (unlikely(set_rc)) { |
284 | 276 |
/* We always need to compute fpcc */ |
285 | 277 |
gen_op_compute_fprf(0); |
286 |
gen_op_store_T0_crf(1);
|
|
278 |
tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
|
|
287 | 279 |
if (set_fprf) |
288 | 280 |
gen_op_float_check_status(); |
289 | 281 |
} |
... | ... | |
1158 | 1150 |
gen_op_##name##_64(); \ |
1159 | 1151 |
else \ |
1160 | 1152 |
gen_op_##name(); \ |
1161 |
gen_op_store_T0_crf(crfD(ctx->opcode)); \
|
|
1153 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \
|
|
1162 | 1154 |
} |
1163 | 1155 |
#else |
1164 | 1156 |
#define GEN_CMP(name, opc, type) \ |
... | ... | |
1167 | 1159 |
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \ |
1168 | 1160 |
tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \ |
1169 | 1161 |
gen_op_##name(); \ |
1170 |
gen_op_store_T0_crf(crfD(ctx->opcode)); \
|
|
1162 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \
|
|
1171 | 1163 |
} |
1172 | 1164 |
#endif |
1173 | 1165 |
|
... | ... | |
1183 | 1175 |
else |
1184 | 1176 |
#endif |
1185 | 1177 |
gen_op_cmpi(SIMM(ctx->opcode)); |
1186 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
1178 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
1187 | 1179 |
} |
1188 | 1180 |
/* cmpl */ |
1189 | 1181 |
GEN_CMP(cmpl, 0x01, PPC_INTEGER); |
... | ... | |
1197 | 1189 |
else |
1198 | 1190 |
#endif |
1199 | 1191 |
gen_op_cmpli(UIMM(ctx->opcode)); |
1200 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
1192 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
1201 | 1193 |
} |
1202 | 1194 |
|
1203 | 1195 |
/* isel (PowerPC 2.03 specification) */ |
... | ... | |
1213 | 1205 |
} |
1214 | 1206 |
tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]); |
1215 | 1207 |
mask = 1 << (3 - (bi & 0x03)); |
1216 |
gen_op_load_crf_T0(bi >> 2);
|
|
1208 |
tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]);
|
|
1217 | 1209 |
gen_op_test_true(mask); |
1218 | 1210 |
gen_op_isel(); |
1219 | 1211 |
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); |
... | ... | |
1977 | 1969 |
tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]); |
1978 | 1970 |
gen_reset_fpstatus(); |
1979 | 1971 |
gen_op_fcmpo(); |
1980 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
1972 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
1981 | 1973 |
gen_op_float_check_status(); |
1982 | 1974 |
} |
1983 | 1975 |
|
... | ... | |
1992 | 1984 |
tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]); |
1993 | 1985 |
gen_reset_fpstatus(); |
1994 | 1986 |
gen_op_fcmpu(); |
1995 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
1987 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
1996 | 1988 |
gen_op_float_check_status(); |
1997 | 1989 |
} |
1998 | 1990 |
|
... | ... | |
2034 | 2026 |
gen_optimize_fprf(); |
2035 | 2027 |
bfa = 4 * (7 - crfS(ctx->opcode)); |
2036 | 2028 |
gen_op_load_fpscr_T0(bfa); |
2037 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
2029 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
2038 | 2030 |
gen_op_fpscr_resetbit(~(0xF << bfa)); |
2039 | 2031 |
} |
2040 | 2032 |
|
... | ... | |
3015 | 3007 |
} |
3016 | 3008 |
} else { |
3017 | 3009 |
mask = 1 << (3 - (bi & 0x03)); |
3018 |
gen_op_load_crf_T0(bi >> 2);
|
|
3010 |
tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]);
|
|
3019 | 3011 |
if (bo & 0x8) { |
3020 | 3012 |
switch (bo & 0x6) { |
3021 | 3013 |
case 0: |
... | ... | |
3109 | 3101 |
{ \ |
3110 | 3102 |
uint8_t bitmask; \ |
3111 | 3103 |
int sh; \ |
3112 |
gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
|
|
3104 |
tcg_gen_mov_i32(cpu_T[0], cpu_crf[crbA(ctx->opcode) >> 2]); \
|
|
3113 | 3105 |
sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \ |
3114 | 3106 |
if (sh > 0) \ |
3115 | 3107 |
gen_op_srli_T0(sh); \ |
3116 | 3108 |
else if (sh < 0) \ |
3117 | 3109 |
gen_op_sli_T0(-sh); \ |
3118 |
gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
|
|
3110 |
tcg_gen_mov_i32(cpu_T[1], cpu_crf[crbB(ctx->opcode) >> 2]); \
|
|
3119 | 3111 |
sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \ |
3120 | 3112 |
if (sh > 0) \ |
3121 | 3113 |
gen_op_srli_T1(sh); \ |
... | ... | |
3124 | 3116 |
gen_op_##op(); \ |
3125 | 3117 |
bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03)); \ |
3126 | 3118 |
gen_op_andi_T0(bitmask); \ |
3127 |
gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \ |
|
3128 |
gen_op_andi_T1(~bitmask); \ |
|
3119 |
tcg_gen_andi_i32(cpu_T[1], cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \ |
|
3129 | 3120 |
gen_op_or(); \ |
3130 |
gen_op_store_T0_crf(crbD(ctx->opcode) >> 2); \
|
|
3121 |
tcg_gen_andi_i32(cpu_crf[crbD(ctx->opcode) >> 2], cpu_T[0], 0xf); \
|
|
3131 | 3122 |
} |
3132 | 3123 |
|
3133 | 3124 |
/* crand */ |
... | ... | |
3149 | 3140 |
/* mcrf */ |
3150 | 3141 |
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER) |
3151 | 3142 |
{ |
3152 |
gen_op_load_crf_T0(crfS(ctx->opcode)); |
|
3153 |
gen_op_store_T0_crf(crfD(ctx->opcode)); |
|
3143 |
tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]); |
|
3154 | 3144 |
} |
3155 | 3145 |
|
3156 | 3146 |
/*** System linkage ***/ |
... | ... | |
3264 | 3254 |
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC) |
3265 | 3255 |
{ |
3266 | 3256 |
gen_op_load_xer_cr(); |
3267 |
gen_op_store_T0_crf(crfD(ctx->opcode));
|
|
3257 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
|
|
3268 | 3258 |
gen_op_clear_xer_ov(); |
3269 | 3259 |
gen_op_clear_xer_ca(); |
3270 | 3260 |
} |
... | ... | |
3278 | 3268 |
crm = CRM(ctx->opcode); |
3279 | 3269 |
if (likely((crm ^ (crm - 1)) == 0)) { |
3280 | 3270 |
crn = ffs(crm); |
3281 |
gen_op_load_cro(7 - crn);
|
|
3271 |
tcg_gen_mov_i32(cpu_T[0], cpu_crf[7 - crn]);
|
|
3282 | 3272 |
} |
3283 | 3273 |
} else { |
3284 | 3274 |
gen_op_load_cr(); |
... | ... | |
3380 | 3370 |
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) { |
3381 | 3371 |
crn = ffs(crm); |
3382 | 3372 |
gen_op_srli_T0(crn * 4); |
3383 |
gen_op_andi_T0(0xF); |
|
3384 |
gen_op_store_cro(7 - crn); |
|
3373 |
tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_T[0], 0xf); |
|
3385 | 3374 |
} else { |
3386 | 3375 |
gen_op_store_cr(crm); |
3387 | 3376 |
} |
... | ... | |
5244 | 5233 |
gen_op_store_xer_bc(); |
5245 | 5234 |
if (Rc(ctx->opcode)) { |
5246 | 5235 |
gen_op_440_dlmzb_update_Rc(); |
5247 |
gen_op_store_T0_crf(0);
|
|
5236 |
tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
|
|
5248 | 5237 |
} |
5249 | 5238 |
} |
5250 | 5239 |
|
... | ... | |
5493 | 5482 |
gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ |
5494 | 5483 |
gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ |
5495 | 5484 |
gen_op_##name(); \ |
5496 |
gen_op_store_T0_crf(crfD(ctx->opcode)); \
|
|
5485 |
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \
|
|
5497 | 5486 |
} |
5498 | 5487 |
|
5499 | 5488 |
/* Logical */ |
... | ... | |
5625 | 5614 |
GEN_EXCP_NO_AP(ctx); |
5626 | 5615 |
return; |
5627 | 5616 |
} |
5628 |
gen_op_load_crf_T0(ctx->opcode & 0x7);
|
|
5617 |
tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
|
|
5629 | 5618 |
gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); |
5630 | 5619 |
gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); |
5631 | 5620 |
gen_op_evsel(); |
Also available in: Unified diff