Commit 324d9e320426253bd710a9efe210797435173eab
1 parent
b2ee0ce2
target-mips: optimize gen_arith_imm()
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7092 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
161 additions
and
106 deletions
target-mips/translate.c
| ... | ... | @@ -57,10 +57,12 @@ enum { |
| 57 | 57 | OPC_ADDIU = (0x09 << 26), |
| 58 | 58 | OPC_SLTI = (0x0A << 26), |
| 59 | 59 | OPC_SLTIU = (0x0B << 26), |
| 60 | + /* logic with immediate */ | |
| 60 | 61 | OPC_ANDI = (0x0C << 26), |
| 61 | 62 | OPC_ORI = (0x0D << 26), |
| 62 | 63 | OPC_XORI = (0x0E << 26), |
| 63 | 64 | OPC_LUI = (0x0F << 26), |
| 65 | + /* arithmetic with immediate */ | |
| 64 | 66 | OPC_DADDI = (0x18 << 26), |
| 65 | 67 | OPC_DADDIU = (0x19 << 26), |
| 66 | 68 | /* Jump and branches */ |
| ... | ... | @@ -1197,140 +1199,184 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
| 1197 | 1199 | static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1198 | 1200 | int rt, int rs, int16_t imm) |
| 1199 | 1201 | { |
| 1200 | - target_ulong uimm; | |
| 1202 | + target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ | |
| 1201 | 1203 | const char *opn = "imm arith"; |
| 1202 | - TCGv t0 = tcg_temp_local_new(); | |
| 1203 | 1204 | |
| 1204 | 1205 | if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { |
| 1205 | 1206 | /* If no destination, treat it as a NOP. |
| 1206 | 1207 | For addi, we must generate the overflow exception when needed. */ |
| 1207 | 1208 | MIPS_DEBUG("NOP"); |
| 1208 | - goto out; | |
| 1209 | - } | |
| 1210 | - uimm = (uint16_t)imm; | |
| 1211 | - switch (opc) { | |
| 1212 | - case OPC_ADDI: | |
| 1213 | - case OPC_ADDIU: | |
| 1214 | -#if defined(TARGET_MIPS64) | |
| 1215 | - case OPC_DADDI: | |
| 1216 | - case OPC_DADDIU: | |
| 1217 | -#endif | |
| 1218 | - case OPC_SLTI: | |
| 1219 | - case OPC_SLTIU: | |
| 1220 | - uimm = (target_long)imm; /* Sign extend to 32/64 bits */ | |
| 1221 | - /* Fall through. */ | |
| 1222 | - case OPC_ANDI: | |
| 1223 | - case OPC_ORI: | |
| 1224 | - case OPC_XORI: | |
| 1225 | - gen_load_gpr(t0, rs); | |
| 1226 | - break; | |
| 1227 | - case OPC_LUI: | |
| 1228 | - tcg_gen_movi_tl(t0, imm << 16); | |
| 1229 | - break; | |
| 1230 | - case OPC_SLL: | |
| 1231 | - case OPC_SRA: | |
| 1232 | - case OPC_SRL: | |
| 1233 | -#if defined(TARGET_MIPS64) | |
| 1234 | - case OPC_DSLL: | |
| 1235 | - case OPC_DSRA: | |
| 1236 | - case OPC_DSRL: | |
| 1237 | - case OPC_DSLL32: | |
| 1238 | - case OPC_DSRA32: | |
| 1239 | - case OPC_DSRL32: | |
| 1240 | -#endif | |
| 1241 | - uimm &= 0x1f; | |
| 1242 | - gen_load_gpr(t0, rs); | |
| 1243 | - break; | |
| 1209 | + return; | |
| 1244 | 1210 | } |
| 1245 | 1211 | switch (opc) { |
| 1246 | 1212 | case OPC_ADDI: |
| 1247 | 1213 | { |
| 1248 | - TCGv r_tmp1 = tcg_temp_new(); | |
| 1249 | - TCGv r_tmp2 = tcg_temp_new(); | |
| 1214 | + TCGv t0 = tcg_temp_local_new(); | |
| 1215 | + TCGv t1 = tcg_temp_new(); | |
| 1216 | + TCGv t2 = tcg_temp_new(); | |
| 1250 | 1217 | int l1 = gen_new_label(); |
| 1251 | 1218 | |
| 1252 | - save_cpu_state(ctx, 1); | |
| 1253 | - tcg_gen_ext32s_tl(r_tmp1, t0); | |
| 1254 | - tcg_gen_addi_tl(t0, r_tmp1, uimm); | |
| 1219 | + gen_load_gpr(t1, rs); | |
| 1220 | + tcg_gen_addi_tl(t0, t1, uimm); | |
| 1221 | + tcg_gen_ext32s_tl(t0, t0); | |
| 1255 | 1222 | |
| 1256 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm); | |
| 1257 | - tcg_gen_xori_tl(r_tmp2, t0, uimm); | |
| 1258 | - tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); | |
| 1259 | - tcg_temp_free(r_tmp2); | |
| 1260 | - tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1223 | + tcg_gen_xori_tl(t1, t1, ~uimm); | |
| 1224 | + tcg_gen_xori_tl(t2, t0, uimm); | |
| 1225 | + tcg_gen_and_tl(t1, t1, t2); | |
| 1226 | + tcg_temp_free(t2); | |
| 1227 | + tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); | |
| 1228 | + tcg_temp_free(t1); | |
| 1261 | 1229 | /* operands of same sign, result different sign */ |
| 1262 | 1230 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1263 | 1231 | gen_set_label(l1); |
| 1264 | - tcg_temp_free(r_tmp1); | |
| 1265 | - | |
| 1266 | 1232 | tcg_gen_ext32s_tl(t0, t0); |
| 1233 | + gen_store_gpr(t0, rt); | |
| 1234 | + tcg_temp_free(t0); | |
| 1267 | 1235 | } |
| 1268 | 1236 | opn = "addi"; |
| 1269 | 1237 | break; |
| 1270 | 1238 | case OPC_ADDIU: |
| 1271 | - tcg_gen_addi_tl(t0, t0, uimm); | |
| 1272 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1239 | + if (rs != 0) { | |
| 1240 | + tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); | |
| 1241 | + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); | |
| 1242 | + } else { | |
| 1243 | + tcg_gen_movi_tl(cpu_gpr[rt], uimm); | |
| 1244 | + } | |
| 1273 | 1245 | opn = "addiu"; |
| 1274 | 1246 | break; |
| 1275 | 1247 | #if defined(TARGET_MIPS64) |
| 1276 | 1248 | case OPC_DADDI: |
| 1277 | 1249 | { |
| 1278 | - TCGv r_tmp1 = tcg_temp_new(); | |
| 1279 | - TCGv r_tmp2 = tcg_temp_new(); | |
| 1250 | + TCGv t0 = tcg_temp_local_new(); | |
| 1251 | + TCGv t1 = tcg_temp_new(); | |
| 1252 | + TCGv t2 = tcg_temp_new(); | |
| 1280 | 1253 | int l1 = gen_new_label(); |
| 1281 | 1254 | |
| 1282 | - save_cpu_state(ctx, 1); | |
| 1283 | - tcg_gen_mov_tl(r_tmp1, t0); | |
| 1284 | - tcg_gen_addi_tl(t0, t0, uimm); | |
| 1255 | + gen_load_gpr(t1, rs); | |
| 1256 | + tcg_gen_addi_tl(t0, t1, uimm); | |
| 1285 | 1257 | |
| 1286 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm); | |
| 1287 | - tcg_gen_xori_tl(r_tmp2, t0, uimm); | |
| 1288 | - tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); | |
| 1289 | - tcg_temp_free(r_tmp2); | |
| 1290 | - tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1258 | + tcg_gen_xori_tl(t1, t1, ~uimm); | |
| 1259 | + tcg_gen_xori_tl(t2, t0, uimm); | |
| 1260 | + tcg_gen_and_tl(t1, t1, t2); | |
| 1261 | + tcg_temp_free(t2); | |
| 1262 | + tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); | |
| 1263 | + tcg_temp_free(t1); | |
| 1291 | 1264 | /* operands of same sign, result different sign */ |
| 1292 | 1265 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1293 | 1266 | gen_set_label(l1); |
| 1294 | - tcg_temp_free(r_tmp1); | |
| 1267 | + gen_store_gpr(t0, rt); | |
| 1268 | + tcg_temp_free(t0); | |
| 1295 | 1269 | } |
| 1296 | 1270 | opn = "daddi"; |
| 1297 | 1271 | break; |
| 1298 | 1272 | case OPC_DADDIU: |
| 1299 | - tcg_gen_addi_tl(t0, t0, uimm); | |
| 1273 | + if (rs != 0) { | |
| 1274 | + tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); | |
| 1275 | + } else { | |
| 1276 | + tcg_gen_movi_tl(cpu_gpr[rt], uimm); | |
| 1277 | + } | |
| 1300 | 1278 | opn = "daddiu"; |
| 1301 | 1279 | break; |
| 1302 | 1280 | #endif |
| 1303 | - case OPC_SLTI: | |
| 1304 | - gen_op_lti(t0, t0, uimm); | |
| 1305 | - opn = "slti"; | |
| 1306 | - break; | |
| 1307 | - case OPC_SLTIU: | |
| 1308 | - gen_op_ltiu(t0, t0, uimm); | |
| 1309 | - opn = "sltiu"; | |
| 1310 | - break; | |
| 1281 | + } | |
| 1282 | + MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); | |
| 1283 | +} | |
| 1284 | + | |
| 1285 | +/* Logic with immediate operand */ | |
| 1286 | +static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm) | |
| 1287 | +{ | |
| 1288 | + target_ulong uimm; | |
| 1289 | + const char *opn = "imm logic"; | |
| 1290 | + | |
| 1291 | + if (rt == 0) { | |
| 1292 | + /* If no destination, treat it as a NOP. */ | |
| 1293 | + MIPS_DEBUG("NOP"); | |
| 1294 | + return; | |
| 1295 | + } | |
| 1296 | + uimm = (uint16_t)imm; | |
| 1297 | + switch (opc) { | |
| 1311 | 1298 | case OPC_ANDI: |
| 1312 | - tcg_gen_andi_tl(t0, t0, uimm); | |
| 1299 | + if (likely(rs != 0)) | |
| 1300 | + tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); | |
| 1301 | + else | |
| 1302 | + tcg_gen_movi_tl(cpu_gpr[rt], 0); | |
| 1313 | 1303 | opn = "andi"; |
| 1314 | 1304 | break; |
| 1315 | 1305 | case OPC_ORI: |
| 1316 | - tcg_gen_ori_tl(t0, t0, uimm); | |
| 1306 | + if (rs != 0) | |
| 1307 | + tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); | |
| 1308 | + else | |
| 1309 | + tcg_gen_movi_tl(cpu_gpr[rt], uimm); | |
| 1317 | 1310 | opn = "ori"; |
| 1318 | 1311 | break; |
| 1319 | 1312 | case OPC_XORI: |
| 1320 | - tcg_gen_xori_tl(t0, t0, uimm); | |
| 1313 | + if (likely(rs != 0)) | |
| 1314 | + tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); | |
| 1315 | + else | |
| 1316 | + tcg_gen_movi_tl(cpu_gpr[rt], uimm); | |
| 1321 | 1317 | opn = "xori"; |
| 1322 | 1318 | break; |
| 1323 | 1319 | case OPC_LUI: |
| 1320 | + tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); | |
| 1324 | 1321 | opn = "lui"; |
| 1325 | 1322 | break; |
| 1323 | + } | |
| 1324 | + MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); | |
| 1325 | +} | |
| 1326 | + | |
| 1327 | +/* Set on less than with immediate operand */ | |
| 1328 | +static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm) | |
| 1329 | +{ | |
| 1330 | + target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ | |
| 1331 | + const char *opn = "imm arith"; | |
| 1332 | + TCGv t0; | |
| 1333 | + | |
| 1334 | + if (rt == 0) { | |
| 1335 | + /* If no destination, treat it as a NOP. */ | |
| 1336 | + MIPS_DEBUG("NOP"); | |
| 1337 | + return; | |
| 1338 | + } | |
| 1339 | + t0 = tcg_temp_new(); | |
| 1340 | + gen_load_gpr(t0, rs); | |
| 1341 | + switch (opc) { | |
| 1342 | + case OPC_SLTI: | |
| 1343 | + gen_op_lti(cpu_gpr[rt], t0, uimm); | |
| 1344 | + opn = "slti"; | |
| 1345 | + break; | |
| 1346 | + case OPC_SLTIU: | |
| 1347 | + gen_op_ltiu(cpu_gpr[rt], t0, uimm); | |
| 1348 | + opn = "sltiu"; | |
| 1349 | + break; | |
| 1350 | + } | |
| 1351 | + MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); | |
| 1352 | + tcg_temp_free(t0); | |
| 1353 | +} | |
| 1354 | + | |
| 1355 | +/* Shifts with immediate operand */ | |
| 1356 | +static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc, | |
| 1357 | + int rt, int rs, int16_t imm) | |
| 1358 | +{ | |
| 1359 | + target_ulong uimm = ((uint16_t)imm) & 0x1f; | |
| 1360 | + const char *opn = "imm shift"; | |
| 1361 | + TCGv t0; | |
| 1362 | + | |
| 1363 | + if (rt == 0) { | |
| 1364 | + /* If no destination, treat it as a NOP. */ | |
| 1365 | + MIPS_DEBUG("NOP"); | |
| 1366 | + return; | |
| 1367 | + } | |
| 1368 | + | |
| 1369 | + t0 = tcg_temp_new(); | |
| 1370 | + gen_load_gpr(t0, rs); | |
| 1371 | + switch (opc) { | |
| 1326 | 1372 | case OPC_SLL: |
| 1327 | 1373 | tcg_gen_shli_tl(t0, t0, uimm); |
| 1328 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1374 | + tcg_gen_ext32s_tl(cpu_gpr[rt], t0); | |
| 1329 | 1375 | opn = "sll"; |
| 1330 | 1376 | break; |
| 1331 | 1377 | case OPC_SRA: |
| 1332 | 1378 | tcg_gen_ext32s_tl(t0, t0); |
| 1333 | - tcg_gen_sari_tl(t0, t0, uimm); | |
| 1379 | + tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); | |
| 1334 | 1380 | opn = "sra"; |
| 1335 | 1381 | break; |
| 1336 | 1382 | case OPC_SRL: |
| ... | ... | @@ -1338,9 +1384,9 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1338 | 1384 | case 0: |
| 1339 | 1385 | if (uimm != 0) { |
| 1340 | 1386 | tcg_gen_ext32u_tl(t0, t0); |
| 1341 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1387 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); | |
| 1342 | 1388 | } else { |
| 1343 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1389 | + tcg_gen_ext32s_tl(cpu_gpr[rt], t0); | |
| 1344 | 1390 | } |
| 1345 | 1391 | opn = "srl"; |
| 1346 | 1392 | break; |
| ... | ... | @@ -1352,16 +1398,16 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1352 | 1398 | |
| 1353 | 1399 | tcg_gen_trunc_tl_i32(r_tmp1, t0); |
| 1354 | 1400 | tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm); |
| 1355 | - tcg_gen_ext_i32_tl(t0, r_tmp1); | |
| 1401 | + tcg_gen_ext_i32_tl(cpu_gpr[rt], r_tmp1); | |
| 1356 | 1402 | tcg_temp_free_i32(r_tmp1); |
| 1357 | 1403 | } |
| 1358 | 1404 | opn = "rotr"; |
| 1359 | 1405 | } else { |
| 1360 | 1406 | if (uimm != 0) { |
| 1361 | 1407 | tcg_gen_ext32u_tl(t0, t0); |
| 1362 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1408 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); | |
| 1363 | 1409 | } else { |
| 1364 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1410 | + tcg_gen_ext32s_tl(cpu_gpr[rt], t0); | |
| 1365 | 1411 | } |
| 1366 | 1412 | opn = "srl"; |
| 1367 | 1413 | } |
| ... | ... | @@ -1374,28 +1420,28 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1374 | 1420 | break; |
| 1375 | 1421 | #if defined(TARGET_MIPS64) |
| 1376 | 1422 | case OPC_DSLL: |
| 1377 | - tcg_gen_shli_tl(t0, t0, uimm); | |
| 1423 | + tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); | |
| 1378 | 1424 | opn = "dsll"; |
| 1379 | 1425 | break; |
| 1380 | 1426 | case OPC_DSRA: |
| 1381 | - tcg_gen_sari_tl(t0, t0, uimm); | |
| 1427 | + tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); | |
| 1382 | 1428 | opn = "dsra"; |
| 1383 | 1429 | break; |
| 1384 | 1430 | case OPC_DSRL: |
| 1385 | 1431 | switch ((ctx->opcode >> 21) & 0x1f) { |
| 1386 | 1432 | case 0: |
| 1387 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1433 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); | |
| 1388 | 1434 | opn = "dsrl"; |
| 1389 | 1435 | break; |
| 1390 | 1436 | case 1: |
| 1391 | 1437 | /* drotr is decoded as dsrl on non-R2 CPUs */ |
| 1392 | 1438 | if (env->insn_flags & ISA_MIPS32R2) { |
| 1393 | 1439 | if (uimm != 0) { |
| 1394 | - tcg_gen_rotri_tl(t0, t0, uimm); | |
| 1440 | + tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); | |
| 1395 | 1441 | } |
| 1396 | 1442 | opn = "drotr"; |
| 1397 | 1443 | } else { |
| 1398 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1444 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); | |
| 1399 | 1445 | opn = "dsrl"; |
| 1400 | 1446 | } |
| 1401 | 1447 | break; |
| ... | ... | @@ -1406,26 +1452,26 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1406 | 1452 | } |
| 1407 | 1453 | break; |
| 1408 | 1454 | case OPC_DSLL32: |
| 1409 | - tcg_gen_shli_tl(t0, t0, uimm + 32); | |
| 1455 | + tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); | |
| 1410 | 1456 | opn = "dsll32"; |
| 1411 | 1457 | break; |
| 1412 | 1458 | case OPC_DSRA32: |
| 1413 | - tcg_gen_sari_tl(t0, t0, uimm + 32); | |
| 1459 | + tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); | |
| 1414 | 1460 | opn = "dsra32"; |
| 1415 | 1461 | break; |
| 1416 | 1462 | case OPC_DSRL32: |
| 1417 | 1463 | switch ((ctx->opcode >> 21) & 0x1f) { |
| 1418 | 1464 | case 0: |
| 1419 | - tcg_gen_shri_tl(t0, t0, uimm + 32); | |
| 1465 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); | |
| 1420 | 1466 | opn = "dsrl32"; |
| 1421 | 1467 | break; |
| 1422 | 1468 | case 1: |
| 1423 | 1469 | /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ |
| 1424 | 1470 | if (env->insn_flags & ISA_MIPS32R2) { |
| 1425 | - tcg_gen_rotri_tl(t0, t0, uimm + 32); | |
| 1471 | + tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); | |
| 1426 | 1472 | opn = "drotr32"; |
| 1427 | 1473 | } else { |
| 1428 | - tcg_gen_shri_tl(t0, t0, uimm + 32); | |
| 1474 | + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); | |
| 1429 | 1475 | opn = "dsrl32"; |
| 1430 | 1476 | } |
| 1431 | 1477 | break; |
| ... | ... | @@ -1436,14 +1482,8 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1436 | 1482 | } |
| 1437 | 1483 | break; |
| 1438 | 1484 | #endif |
| 1439 | - default: | |
| 1440 | - MIPS_INVAL(opn); | |
| 1441 | - generate_exception(ctx, EXCP_RI); | |
| 1442 | - goto out; | |
| 1443 | 1485 | } |
| 1444 | - gen_store_gpr(t0, rt); | |
| 1445 | 1486 | MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); |
| 1446 | - out: | |
| 1447 | 1487 | tcg_temp_free(t0); |
| 1448 | 1488 | } |
| 1449 | 1489 | |
| ... | ... | @@ -7556,9 +7596,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7556 | 7596 | case OPC_SPECIAL: |
| 7557 | 7597 | op1 = MASK_SPECIAL(ctx->opcode); |
| 7558 | 7598 | switch (op1) { |
| 7559 | - case OPC_SLL: /* Arithmetic with immediate */ | |
| 7560 | - case OPC_SRL ... OPC_SRA: | |
| 7561 | - gen_arith_imm(env, ctx, op1, rd, rt, sa); | |
| 7599 | + case OPC_SLL: /* Shift with immediate */ | |
| 7600 | + case OPC_SRA: | |
| 7601 | + case OPC_SRL: | |
| 7602 | + gen_shift_imm(env, ctx, op1, rd, rt, sa); | |
| 7562 | 7603 | break; |
| 7563 | 7604 | case OPC_MOVN: /* Conditional move */ |
| 7564 | 7605 | case OPC_MOVZ: |
| ... | ... | @@ -7648,12 +7689,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7648 | 7689 | #if defined(TARGET_MIPS64) |
| 7649 | 7690 | /* MIPS64 specific opcodes */ |
| 7650 | 7691 | case OPC_DSLL: |
| 7651 | - case OPC_DSRL ... OPC_DSRA: | |
| 7692 | + case OPC_DSRA: | |
| 7693 | + case OPC_DSRL: | |
| 7652 | 7694 | case OPC_DSLL32: |
| 7653 | - case OPC_DSRL32 ... OPC_DSRA32: | |
| 7695 | + case OPC_DSRA32: | |
| 7696 | + case OPC_DSRL32: | |
| 7654 | 7697 | check_insn(env, ctx, ISA_MIPS3); |
| 7655 | 7698 | check_mips_64(ctx); |
| 7656 | - gen_arith_imm(env, ctx, op1, rd, rt, sa); | |
| 7699 | + gen_shift_imm(env, ctx, op1, rd, rt, sa); | |
| 7657 | 7700 | break; |
| 7658 | 7701 | case OPC_DADD ... OPC_DSUBU: |
| 7659 | 7702 | check_insn(env, ctx, ISA_MIPS3); |
| ... | ... | @@ -7928,9 +7971,20 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7928 | 7971 | break; |
| 7929 | 7972 | } |
| 7930 | 7973 | break; |
| 7931 | - case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */ | |
| 7974 | + case OPC_ADDI: /* Arithmetic with immediate opcode */ | |
| 7975 | + case OPC_ADDIU: | |
| 7932 | 7976 | gen_arith_imm(env, ctx, op, rt, rs, imm); |
| 7933 | 7977 | break; |
| 7978 | + case OPC_SLTI: /* Set on less than with immediate opcode */ | |
| 7979 | + case OPC_SLTIU: | |
| 7980 | + gen_slt_imm(env, op, rt, rs, imm); | |
| 7981 | + break; | |
| 7982 | + case OPC_ANDI: /* Arithmetic with immediate opcode */ | |
| 7983 | + case OPC_LUI: | |
| 7984 | + case OPC_ORI: | |
| 7985 | + case OPC_XORI: | |
| 7986 | + gen_logic_imm(env, op, rt, rs, imm); | |
| 7987 | + break; | |
| 7934 | 7988 | case OPC_J ... OPC_JAL: /* Jump */ |
| 7935 | 7989 | offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; |
| 7936 | 7990 | gen_compute_branch(ctx, op, rs, rt, offset); |
| ... | ... | @@ -8080,7 +8134,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 8080 | 8134 | check_mips_64(ctx); |
| 8081 | 8135 | gen_ldst(ctx, op, rt, rs, imm); |
| 8082 | 8136 | break; |
| 8083 | - case OPC_DADDI ... OPC_DADDIU: | |
| 8137 | + case OPC_DADDI: | |
| 8138 | + case OPC_DADDIU: | |
| 8084 | 8139 | check_insn(env, ctx, ISA_MIPS3); |
| 8085 | 8140 | check_mips_64(ctx); |
| 8086 | 8141 | gen_arith_imm(env, ctx, op, rt, rs, imm); | ... | ... |