Commit 324d9e320426253bd710a9efe210797435173eab

Authored by aurel32
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,10 +57,12 @@ enum {
57 OPC_ADDIU = (0x09 << 26), 57 OPC_ADDIU = (0x09 << 26),
58 OPC_SLTI = (0x0A << 26), 58 OPC_SLTI = (0x0A << 26),
59 OPC_SLTIU = (0x0B << 26), 59 OPC_SLTIU = (0x0B << 26),
  60 + /* logic with immediate */
60 OPC_ANDI = (0x0C << 26), 61 OPC_ANDI = (0x0C << 26),
61 OPC_ORI = (0x0D << 26), 62 OPC_ORI = (0x0D << 26),
62 OPC_XORI = (0x0E << 26), 63 OPC_XORI = (0x0E << 26),
63 OPC_LUI = (0x0F << 26), 64 OPC_LUI = (0x0F << 26),
  65 + /* arithmetic with immediate */
64 OPC_DADDI = (0x18 << 26), 66 OPC_DADDI = (0x18 << 26),
65 OPC_DADDIU = (0x19 << 26), 67 OPC_DADDIU = (0x19 << 26),
66 /* Jump and branches */ 68 /* Jump and branches */
@@ -1197,140 +1199,184 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, @@ -1197,140 +1199,184 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1197 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, 1199 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1198 int rt, int rs, int16_t imm) 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 const char *opn = "imm arith"; 1203 const char *opn = "imm arith";
1202 - TCGv t0 = tcg_temp_local_new();  
1203 1204
1204 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 1205 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1205 /* If no destination, treat it as a NOP. 1206 /* If no destination, treat it as a NOP.
1206 For addi, we must generate the overflow exception when needed. */ 1207 For addi, we must generate the overflow exception when needed. */
1207 MIPS_DEBUG("NOP"); 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 switch (opc) { 1211 switch (opc) {
1246 case OPC_ADDI: 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 int l1 = gen_new_label(); 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 /* operands of same sign, result different sign */ 1229 /* operands of same sign, result different sign */
1262 generate_exception(ctx, EXCP_OVERFLOW); 1230 generate_exception(ctx, EXCP_OVERFLOW);
1263 gen_set_label(l1); 1231 gen_set_label(l1);
1264 - tcg_temp_free(r_tmp1);  
1265 -  
1266 tcg_gen_ext32s_tl(t0, t0); 1232 tcg_gen_ext32s_tl(t0, t0);
  1233 + gen_store_gpr(t0, rt);
  1234 + tcg_temp_free(t0);
1267 } 1235 }
1268 opn = "addi"; 1236 opn = "addi";
1269 break; 1237 break;
1270 case OPC_ADDIU: 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 opn = "addiu"; 1245 opn = "addiu";
1274 break; 1246 break;
1275 #if defined(TARGET_MIPS64) 1247 #if defined(TARGET_MIPS64)
1276 case OPC_DADDI: 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 int l1 = gen_new_label(); 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 /* operands of same sign, result different sign */ 1264 /* operands of same sign, result different sign */
1292 generate_exception(ctx, EXCP_OVERFLOW); 1265 generate_exception(ctx, EXCP_OVERFLOW);
1293 gen_set_label(l1); 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 opn = "daddi"; 1270 opn = "daddi";
1297 break; 1271 break;
1298 case OPC_DADDIU: 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 opn = "daddiu"; 1278 opn = "daddiu";
1301 break; 1279 break;
1302 #endif 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 case OPC_ANDI: 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 opn = "andi"; 1303 opn = "andi";
1314 break; 1304 break;
1315 case OPC_ORI: 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 opn = "ori"; 1310 opn = "ori";
1318 break; 1311 break;
1319 case OPC_XORI: 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 opn = "xori"; 1317 opn = "xori";
1322 break; 1318 break;
1323 case OPC_LUI: 1319 case OPC_LUI:
  1320 + tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1324 opn = "lui"; 1321 opn = "lui";
1325 break; 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 case OPC_SLL: 1372 case OPC_SLL:
1327 tcg_gen_shli_tl(t0, t0, uimm); 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 opn = "sll"; 1375 opn = "sll";
1330 break; 1376 break;
1331 case OPC_SRA: 1377 case OPC_SRA:
1332 tcg_gen_ext32s_tl(t0, t0); 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 opn = "sra"; 1380 opn = "sra";
1335 break; 1381 break;
1336 case OPC_SRL: 1382 case OPC_SRL:
@@ -1338,9 +1384,9 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1338,9 +1384,9 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1338 case 0: 1384 case 0:
1339 if (uimm != 0) { 1385 if (uimm != 0) {
1340 tcg_gen_ext32u_tl(t0, t0); 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 } else { 1388 } else {
1343 - tcg_gen_ext32s_tl(t0, t0); 1389 + tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1344 } 1390 }
1345 opn = "srl"; 1391 opn = "srl";
1346 break; 1392 break;
@@ -1352,16 +1398,16 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1352,16 +1398,16 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1352 1398
1353 tcg_gen_trunc_tl_i32(r_tmp1, t0); 1399 tcg_gen_trunc_tl_i32(r_tmp1, t0);
1354 tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm); 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 tcg_temp_free_i32(r_tmp1); 1402 tcg_temp_free_i32(r_tmp1);
1357 } 1403 }
1358 opn = "rotr"; 1404 opn = "rotr";
1359 } else { 1405 } else {
1360 if (uimm != 0) { 1406 if (uimm != 0) {
1361 tcg_gen_ext32u_tl(t0, t0); 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 } else { 1409 } else {
1364 - tcg_gen_ext32s_tl(t0, t0); 1410 + tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1365 } 1411 }
1366 opn = "srl"; 1412 opn = "srl";
1367 } 1413 }
@@ -1374,28 +1420,28 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1374,28 +1420,28 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1374 break; 1420 break;
1375 #if defined(TARGET_MIPS64) 1421 #if defined(TARGET_MIPS64)
1376 case OPC_DSLL: 1422 case OPC_DSLL:
1377 - tcg_gen_shli_tl(t0, t0, uimm); 1423 + tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1378 opn = "dsll"; 1424 opn = "dsll";
1379 break; 1425 break;
1380 case OPC_DSRA: 1426 case OPC_DSRA:
1381 - tcg_gen_sari_tl(t0, t0, uimm); 1427 + tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1382 opn = "dsra"; 1428 opn = "dsra";
1383 break; 1429 break;
1384 case OPC_DSRL: 1430 case OPC_DSRL:
1385 switch ((ctx->opcode >> 21) & 0x1f) { 1431 switch ((ctx->opcode >> 21) & 0x1f) {
1386 case 0: 1432 case 0:
1387 - tcg_gen_shri_tl(t0, t0, uimm); 1433 + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1388 opn = "dsrl"; 1434 opn = "dsrl";
1389 break; 1435 break;
1390 case 1: 1436 case 1:
1391 /* drotr is decoded as dsrl on non-R2 CPUs */ 1437 /* drotr is decoded as dsrl on non-R2 CPUs */
1392 if (env->insn_flags & ISA_MIPS32R2) { 1438 if (env->insn_flags & ISA_MIPS32R2) {
1393 if (uimm != 0) { 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 opn = "drotr"; 1442 opn = "drotr";
1397 } else { 1443 } else {
1398 - tcg_gen_shri_tl(t0, t0, uimm); 1444 + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1399 opn = "dsrl"; 1445 opn = "dsrl";
1400 } 1446 }
1401 break; 1447 break;
@@ -1406,26 +1452,26 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1406,26 +1452,26 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1406 } 1452 }
1407 break; 1453 break;
1408 case OPC_DSLL32: 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 opn = "dsll32"; 1456 opn = "dsll32";
1411 break; 1457 break;
1412 case OPC_DSRA32: 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 opn = "dsra32"; 1460 opn = "dsra32";
1415 break; 1461 break;
1416 case OPC_DSRL32: 1462 case OPC_DSRL32:
1417 switch ((ctx->opcode >> 21) & 0x1f) { 1463 switch ((ctx->opcode >> 21) & 0x1f) {
1418 case 0: 1464 case 0:
1419 - tcg_gen_shri_tl(t0, t0, uimm + 32); 1465 + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1420 opn = "dsrl32"; 1466 opn = "dsrl32";
1421 break; 1467 break;
1422 case 1: 1468 case 1:
1423 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 1469 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1424 if (env->insn_flags & ISA_MIPS32R2) { 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 opn = "drotr32"; 1472 opn = "drotr32";
1427 } else { 1473 } else {
1428 - tcg_gen_shri_tl(t0, t0, uimm + 32); 1474 + tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1429 opn = "dsrl32"; 1475 opn = "dsrl32";
1430 } 1476 }
1431 break; 1477 break;
@@ -1436,14 +1482,8 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1436,14 +1482,8 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1436 } 1482 }
1437 break; 1483 break;
1438 #endif 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 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1486 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1446 - out:  
1447 tcg_temp_free(t0); 1487 tcg_temp_free(t0);
1448 } 1488 }
1449 1489
@@ -7556,9 +7596,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -7556,9 +7596,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
7556 case OPC_SPECIAL: 7596 case OPC_SPECIAL:
7557 op1 = MASK_SPECIAL(ctx->opcode); 7597 op1 = MASK_SPECIAL(ctx->opcode);
7558 switch (op1) { 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 break; 7603 break;
7563 case OPC_MOVN: /* Conditional move */ 7604 case OPC_MOVN: /* Conditional move */
7564 case OPC_MOVZ: 7605 case OPC_MOVZ:
@@ -7648,12 +7689,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -7648,12 +7689,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
7648 #if defined(TARGET_MIPS64) 7689 #if defined(TARGET_MIPS64)
7649 /* MIPS64 specific opcodes */ 7690 /* MIPS64 specific opcodes */
7650 case OPC_DSLL: 7691 case OPC_DSLL:
7651 - case OPC_DSRL ... OPC_DSRA: 7692 + case OPC_DSRA:
  7693 + case OPC_DSRL:
7652 case OPC_DSLL32: 7694 case OPC_DSLL32:
7653 - case OPC_DSRL32 ... OPC_DSRA32: 7695 + case OPC_DSRA32:
  7696 + case OPC_DSRL32:
7654 check_insn(env, ctx, ISA_MIPS3); 7697 check_insn(env, ctx, ISA_MIPS3);
7655 check_mips_64(ctx); 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 break; 7700 break;
7658 case OPC_DADD ... OPC_DSUBU: 7701 case OPC_DADD ... OPC_DSUBU:
7659 check_insn(env, ctx, ISA_MIPS3); 7702 check_insn(env, ctx, ISA_MIPS3);
@@ -7928,9 +7971,20 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -7928,9 +7971,20 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
7928 break; 7971 break;
7929 } 7972 }
7930 break; 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 gen_arith_imm(env, ctx, op, rt, rs, imm); 7976 gen_arith_imm(env, ctx, op, rt, rs, imm);
7933 break; 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 case OPC_J ... OPC_JAL: /* Jump */ 7988 case OPC_J ... OPC_JAL: /* Jump */
7935 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 7989 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7936 gen_compute_branch(ctx, op, rs, rt, offset); 7990 gen_compute_branch(ctx, op, rs, rt, offset);
@@ -8080,7 +8134,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -8080,7 +8134,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
8080 check_mips_64(ctx); 8134 check_mips_64(ctx);
8081 gen_ldst(ctx, op, rt, rs, imm); 8135 gen_ldst(ctx, op, rt, rs, imm);
8082 break; 8136 break;
8083 - case OPC_DADDI ... OPC_DADDIU: 8137 + case OPC_DADDI:
  8138 + case OPC_DADDIU:
8084 check_insn(env, ctx, ISA_MIPS3); 8139 check_insn(env, ctx, ISA_MIPS3);
8085 check_mips_64(ctx); 8140 check_mips_64(ctx);
8086 gen_arith_imm(env, ctx, op, rt, rs, imm); 8141 gen_arith_imm(env, ctx, op, rt, rs, imm);