.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Single-step support. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | #include <linux/kernel.h> |
---|
12 | 8 | #include <linux/kprobes.h> |
---|
.. | .. |
---|
17 | 13 | #include <linux/uaccess.h> |
---|
18 | 14 | #include <asm/cpu_has_feature.h> |
---|
19 | 15 | #include <asm/cputable.h> |
---|
| 16 | +#include <asm/disassemble.h> |
---|
20 | 17 | |
---|
21 | 18 | extern char system_call_common[]; |
---|
| 19 | +extern char system_call_vectored_emulate[]; |
---|
22 | 20 | |
---|
23 | 21 | #ifdef CONFIG_PPC64 |
---|
24 | 22 | /* Bits in SRR1 that are copied from MSR */ |
---|
.. | .. |
---|
110 | 108 | { |
---|
111 | 109 | if (!user_mode(regs)) |
---|
112 | 110 | return 1; |
---|
113 | | - if (__access_ok(ea, nb, USER_DS)) |
---|
| 111 | + if (access_ok((void __user *)ea, nb)) |
---|
114 | 112 | return 1; |
---|
115 | | - if (__access_ok(ea, 1, USER_DS)) |
---|
| 113 | + if (access_ok((void __user *)ea, 1)) |
---|
116 | 114 | /* Access overlaps the end of the user region */ |
---|
117 | | - regs->dar = USER_DS.seg; |
---|
| 115 | + regs->dar = TASK_SIZE_MAX - 1; |
---|
118 | 116 | else |
---|
119 | 117 | regs->dar = ea; |
---|
120 | 118 | return 0; |
---|
.. | .. |
---|
187 | 185 | ea = regs->gpr[rb]; |
---|
188 | 186 | if (ra) |
---|
189 | 187 | ea += regs->gpr[ra]; |
---|
| 188 | + |
---|
| 189 | + return ea; |
---|
| 190 | +} |
---|
| 191 | + |
---|
| 192 | +/* |
---|
| 193 | + * Calculate effective address for a MLS:D-form / 8LS:D-form |
---|
| 194 | + * prefixed instruction |
---|
| 195 | + */ |
---|
| 196 | +static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr, |
---|
| 197 | + unsigned int suffix, |
---|
| 198 | + const struct pt_regs *regs) |
---|
| 199 | +{ |
---|
| 200 | + int ra, prefix_r; |
---|
| 201 | + unsigned int dd; |
---|
| 202 | + unsigned long ea, d0, d1, d; |
---|
| 203 | + |
---|
| 204 | + prefix_r = GET_PREFIX_R(instr); |
---|
| 205 | + ra = GET_PREFIX_RA(suffix); |
---|
| 206 | + |
---|
| 207 | + d0 = instr & 0x3ffff; |
---|
| 208 | + d1 = suffix & 0xffff; |
---|
| 209 | + d = (d0 << 16) | d1; |
---|
| 210 | + |
---|
| 211 | + /* |
---|
| 212 | + * sign extend a 34 bit number |
---|
| 213 | + */ |
---|
| 214 | + dd = (unsigned int)(d >> 2); |
---|
| 215 | + ea = (signed int)dd; |
---|
| 216 | + ea = (ea << 2) | (d & 0x3); |
---|
| 217 | + |
---|
| 218 | + if (!prefix_r && ra) |
---|
| 219 | + ea += regs->gpr[ra]; |
---|
| 220 | + else if (!prefix_r && !ra) |
---|
| 221 | + ; /* Leave ea as is */ |
---|
| 222 | + else if (prefix_r) |
---|
| 223 | + ea += regs->nip; |
---|
| 224 | + |
---|
| 225 | + /* |
---|
| 226 | + * (prefix_r && ra) is an invalid form. Should already be |
---|
| 227 | + * checked for by caller! |
---|
| 228 | + */ |
---|
190 | 229 | |
---|
191 | 230 | return ea; |
---|
192 | 231 | } |
---|
.. | .. |
---|
910 | 949 | |
---|
911 | 950 | #define __put_user_asmx(x, addr, err, op, cr) \ |
---|
912 | 951 | __asm__ __volatile__( \ |
---|
| 952 | + ".machine push\n" \ |
---|
| 953 | + ".machine power8\n" \ |
---|
913 | 954 | "1: " op " %2,0,%3\n" \ |
---|
| 955 | + ".machine pop\n" \ |
---|
914 | 956 | " mfcr %1\n" \ |
---|
915 | 957 | "2:\n" \ |
---|
916 | 958 | ".section .fixup,\"ax\"\n" \ |
---|
.. | .. |
---|
923 | 965 | |
---|
924 | 966 | #define __get_user_asmx(x, addr, err, op) \ |
---|
925 | 967 | __asm__ __volatile__( \ |
---|
| 968 | + ".machine push\n" \ |
---|
| 969 | + ".machine power8\n" \ |
---|
926 | 970 | "1: "op" %1,0,%2\n" \ |
---|
| 971 | + ".machine pop\n" \ |
---|
927 | 972 | "2:\n" \ |
---|
928 | 973 | ".section .fixup,\"ax\"\n" \ |
---|
929 | 974 | "3: li %0,%3\n" \ |
---|
.. | .. |
---|
1167 | 1212 | * otherwise. |
---|
1168 | 1213 | */ |
---|
1169 | 1214 | int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, |
---|
1170 | | - unsigned int instr) |
---|
| 1215 | + struct ppc_inst instr) |
---|
1171 | 1216 | { |
---|
1172 | | - unsigned int opcode, ra, rb, rd, spr, u; |
---|
| 1217 | +#ifdef CONFIG_PPC64 |
---|
| 1218 | + unsigned int suffixopcode, prefixtype, prefix_r; |
---|
| 1219 | +#endif |
---|
| 1220 | + unsigned int opcode, ra, rb, rc, rd, spr, u; |
---|
1173 | 1221 | unsigned long int imm; |
---|
1174 | 1222 | unsigned long int val, val2; |
---|
1175 | 1223 | unsigned int mb, me, sh; |
---|
| 1224 | + unsigned int word, suffix; |
---|
1176 | 1225 | long ival; |
---|
| 1226 | + |
---|
| 1227 | + word = ppc_inst_val(instr); |
---|
| 1228 | + suffix = ppc_inst_suffix(instr); |
---|
1177 | 1229 | |
---|
1178 | 1230 | op->type = COMPUTE; |
---|
1179 | 1231 | |
---|
1180 | | - opcode = instr >> 26; |
---|
| 1232 | + opcode = ppc_inst_primary_opcode(instr); |
---|
1181 | 1233 | switch (opcode) { |
---|
1182 | 1234 | case 16: /* bc */ |
---|
1183 | 1235 | op->type = BRANCH; |
---|
1184 | | - imm = (signed short)(instr & 0xfffc); |
---|
1185 | | - if ((instr & 2) == 0) |
---|
| 1236 | + imm = (signed short)(word & 0xfffc); |
---|
| 1237 | + if ((word & 2) == 0) |
---|
1186 | 1238 | imm += regs->nip; |
---|
1187 | 1239 | op->val = truncate_if_32bit(regs->msr, imm); |
---|
1188 | | - if (instr & 1) |
---|
| 1240 | + if (word & 1) |
---|
1189 | 1241 | op->type |= SETLK; |
---|
1190 | | - if (branch_taken(instr, regs, op)) |
---|
| 1242 | + if (branch_taken(word, regs, op)) |
---|
1191 | 1243 | op->type |= BRTAKEN; |
---|
1192 | 1244 | return 1; |
---|
1193 | 1245 | #ifdef CONFIG_PPC64 |
---|
1194 | 1246 | case 17: /* sc */ |
---|
1195 | | - if ((instr & 0xfe2) == 2) |
---|
| 1247 | + if ((word & 0xfe2) == 2) |
---|
1196 | 1248 | op->type = SYSCALL; |
---|
1197 | | - else |
---|
| 1249 | + else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && |
---|
| 1250 | + (word & 0xfe3) == 1) { /* scv */ |
---|
| 1251 | + op->type = SYSCALL_VECTORED_0; |
---|
| 1252 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1253 | + goto unknown_opcode; |
---|
| 1254 | + } else |
---|
1198 | 1255 | op->type = UNKNOWN; |
---|
1199 | 1256 | return 0; |
---|
1200 | 1257 | #endif |
---|
1201 | 1258 | case 18: /* b */ |
---|
1202 | 1259 | op->type = BRANCH | BRTAKEN; |
---|
1203 | | - imm = instr & 0x03fffffc; |
---|
| 1260 | + imm = word & 0x03fffffc; |
---|
1204 | 1261 | if (imm & 0x02000000) |
---|
1205 | 1262 | imm -= 0x04000000; |
---|
1206 | | - if ((instr & 2) == 0) |
---|
| 1263 | + if ((word & 2) == 0) |
---|
1207 | 1264 | imm += regs->nip; |
---|
1208 | 1265 | op->val = truncate_if_32bit(regs->msr, imm); |
---|
1209 | | - if (instr & 1) |
---|
| 1266 | + if (word & 1) |
---|
1210 | 1267 | op->type |= SETLK; |
---|
1211 | 1268 | return 1; |
---|
1212 | 1269 | case 19: |
---|
1213 | | - switch ((instr >> 1) & 0x3ff) { |
---|
| 1270 | + switch ((word >> 1) & 0x3ff) { |
---|
1214 | 1271 | case 0: /* mcrf */ |
---|
1215 | 1272 | op->type = COMPUTE + SETCC; |
---|
1216 | | - rd = 7 - ((instr >> 23) & 0x7); |
---|
1217 | | - ra = 7 - ((instr >> 18) & 0x7); |
---|
| 1273 | + rd = 7 - ((word >> 23) & 0x7); |
---|
| 1274 | + ra = 7 - ((word >> 18) & 0x7); |
---|
1218 | 1275 | rd *= 4; |
---|
1219 | 1276 | ra *= 4; |
---|
1220 | 1277 | val = (regs->ccr >> ra) & 0xf; |
---|
.. | .. |
---|
1224 | 1281 | case 16: /* bclr */ |
---|
1225 | 1282 | case 528: /* bcctr */ |
---|
1226 | 1283 | op->type = BRANCH; |
---|
1227 | | - imm = (instr & 0x400)? regs->ctr: regs->link; |
---|
| 1284 | + imm = (word & 0x400)? regs->ctr: regs->link; |
---|
1228 | 1285 | op->val = truncate_if_32bit(regs->msr, imm); |
---|
1229 | | - if (instr & 1) |
---|
| 1286 | + if (word & 1) |
---|
1230 | 1287 | op->type |= SETLK; |
---|
1231 | | - if (branch_taken(instr, regs, op)) |
---|
| 1288 | + if (branch_taken(word, regs, op)) |
---|
1232 | 1289 | op->type |= BRTAKEN; |
---|
1233 | 1290 | return 1; |
---|
1234 | 1291 | |
---|
.. | .. |
---|
1251 | 1308 | case 417: /* crorc */ |
---|
1252 | 1309 | case 449: /* cror */ |
---|
1253 | 1310 | op->type = COMPUTE + SETCC; |
---|
1254 | | - ra = (instr >> 16) & 0x1f; |
---|
1255 | | - rb = (instr >> 11) & 0x1f; |
---|
1256 | | - rd = (instr >> 21) & 0x1f; |
---|
| 1311 | + ra = (word >> 16) & 0x1f; |
---|
| 1312 | + rb = (word >> 11) & 0x1f; |
---|
| 1313 | + rd = (word >> 21) & 0x1f; |
---|
1257 | 1314 | ra = (regs->ccr >> (31 - ra)) & 1; |
---|
1258 | 1315 | rb = (regs->ccr >> (31 - rb)) & 1; |
---|
1259 | | - val = (instr >> (6 + ra * 2 + rb)) & 1; |
---|
| 1316 | + val = (word >> (6 + ra * 2 + rb)) & 1; |
---|
1260 | 1317 | op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | |
---|
1261 | 1318 | (val << (31 - rd)); |
---|
1262 | 1319 | return 1; |
---|
1263 | 1320 | } |
---|
1264 | 1321 | break; |
---|
1265 | 1322 | case 31: |
---|
1266 | | - switch ((instr >> 1) & 0x3ff) { |
---|
| 1323 | + switch ((word >> 1) & 0x3ff) { |
---|
1267 | 1324 | case 598: /* sync */ |
---|
1268 | 1325 | op->type = BARRIER + BARRIER_SYNC; |
---|
1269 | 1326 | #ifdef __powerpc64__ |
---|
1270 | | - switch ((instr >> 21) & 3) { |
---|
| 1327 | + switch ((word >> 21) & 3) { |
---|
1271 | 1328 | case 1: /* lwsync */ |
---|
1272 | 1329 | op->type = BARRIER + BARRIER_LWSYNC; |
---|
1273 | 1330 | break; |
---|
.. | .. |
---|
1289 | 1346 | if (!FULL_REGS(regs)) |
---|
1290 | 1347 | return -1; |
---|
1291 | 1348 | |
---|
1292 | | - rd = (instr >> 21) & 0x1f; |
---|
1293 | | - ra = (instr >> 16) & 0x1f; |
---|
1294 | | - rb = (instr >> 11) & 0x1f; |
---|
| 1349 | + rd = (word >> 21) & 0x1f; |
---|
| 1350 | + ra = (word >> 16) & 0x1f; |
---|
| 1351 | + rb = (word >> 11) & 0x1f; |
---|
| 1352 | + rc = (word >> 6) & 0x1f; |
---|
1295 | 1353 | |
---|
1296 | 1354 | switch (opcode) { |
---|
1297 | 1355 | #ifdef __powerpc64__ |
---|
| 1356 | + case 1: |
---|
| 1357 | + if (!cpu_has_feature(CPU_FTR_ARCH_31)) |
---|
| 1358 | + goto unknown_opcode; |
---|
| 1359 | + |
---|
| 1360 | + prefix_r = GET_PREFIX_R(word); |
---|
| 1361 | + ra = GET_PREFIX_RA(suffix); |
---|
| 1362 | + rd = (suffix >> 21) & 0x1f; |
---|
| 1363 | + op->reg = rd; |
---|
| 1364 | + op->val = regs->gpr[rd]; |
---|
| 1365 | + suffixopcode = get_op(suffix); |
---|
| 1366 | + prefixtype = (word >> 24) & 0x3; |
---|
| 1367 | + switch (prefixtype) { |
---|
| 1368 | + case 2: |
---|
| 1369 | + if (prefix_r && ra) |
---|
| 1370 | + return 0; |
---|
| 1371 | + switch (suffixopcode) { |
---|
| 1372 | + case 14: /* paddi */ |
---|
| 1373 | + op->type = COMPUTE | PREFIXED; |
---|
| 1374 | + op->val = mlsd_8lsd_ea(word, suffix, regs); |
---|
| 1375 | + goto compute_done; |
---|
| 1376 | + } |
---|
| 1377 | + } |
---|
| 1378 | + break; |
---|
1298 | 1379 | case 2: /* tdi */ |
---|
1299 | | - if (rd & trap_compare(regs->gpr[ra], (short) instr)) |
---|
| 1380 | + if (rd & trap_compare(regs->gpr[ra], (short) word)) |
---|
1300 | 1381 | goto trap; |
---|
1301 | 1382 | return 1; |
---|
1302 | 1383 | #endif |
---|
1303 | 1384 | case 3: /* twi */ |
---|
1304 | | - if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) |
---|
| 1385 | + if (rd & trap_compare((int)regs->gpr[ra], (short) word)) |
---|
1305 | 1386 | goto trap; |
---|
1306 | 1387 | return 1; |
---|
1307 | 1388 | |
---|
| 1389 | +#ifdef __powerpc64__ |
---|
| 1390 | + case 4: |
---|
| 1391 | + /* |
---|
| 1392 | + * There are very many instructions with this primary opcode |
---|
| 1393 | + * introduced in the ISA as early as v2.03. However, the ones |
---|
| 1394 | + * we currently emulate were all introduced with ISA 3.0 |
---|
| 1395 | + */ |
---|
| 1396 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1397 | + goto unknown_opcode; |
---|
| 1398 | + |
---|
| 1399 | + switch (word & 0x3f) { |
---|
| 1400 | + case 48: /* maddhd */ |
---|
| 1401 | + asm volatile(PPC_MADDHD(%0, %1, %2, %3) : |
---|
| 1402 | + "=r" (op->val) : "r" (regs->gpr[ra]), |
---|
| 1403 | + "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); |
---|
| 1404 | + goto compute_done; |
---|
| 1405 | + |
---|
| 1406 | + case 49: /* maddhdu */ |
---|
| 1407 | + asm volatile(PPC_MADDHDU(%0, %1, %2, %3) : |
---|
| 1408 | + "=r" (op->val) : "r" (regs->gpr[ra]), |
---|
| 1409 | + "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); |
---|
| 1410 | + goto compute_done; |
---|
| 1411 | + |
---|
| 1412 | + case 51: /* maddld */ |
---|
| 1413 | + asm volatile(PPC_MADDLD(%0, %1, %2, %3) : |
---|
| 1414 | + "=r" (op->val) : "r" (regs->gpr[ra]), |
---|
| 1415 | + "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); |
---|
| 1416 | + goto compute_done; |
---|
| 1417 | + } |
---|
| 1418 | + |
---|
| 1419 | + /* |
---|
| 1420 | + * There are other instructions from ISA 3.0 with the same |
---|
| 1421 | + * primary opcode which do not have emulation support yet. |
---|
| 1422 | + */ |
---|
| 1423 | + goto unknown_opcode; |
---|
| 1424 | +#endif |
---|
| 1425 | + |
---|
1308 | 1426 | case 7: /* mulli */ |
---|
1309 | | - op->val = regs->gpr[ra] * (short) instr; |
---|
| 1427 | + op->val = regs->gpr[ra] * (short) word; |
---|
1310 | 1428 | goto compute_done; |
---|
1311 | 1429 | |
---|
1312 | 1430 | case 8: /* subfic */ |
---|
1313 | | - imm = (short) instr; |
---|
| 1431 | + imm = (short) word; |
---|
1314 | 1432 | add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1); |
---|
1315 | 1433 | return 1; |
---|
1316 | 1434 | |
---|
1317 | 1435 | case 10: /* cmpli */ |
---|
1318 | | - imm = (unsigned short) instr; |
---|
| 1436 | + imm = (unsigned short) word; |
---|
1319 | 1437 | val = regs->gpr[ra]; |
---|
1320 | 1438 | #ifdef __powerpc64__ |
---|
1321 | 1439 | if ((rd & 1) == 0) |
---|
.. | .. |
---|
1325 | 1443 | return 1; |
---|
1326 | 1444 | |
---|
1327 | 1445 | case 11: /* cmpi */ |
---|
1328 | | - imm = (short) instr; |
---|
| 1446 | + imm = (short) word; |
---|
1329 | 1447 | val = regs->gpr[ra]; |
---|
1330 | 1448 | #ifdef __powerpc64__ |
---|
1331 | 1449 | if ((rd & 1) == 0) |
---|
.. | .. |
---|
1335 | 1453 | return 1; |
---|
1336 | 1454 | |
---|
1337 | 1455 | case 12: /* addic */ |
---|
1338 | | - imm = (short) instr; |
---|
| 1456 | + imm = (short) word; |
---|
1339 | 1457 | add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); |
---|
1340 | 1458 | return 1; |
---|
1341 | 1459 | |
---|
1342 | 1460 | case 13: /* addic. */ |
---|
1343 | | - imm = (short) instr; |
---|
| 1461 | + imm = (short) word; |
---|
1344 | 1462 | add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); |
---|
1345 | 1463 | set_cr0(regs, op); |
---|
1346 | 1464 | return 1; |
---|
1347 | 1465 | |
---|
1348 | 1466 | case 14: /* addi */ |
---|
1349 | | - imm = (short) instr; |
---|
| 1467 | + imm = (short) word; |
---|
1350 | 1468 | if (ra) |
---|
1351 | 1469 | imm += regs->gpr[ra]; |
---|
1352 | 1470 | op->val = imm; |
---|
1353 | 1471 | goto compute_done; |
---|
1354 | 1472 | |
---|
1355 | 1473 | case 15: /* addis */ |
---|
1356 | | - imm = ((short) instr) << 16; |
---|
| 1474 | + imm = ((short) word) << 16; |
---|
1357 | 1475 | if (ra) |
---|
1358 | 1476 | imm += regs->gpr[ra]; |
---|
1359 | 1477 | op->val = imm; |
---|
1360 | 1478 | goto compute_done; |
---|
1361 | 1479 | |
---|
1362 | 1480 | case 19: |
---|
1363 | | - if (((instr >> 1) & 0x1f) == 2) { |
---|
| 1481 | + if (((word >> 1) & 0x1f) == 2) { |
---|
1364 | 1482 | /* addpcis */ |
---|
1365 | | - imm = (short) (instr & 0xffc1); /* d0 + d2 fields */ |
---|
1366 | | - imm |= (instr >> 15) & 0x3e; /* d1 field */ |
---|
| 1483 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1484 | + goto unknown_opcode; |
---|
| 1485 | + imm = (short) (word & 0xffc1); /* d0 + d2 fields */ |
---|
| 1486 | + imm |= (word >> 15) & 0x3e; /* d1 field */ |
---|
1367 | 1487 | op->val = regs->nip + (imm << 16) + 4; |
---|
1368 | 1488 | goto compute_done; |
---|
1369 | 1489 | } |
---|
.. | .. |
---|
1371 | 1491 | return 0; |
---|
1372 | 1492 | |
---|
1373 | 1493 | case 20: /* rlwimi */ |
---|
1374 | | - mb = (instr >> 6) & 0x1f; |
---|
1375 | | - me = (instr >> 1) & 0x1f; |
---|
| 1494 | + mb = (word >> 6) & 0x1f; |
---|
| 1495 | + me = (word >> 1) & 0x1f; |
---|
1376 | 1496 | val = DATA32(regs->gpr[rd]); |
---|
1377 | 1497 | imm = MASK32(mb, me); |
---|
1378 | 1498 | op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); |
---|
1379 | 1499 | goto logical_done; |
---|
1380 | 1500 | |
---|
1381 | 1501 | case 21: /* rlwinm */ |
---|
1382 | | - mb = (instr >> 6) & 0x1f; |
---|
1383 | | - me = (instr >> 1) & 0x1f; |
---|
| 1502 | + mb = (word >> 6) & 0x1f; |
---|
| 1503 | + me = (word >> 1) & 0x1f; |
---|
1384 | 1504 | val = DATA32(regs->gpr[rd]); |
---|
1385 | 1505 | op->val = ROTATE(val, rb) & MASK32(mb, me); |
---|
1386 | 1506 | goto logical_done; |
---|
1387 | 1507 | |
---|
1388 | 1508 | case 23: /* rlwnm */ |
---|
1389 | | - mb = (instr >> 6) & 0x1f; |
---|
1390 | | - me = (instr >> 1) & 0x1f; |
---|
| 1509 | + mb = (word >> 6) & 0x1f; |
---|
| 1510 | + me = (word >> 1) & 0x1f; |
---|
1391 | 1511 | rb = regs->gpr[rb] & 0x1f; |
---|
1392 | 1512 | val = DATA32(regs->gpr[rd]); |
---|
1393 | 1513 | op->val = ROTATE(val, rb) & MASK32(mb, me); |
---|
1394 | 1514 | goto logical_done; |
---|
1395 | 1515 | |
---|
1396 | 1516 | case 24: /* ori */ |
---|
1397 | | - op->val = regs->gpr[rd] | (unsigned short) instr; |
---|
| 1517 | + op->val = regs->gpr[rd] | (unsigned short) word; |
---|
1398 | 1518 | goto logical_done_nocc; |
---|
1399 | 1519 | |
---|
1400 | 1520 | case 25: /* oris */ |
---|
1401 | | - imm = (unsigned short) instr; |
---|
| 1521 | + imm = (unsigned short) word; |
---|
1402 | 1522 | op->val = regs->gpr[rd] | (imm << 16); |
---|
1403 | 1523 | goto logical_done_nocc; |
---|
1404 | 1524 | |
---|
1405 | 1525 | case 26: /* xori */ |
---|
1406 | | - op->val = regs->gpr[rd] ^ (unsigned short) instr; |
---|
| 1526 | + op->val = regs->gpr[rd] ^ (unsigned short) word; |
---|
1407 | 1527 | goto logical_done_nocc; |
---|
1408 | 1528 | |
---|
1409 | 1529 | case 27: /* xoris */ |
---|
1410 | | - imm = (unsigned short) instr; |
---|
| 1530 | + imm = (unsigned short) word; |
---|
1411 | 1531 | op->val = regs->gpr[rd] ^ (imm << 16); |
---|
1412 | 1532 | goto logical_done_nocc; |
---|
1413 | 1533 | |
---|
1414 | 1534 | case 28: /* andi. */ |
---|
1415 | | - op->val = regs->gpr[rd] & (unsigned short) instr; |
---|
| 1535 | + op->val = regs->gpr[rd] & (unsigned short) word; |
---|
1416 | 1536 | set_cr0(regs, op); |
---|
1417 | 1537 | goto logical_done_nocc; |
---|
1418 | 1538 | |
---|
1419 | 1539 | case 29: /* andis. */ |
---|
1420 | | - imm = (unsigned short) instr; |
---|
| 1540 | + imm = (unsigned short) word; |
---|
1421 | 1541 | op->val = regs->gpr[rd] & (imm << 16); |
---|
1422 | 1542 | set_cr0(regs, op); |
---|
1423 | 1543 | goto logical_done_nocc; |
---|
1424 | 1544 | |
---|
1425 | 1545 | #ifdef __powerpc64__ |
---|
1426 | 1546 | case 30: /* rld* */ |
---|
1427 | | - mb = ((instr >> 6) & 0x1f) | (instr & 0x20); |
---|
| 1547 | + mb = ((word >> 6) & 0x1f) | (word & 0x20); |
---|
1428 | 1548 | val = regs->gpr[rd]; |
---|
1429 | | - if ((instr & 0x10) == 0) { |
---|
1430 | | - sh = rb | ((instr & 2) << 4); |
---|
| 1549 | + if ((word & 0x10) == 0) { |
---|
| 1550 | + sh = rb | ((word & 2) << 4); |
---|
1431 | 1551 | val = ROTATE(val, sh); |
---|
1432 | | - switch ((instr >> 2) & 3) { |
---|
| 1552 | + switch ((word >> 2) & 3) { |
---|
1433 | 1553 | case 0: /* rldicl */ |
---|
1434 | 1554 | val &= MASK64_L(mb); |
---|
1435 | 1555 | break; |
---|
.. | .. |
---|
1449 | 1569 | } else { |
---|
1450 | 1570 | sh = regs->gpr[rb] & 0x3f; |
---|
1451 | 1571 | val = ROTATE(val, sh); |
---|
1452 | | - switch ((instr >> 1) & 7) { |
---|
| 1572 | + switch ((word >> 1) & 7) { |
---|
1453 | 1573 | case 0: /* rldcl */ |
---|
1454 | 1574 | op->val = val & MASK64_L(mb); |
---|
1455 | 1575 | goto logical_done; |
---|
.. | .. |
---|
1464 | 1584 | |
---|
1465 | 1585 | case 31: |
---|
1466 | 1586 | /* isel occupies 32 minor opcodes */ |
---|
1467 | | - if (((instr >> 1) & 0x1f) == 15) { |
---|
1468 | | - mb = (instr >> 6) & 0x1f; /* bc field */ |
---|
| 1587 | + if (((word >> 1) & 0x1f) == 15) { |
---|
| 1588 | + mb = (word >> 6) & 0x1f; /* bc field */ |
---|
1469 | 1589 | val = (regs->ccr >> (31 - mb)) & 1; |
---|
1470 | 1590 | val2 = (ra) ? regs->gpr[ra] : 0; |
---|
1471 | 1591 | |
---|
.. | .. |
---|
1473 | 1593 | goto compute_done; |
---|
1474 | 1594 | } |
---|
1475 | 1595 | |
---|
1476 | | - switch ((instr >> 1) & 0x3ff) { |
---|
| 1596 | + switch ((word >> 1) & 0x3ff) { |
---|
1477 | 1597 | case 4: /* tw */ |
---|
1478 | 1598 | if (rd == 0x1f || |
---|
1479 | 1599 | (rd & trap_compare((int)regs->gpr[ra], |
---|
.. | .. |
---|
1507 | 1627 | op->reg = rd; |
---|
1508 | 1628 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ |
---|
1509 | 1629 | /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */ |
---|
1510 | | - imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL; |
---|
| 1630 | + imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL; |
---|
1511 | 1631 | op->val = imm; |
---|
1512 | 1632 | return 0; |
---|
1513 | 1633 | #endif |
---|
1514 | 1634 | |
---|
1515 | 1635 | case 19: /* mfcr */ |
---|
1516 | 1636 | imm = 0xffffffffUL; |
---|
1517 | | - if ((instr >> 20) & 1) { |
---|
| 1637 | + if ((word >> 20) & 1) { |
---|
1518 | 1638 | imm = 0xf0000000UL; |
---|
1519 | 1639 | for (sh = 0; sh < 8; ++sh) { |
---|
1520 | | - if (instr & (0x80000 >> sh)) |
---|
| 1640 | + if (word & (0x80000 >> sh)) |
---|
1521 | 1641 | break; |
---|
1522 | 1642 | imm >>= 4; |
---|
1523 | 1643 | } |
---|
.. | .. |
---|
1531 | 1651 | val = regs->gpr[rd]; |
---|
1532 | 1652 | op->ccval = regs->ccr; |
---|
1533 | 1653 | for (sh = 0; sh < 8; ++sh) { |
---|
1534 | | - if (instr & (0x80000 >> sh)) |
---|
| 1654 | + if (word & (0x80000 >> sh)) |
---|
1535 | 1655 | op->ccval = (op->ccval & ~imm) | |
---|
1536 | 1656 | (val & imm); |
---|
1537 | 1657 | imm >>= 4; |
---|
.. | .. |
---|
1539 | 1659 | return 1; |
---|
1540 | 1660 | |
---|
1541 | 1661 | case 339: /* mfspr */ |
---|
1542 | | - spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); |
---|
| 1662 | + spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0); |
---|
1543 | 1663 | op->type = MFSPR; |
---|
1544 | 1664 | op->reg = rd; |
---|
1545 | 1665 | op->spr = spr; |
---|
.. | .. |
---|
1549 | 1669 | return 0; |
---|
1550 | 1670 | |
---|
1551 | 1671 | case 467: /* mtspr */ |
---|
1552 | | - spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); |
---|
| 1672 | + spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0); |
---|
1553 | 1673 | op->type = MTSPR; |
---|
1554 | 1674 | op->val = regs->gpr[rd]; |
---|
1555 | 1675 | op->spr = spr; |
---|
.. | .. |
---|
1671 | 1791 | (int) regs->gpr[rb]; |
---|
1672 | 1792 | |
---|
1673 | 1793 | goto arith_done; |
---|
1674 | | - |
---|
| 1794 | +#ifdef __powerpc64__ |
---|
| 1795 | + case 265: /* modud */ |
---|
| 1796 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1797 | + goto unknown_opcode; |
---|
| 1798 | + op->val = regs->gpr[ra] % regs->gpr[rb]; |
---|
| 1799 | + goto compute_done; |
---|
| 1800 | +#endif |
---|
1675 | 1801 | case 266: /* add */ |
---|
1676 | 1802 | op->val = regs->gpr[ra] + regs->gpr[rb]; |
---|
1677 | 1803 | goto arith_done; |
---|
| 1804 | + |
---|
| 1805 | + case 267: /* moduw */ |
---|
| 1806 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1807 | + goto unknown_opcode; |
---|
| 1808 | + op->val = (unsigned int) regs->gpr[ra] % |
---|
| 1809 | + (unsigned int) regs->gpr[rb]; |
---|
| 1810 | + goto compute_done; |
---|
1678 | 1811 | #ifdef __powerpc64__ |
---|
1679 | 1812 | case 457: /* divdu */ |
---|
1680 | 1813 | op->val = regs->gpr[ra] / regs->gpr[rb]; |
---|
.. | .. |
---|
1694 | 1827 | op->val = (int) regs->gpr[ra] / |
---|
1695 | 1828 | (int) regs->gpr[rb]; |
---|
1696 | 1829 | goto arith_done; |
---|
| 1830 | +#ifdef __powerpc64__ |
---|
| 1831 | + case 425: /* divde[.] */ |
---|
| 1832 | + asm volatile(PPC_DIVDE(%0, %1, %2) : |
---|
| 1833 | + "=r" (op->val) : "r" (regs->gpr[ra]), |
---|
| 1834 | + "r" (regs->gpr[rb])); |
---|
| 1835 | + goto arith_done; |
---|
| 1836 | + case 393: /* divdeu[.] */ |
---|
| 1837 | + asm volatile(PPC_DIVDEU(%0, %1, %2) : |
---|
| 1838 | + "=r" (op->val) : "r" (regs->gpr[ra]), |
---|
| 1839 | + "r" (regs->gpr[rb])); |
---|
| 1840 | + goto arith_done; |
---|
| 1841 | +#endif |
---|
| 1842 | + case 755: /* darn */ |
---|
| 1843 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1844 | + goto unknown_opcode; |
---|
| 1845 | + switch (ra & 0x3) { |
---|
| 1846 | + case 0: |
---|
| 1847 | + /* 32-bit conditioned */ |
---|
| 1848 | + asm volatile(PPC_DARN(%0, 0) : "=r" (op->val)); |
---|
| 1849 | + goto compute_done; |
---|
| 1850 | + |
---|
| 1851 | + case 1: |
---|
| 1852 | + /* 64-bit conditioned */ |
---|
| 1853 | + asm volatile(PPC_DARN(%0, 1) : "=r" (op->val)); |
---|
| 1854 | + goto compute_done; |
---|
| 1855 | + |
---|
| 1856 | + case 2: |
---|
| 1857 | + /* 64-bit raw */ |
---|
| 1858 | + asm volatile(PPC_DARN(%0, 2) : "=r" (op->val)); |
---|
| 1859 | + goto compute_done; |
---|
| 1860 | + } |
---|
| 1861 | + |
---|
| 1862 | + goto unknown_opcode; |
---|
| 1863 | +#ifdef __powerpc64__ |
---|
| 1864 | + case 777: /* modsd */ |
---|
| 1865 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1866 | + goto unknown_opcode; |
---|
| 1867 | + op->val = (long int) regs->gpr[ra] % |
---|
| 1868 | + (long int) regs->gpr[rb]; |
---|
| 1869 | + goto compute_done; |
---|
| 1870 | +#endif |
---|
| 1871 | + case 779: /* modsw */ |
---|
| 1872 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1873 | + goto unknown_opcode; |
---|
| 1874 | + op->val = (int) regs->gpr[ra] % |
---|
| 1875 | + (int) regs->gpr[rb]; |
---|
| 1876 | + goto compute_done; |
---|
1697 | 1877 | |
---|
1698 | 1878 | |
---|
1699 | 1879 | /* |
---|
.. | .. |
---|
1764 | 1944 | case 506: /* popcntd */ |
---|
1765 | 1945 | do_popcnt(regs, op, regs->gpr[rd], 64); |
---|
1766 | 1946 | goto logical_done_nocc; |
---|
| 1947 | +#endif |
---|
| 1948 | + case 538: /* cnttzw */ |
---|
| 1949 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1950 | + goto unknown_opcode; |
---|
| 1951 | + val = (unsigned int) regs->gpr[rd]; |
---|
| 1952 | + op->val = (val ? __builtin_ctz(val) : 32); |
---|
| 1953 | + goto logical_done; |
---|
| 1954 | +#ifdef __powerpc64__ |
---|
| 1955 | + case 570: /* cnttzd */ |
---|
| 1956 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 1957 | + goto unknown_opcode; |
---|
| 1958 | + val = regs->gpr[rd]; |
---|
| 1959 | + op->val = (val ? __builtin_ctzl(val) : 64); |
---|
| 1960 | + goto logical_done; |
---|
1767 | 1961 | #endif |
---|
1768 | 1962 | case 922: /* extsh */ |
---|
1769 | 1963 | op->val = (signed short) regs->gpr[rd]; |
---|
.. | .. |
---|
1856 | 2050 | case 826: /* sradi with sh_5 = 0 */ |
---|
1857 | 2051 | case 827: /* sradi with sh_5 = 1 */ |
---|
1858 | 2052 | op->type = COMPUTE + SETREG + SETXER; |
---|
1859 | | - sh = rb | ((instr & 2) << 4); |
---|
| 2053 | + sh = rb | ((word & 2) << 4); |
---|
1860 | 2054 | ival = (signed long int) regs->gpr[rd]; |
---|
1861 | 2055 | op->val = ival >> sh; |
---|
1862 | 2056 | op->xerval = regs->xer; |
---|
.. | .. |
---|
1866 | 2060 | op->xerval &= ~XER_CA; |
---|
1867 | 2061 | set_ca32(op, op->xerval & XER_CA); |
---|
1868 | 2062 | goto logical_done; |
---|
| 2063 | + |
---|
| 2064 | + case 890: /* extswsli with sh_5 = 0 */ |
---|
| 2065 | + case 891: /* extswsli with sh_5 = 1 */ |
---|
| 2066 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2067 | + goto unknown_opcode; |
---|
| 2068 | + op->type = COMPUTE + SETREG; |
---|
| 2069 | + sh = rb | ((word & 2) << 4); |
---|
| 2070 | + val = (signed int) regs->gpr[rd]; |
---|
| 2071 | + if (sh) |
---|
| 2072 | + op->val = ROTATE(val, sh) & MASK64(0, 63 - sh); |
---|
| 2073 | + else |
---|
| 2074 | + op->val = val; |
---|
| 2075 | + goto logical_done; |
---|
| 2076 | + |
---|
1869 | 2077 | #endif /* __powerpc64__ */ |
---|
1870 | 2078 | |
---|
1871 | 2079 | /* |
---|
.. | .. |
---|
1873 | 2081 | */ |
---|
1874 | 2082 | case 54: /* dcbst */ |
---|
1875 | 2083 | op->type = MKOP(CACHEOP, DCBST, 0); |
---|
1876 | | - op->ea = xform_ea(instr, regs); |
---|
| 2084 | + op->ea = xform_ea(word, regs); |
---|
1877 | 2085 | return 0; |
---|
1878 | 2086 | |
---|
1879 | 2087 | case 86: /* dcbf */ |
---|
1880 | 2088 | op->type = MKOP(CACHEOP, DCBF, 0); |
---|
1881 | | - op->ea = xform_ea(instr, regs); |
---|
| 2089 | + op->ea = xform_ea(word, regs); |
---|
1882 | 2090 | return 0; |
---|
1883 | 2091 | |
---|
1884 | 2092 | case 246: /* dcbtst */ |
---|
1885 | 2093 | op->type = MKOP(CACHEOP, DCBTST, 0); |
---|
1886 | | - op->ea = xform_ea(instr, regs); |
---|
| 2094 | + op->ea = xform_ea(word, regs); |
---|
1887 | 2095 | op->reg = rd; |
---|
1888 | 2096 | return 0; |
---|
1889 | 2097 | |
---|
1890 | 2098 | case 278: /* dcbt */ |
---|
1891 | 2099 | op->type = MKOP(CACHEOP, DCBTST, 0); |
---|
1892 | | - op->ea = xform_ea(instr, regs); |
---|
| 2100 | + op->ea = xform_ea(word, regs); |
---|
1893 | 2101 | op->reg = rd; |
---|
1894 | 2102 | return 0; |
---|
1895 | 2103 | |
---|
1896 | 2104 | case 982: /* icbi */ |
---|
1897 | 2105 | op->type = MKOP(CACHEOP, ICBI, 0); |
---|
1898 | | - op->ea = xform_ea(instr, regs); |
---|
| 2106 | + op->ea = xform_ea(word, regs); |
---|
1899 | 2107 | return 0; |
---|
1900 | 2108 | |
---|
1901 | 2109 | case 1014: /* dcbz */ |
---|
1902 | 2110 | op->type = MKOP(CACHEOP, DCBZ, 0); |
---|
1903 | | - op->ea = xform_ea(instr, regs); |
---|
| 2111 | + op->ea = xform_ea(word, regs); |
---|
1904 | 2112 | return 0; |
---|
1905 | 2113 | } |
---|
1906 | 2114 | break; |
---|
.. | .. |
---|
1913 | 2121 | op->update_reg = ra; |
---|
1914 | 2122 | op->reg = rd; |
---|
1915 | 2123 | op->val = regs->gpr[rd]; |
---|
1916 | | - u = (instr >> 20) & UPDATE; |
---|
| 2124 | + u = (word >> 20) & UPDATE; |
---|
1917 | 2125 | op->vsx_flags = 0; |
---|
1918 | 2126 | |
---|
1919 | 2127 | switch (opcode) { |
---|
1920 | 2128 | case 31: |
---|
1921 | | - u = instr & UPDATE; |
---|
1922 | | - op->ea = xform_ea(instr, regs); |
---|
1923 | | - switch ((instr >> 1) & 0x3ff) { |
---|
| 2129 | + u = word & UPDATE; |
---|
| 2130 | + op->ea = xform_ea(word, regs); |
---|
| 2131 | + switch ((word >> 1) & 0x3ff) { |
---|
1924 | 2132 | case 20: /* lwarx */ |
---|
1925 | 2133 | op->type = MKOP(LARX, 0, 4); |
---|
1926 | 2134 | break; |
---|
.. | .. |
---|
2165 | 2373 | |
---|
2166 | 2374 | #ifdef CONFIG_VSX |
---|
2167 | 2375 | case 12: /* lxsiwzx */ |
---|
2168 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2376 | + op->reg = rd | ((word & 1) << 5); |
---|
2169 | 2377 | op->type = MKOP(LOAD_VSX, 0, 4); |
---|
2170 | 2378 | op->element_size = 8; |
---|
2171 | 2379 | break; |
---|
2172 | 2380 | |
---|
2173 | 2381 | case 76: /* lxsiwax */ |
---|
2174 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2382 | + op->reg = rd | ((word & 1) << 5); |
---|
2175 | 2383 | op->type = MKOP(LOAD_VSX, SIGNEXT, 4); |
---|
2176 | 2384 | op->element_size = 8; |
---|
2177 | 2385 | break; |
---|
2178 | 2386 | |
---|
2179 | 2387 | case 140: /* stxsiwx */ |
---|
2180 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2388 | + op->reg = rd | ((word & 1) << 5); |
---|
2181 | 2389 | op->type = MKOP(STORE_VSX, 0, 4); |
---|
2182 | 2390 | op->element_size = 8; |
---|
2183 | 2391 | break; |
---|
2184 | 2392 | |
---|
2185 | 2393 | case 268: /* lxvx */ |
---|
2186 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2394 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2395 | + goto unknown_opcode; |
---|
| 2396 | + op->reg = rd | ((word & 1) << 5); |
---|
2187 | 2397 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2188 | 2398 | op->element_size = 16; |
---|
2189 | 2399 | op->vsx_flags = VSX_CHECK_VEC; |
---|
.. | .. |
---|
2192 | 2402 | case 269: /* lxvl */ |
---|
2193 | 2403 | case 301: { /* lxvll */ |
---|
2194 | 2404 | int nb; |
---|
2195 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2405 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2406 | + goto unknown_opcode; |
---|
| 2407 | + op->reg = rd | ((word & 1) << 5); |
---|
2196 | 2408 | op->ea = ra ? regs->gpr[ra] : 0; |
---|
2197 | 2409 | nb = regs->gpr[rb] & 0xff; |
---|
2198 | 2410 | if (nb > 16) |
---|
2199 | 2411 | nb = 16; |
---|
2200 | 2412 | op->type = MKOP(LOAD_VSX, 0, nb); |
---|
2201 | 2413 | op->element_size = 16; |
---|
2202 | | - op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | |
---|
| 2414 | + op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) | |
---|
2203 | 2415 | VSX_CHECK_VEC; |
---|
2204 | 2416 | break; |
---|
2205 | 2417 | } |
---|
2206 | 2418 | case 332: /* lxvdsx */ |
---|
2207 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2419 | + op->reg = rd | ((word & 1) << 5); |
---|
2208 | 2420 | op->type = MKOP(LOAD_VSX, 0, 8); |
---|
2209 | 2421 | op->element_size = 8; |
---|
2210 | 2422 | op->vsx_flags = VSX_SPLAT; |
---|
2211 | 2423 | break; |
---|
2212 | 2424 | |
---|
2213 | 2425 | case 364: /* lxvwsx */ |
---|
2214 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2426 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2427 | + goto unknown_opcode; |
---|
| 2428 | + op->reg = rd | ((word & 1) << 5); |
---|
2215 | 2429 | op->type = MKOP(LOAD_VSX, 0, 4); |
---|
2216 | 2430 | op->element_size = 4; |
---|
2217 | 2431 | op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC; |
---|
2218 | 2432 | break; |
---|
2219 | 2433 | |
---|
2220 | 2434 | case 396: /* stxvx */ |
---|
2221 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2435 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2436 | + goto unknown_opcode; |
---|
| 2437 | + op->reg = rd | ((word & 1) << 5); |
---|
2222 | 2438 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2223 | 2439 | op->element_size = 16; |
---|
2224 | 2440 | op->vsx_flags = VSX_CHECK_VEC; |
---|
.. | .. |
---|
2227 | 2443 | case 397: /* stxvl */ |
---|
2228 | 2444 | case 429: { /* stxvll */ |
---|
2229 | 2445 | int nb; |
---|
2230 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2446 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2447 | + goto unknown_opcode; |
---|
| 2448 | + op->reg = rd | ((word & 1) << 5); |
---|
2231 | 2449 | op->ea = ra ? regs->gpr[ra] : 0; |
---|
2232 | 2450 | nb = regs->gpr[rb] & 0xff; |
---|
2233 | 2451 | if (nb > 16) |
---|
2234 | 2452 | nb = 16; |
---|
2235 | 2453 | op->type = MKOP(STORE_VSX, 0, nb); |
---|
2236 | 2454 | op->element_size = 16; |
---|
2237 | | - op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | |
---|
| 2455 | + op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) | |
---|
2238 | 2456 | VSX_CHECK_VEC; |
---|
2239 | 2457 | break; |
---|
2240 | 2458 | } |
---|
2241 | 2459 | case 524: /* lxsspx */ |
---|
2242 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2460 | + op->reg = rd | ((word & 1) << 5); |
---|
2243 | 2461 | op->type = MKOP(LOAD_VSX, 0, 4); |
---|
2244 | 2462 | op->element_size = 8; |
---|
2245 | 2463 | op->vsx_flags = VSX_FPCONV; |
---|
2246 | 2464 | break; |
---|
2247 | 2465 | |
---|
2248 | 2466 | case 588: /* lxsdx */ |
---|
2249 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2467 | + op->reg = rd | ((word & 1) << 5); |
---|
2250 | 2468 | op->type = MKOP(LOAD_VSX, 0, 8); |
---|
2251 | 2469 | op->element_size = 8; |
---|
2252 | 2470 | break; |
---|
2253 | 2471 | |
---|
2254 | 2472 | case 652: /* stxsspx */ |
---|
2255 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2473 | + op->reg = rd | ((word & 1) << 5); |
---|
2256 | 2474 | op->type = MKOP(STORE_VSX, 0, 4); |
---|
2257 | 2475 | op->element_size = 8; |
---|
2258 | 2476 | op->vsx_flags = VSX_FPCONV; |
---|
2259 | 2477 | break; |
---|
2260 | 2478 | |
---|
2261 | 2479 | case 716: /* stxsdx */ |
---|
2262 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2480 | + op->reg = rd | ((word & 1) << 5); |
---|
2263 | 2481 | op->type = MKOP(STORE_VSX, 0, 8); |
---|
2264 | 2482 | op->element_size = 8; |
---|
2265 | 2483 | break; |
---|
2266 | 2484 | |
---|
2267 | 2485 | case 780: /* lxvw4x */ |
---|
2268 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2486 | + op->reg = rd | ((word & 1) << 5); |
---|
2269 | 2487 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2270 | 2488 | op->element_size = 4; |
---|
2271 | 2489 | break; |
---|
2272 | 2490 | |
---|
2273 | 2491 | case 781: /* lxsibzx */ |
---|
2274 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2492 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2493 | + goto unknown_opcode; |
---|
| 2494 | + op->reg = rd | ((word & 1) << 5); |
---|
2275 | 2495 | op->type = MKOP(LOAD_VSX, 0, 1); |
---|
2276 | 2496 | op->element_size = 8; |
---|
2277 | 2497 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2278 | 2498 | break; |
---|
2279 | 2499 | |
---|
2280 | 2500 | case 812: /* lxvh8x */ |
---|
2281 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2501 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2502 | + goto unknown_opcode; |
---|
| 2503 | + op->reg = rd | ((word & 1) << 5); |
---|
2282 | 2504 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2283 | 2505 | op->element_size = 2; |
---|
2284 | 2506 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2285 | 2507 | break; |
---|
2286 | 2508 | |
---|
2287 | 2509 | case 813: /* lxsihzx */ |
---|
2288 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2510 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2511 | + goto unknown_opcode; |
---|
| 2512 | + op->reg = rd | ((word & 1) << 5); |
---|
2289 | 2513 | op->type = MKOP(LOAD_VSX, 0, 2); |
---|
2290 | 2514 | op->element_size = 8; |
---|
2291 | 2515 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2292 | 2516 | break; |
---|
2293 | 2517 | |
---|
2294 | 2518 | case 844: /* lxvd2x */ |
---|
2295 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2519 | + op->reg = rd | ((word & 1) << 5); |
---|
2296 | 2520 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2297 | 2521 | op->element_size = 8; |
---|
2298 | 2522 | break; |
---|
2299 | 2523 | |
---|
2300 | 2524 | case 876: /* lxvb16x */ |
---|
2301 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2525 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2526 | + goto unknown_opcode; |
---|
| 2527 | + op->reg = rd | ((word & 1) << 5); |
---|
2302 | 2528 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2303 | 2529 | op->element_size = 1; |
---|
2304 | 2530 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2305 | 2531 | break; |
---|
2306 | 2532 | |
---|
2307 | 2533 | case 908: /* stxvw4x */ |
---|
2308 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2534 | + op->reg = rd | ((word & 1) << 5); |
---|
2309 | 2535 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2310 | 2536 | op->element_size = 4; |
---|
2311 | 2537 | break; |
---|
2312 | 2538 | |
---|
2313 | 2539 | case 909: /* stxsibx */ |
---|
2314 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2540 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2541 | + goto unknown_opcode; |
---|
| 2542 | + op->reg = rd | ((word & 1) << 5); |
---|
2315 | 2543 | op->type = MKOP(STORE_VSX, 0, 1); |
---|
2316 | 2544 | op->element_size = 8; |
---|
2317 | 2545 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2318 | 2546 | break; |
---|
2319 | 2547 | |
---|
2320 | 2548 | case 940: /* stxvh8x */ |
---|
2321 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2549 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2550 | + goto unknown_opcode; |
---|
| 2551 | + op->reg = rd | ((word & 1) << 5); |
---|
2322 | 2552 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2323 | 2553 | op->element_size = 2; |
---|
2324 | 2554 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2325 | 2555 | break; |
---|
2326 | 2556 | |
---|
2327 | 2557 | case 941: /* stxsihx */ |
---|
2328 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2558 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2559 | + goto unknown_opcode; |
---|
| 2560 | + op->reg = rd | ((word & 1) << 5); |
---|
2329 | 2561 | op->type = MKOP(STORE_VSX, 0, 2); |
---|
2330 | 2562 | op->element_size = 8; |
---|
2331 | 2563 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2332 | 2564 | break; |
---|
2333 | 2565 | |
---|
2334 | 2566 | case 972: /* stxvd2x */ |
---|
2335 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2567 | + op->reg = rd | ((word & 1) << 5); |
---|
2336 | 2568 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2337 | 2569 | op->element_size = 8; |
---|
2338 | 2570 | break; |
---|
2339 | 2571 | |
---|
2340 | 2572 | case 1004: /* stxvb16x */ |
---|
2341 | | - op->reg = rd | ((instr & 1) << 5); |
---|
| 2573 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2574 | + goto unknown_opcode; |
---|
| 2575 | + op->reg = rd | ((word & 1) << 5); |
---|
2342 | 2576 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2343 | 2577 | op->element_size = 1; |
---|
2344 | 2578 | op->vsx_flags = VSX_CHECK_VEC; |
---|
.. | .. |
---|
2351 | 2585 | case 32: /* lwz */ |
---|
2352 | 2586 | case 33: /* lwzu */ |
---|
2353 | 2587 | op->type = MKOP(LOAD, u, 4); |
---|
2354 | | - op->ea = dform_ea(instr, regs); |
---|
| 2588 | + op->ea = dform_ea(word, regs); |
---|
2355 | 2589 | break; |
---|
2356 | 2590 | |
---|
2357 | 2591 | case 34: /* lbz */ |
---|
2358 | 2592 | case 35: /* lbzu */ |
---|
2359 | 2593 | op->type = MKOP(LOAD, u, 1); |
---|
2360 | | - op->ea = dform_ea(instr, regs); |
---|
| 2594 | + op->ea = dform_ea(word, regs); |
---|
2361 | 2595 | break; |
---|
2362 | 2596 | |
---|
2363 | 2597 | case 36: /* stw */ |
---|
2364 | 2598 | case 37: /* stwu */ |
---|
2365 | 2599 | op->type = MKOP(STORE, u, 4); |
---|
2366 | | - op->ea = dform_ea(instr, regs); |
---|
| 2600 | + op->ea = dform_ea(word, regs); |
---|
2367 | 2601 | break; |
---|
2368 | 2602 | |
---|
2369 | 2603 | case 38: /* stb */ |
---|
2370 | 2604 | case 39: /* stbu */ |
---|
2371 | 2605 | op->type = MKOP(STORE, u, 1); |
---|
2372 | | - op->ea = dform_ea(instr, regs); |
---|
| 2606 | + op->ea = dform_ea(word, regs); |
---|
2373 | 2607 | break; |
---|
2374 | 2608 | |
---|
2375 | 2609 | case 40: /* lhz */ |
---|
2376 | 2610 | case 41: /* lhzu */ |
---|
2377 | 2611 | op->type = MKOP(LOAD, u, 2); |
---|
2378 | | - op->ea = dform_ea(instr, regs); |
---|
| 2612 | + op->ea = dform_ea(word, regs); |
---|
2379 | 2613 | break; |
---|
2380 | 2614 | |
---|
2381 | 2615 | case 42: /* lha */ |
---|
2382 | 2616 | case 43: /* lhau */ |
---|
2383 | 2617 | op->type = MKOP(LOAD, SIGNEXT | u, 2); |
---|
2384 | | - op->ea = dform_ea(instr, regs); |
---|
| 2618 | + op->ea = dform_ea(word, regs); |
---|
2385 | 2619 | break; |
---|
2386 | 2620 | |
---|
2387 | 2621 | case 44: /* sth */ |
---|
2388 | 2622 | case 45: /* sthu */ |
---|
2389 | 2623 | op->type = MKOP(STORE, u, 2); |
---|
2390 | | - op->ea = dform_ea(instr, regs); |
---|
| 2624 | + op->ea = dform_ea(word, regs); |
---|
2391 | 2625 | break; |
---|
2392 | 2626 | |
---|
2393 | 2627 | case 46: /* lmw */ |
---|
2394 | 2628 | if (ra >= rd) |
---|
2395 | 2629 | break; /* invalid form, ra in range to load */ |
---|
2396 | 2630 | op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd)); |
---|
2397 | | - op->ea = dform_ea(instr, regs); |
---|
| 2631 | + op->ea = dform_ea(word, regs); |
---|
2398 | 2632 | break; |
---|
2399 | 2633 | |
---|
2400 | 2634 | case 47: /* stmw */ |
---|
2401 | 2635 | op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd)); |
---|
2402 | | - op->ea = dform_ea(instr, regs); |
---|
| 2636 | + op->ea = dform_ea(word, regs); |
---|
2403 | 2637 | break; |
---|
2404 | 2638 | |
---|
2405 | 2639 | #ifdef CONFIG_PPC_FPU |
---|
2406 | 2640 | case 48: /* lfs */ |
---|
2407 | 2641 | case 49: /* lfsu */ |
---|
2408 | 2642 | op->type = MKOP(LOAD_FP, u | FPCONV, 4); |
---|
2409 | | - op->ea = dform_ea(instr, regs); |
---|
| 2643 | + op->ea = dform_ea(word, regs); |
---|
2410 | 2644 | break; |
---|
2411 | 2645 | |
---|
2412 | 2646 | case 50: /* lfd */ |
---|
2413 | 2647 | case 51: /* lfdu */ |
---|
2414 | 2648 | op->type = MKOP(LOAD_FP, u, 8); |
---|
2415 | | - op->ea = dform_ea(instr, regs); |
---|
| 2649 | + op->ea = dform_ea(word, regs); |
---|
2416 | 2650 | break; |
---|
2417 | 2651 | |
---|
2418 | 2652 | case 52: /* stfs */ |
---|
2419 | 2653 | case 53: /* stfsu */ |
---|
2420 | 2654 | op->type = MKOP(STORE_FP, u | FPCONV, 4); |
---|
2421 | | - op->ea = dform_ea(instr, regs); |
---|
| 2655 | + op->ea = dform_ea(word, regs); |
---|
2422 | 2656 | break; |
---|
2423 | 2657 | |
---|
2424 | 2658 | case 54: /* stfd */ |
---|
2425 | 2659 | case 55: /* stfdu */ |
---|
2426 | 2660 | op->type = MKOP(STORE_FP, u, 8); |
---|
2427 | | - op->ea = dform_ea(instr, regs); |
---|
| 2661 | + op->ea = dform_ea(word, regs); |
---|
2428 | 2662 | break; |
---|
2429 | 2663 | #endif |
---|
2430 | 2664 | |
---|
.. | .. |
---|
2432 | 2666 | case 56: /* lq */ |
---|
2433 | 2667 | if (!((rd & 1) || (rd == ra))) |
---|
2434 | 2668 | op->type = MKOP(LOAD, 0, 16); |
---|
2435 | | - op->ea = dqform_ea(instr, regs); |
---|
| 2669 | + op->ea = dqform_ea(word, regs); |
---|
2436 | 2670 | break; |
---|
2437 | 2671 | #endif |
---|
2438 | 2672 | |
---|
2439 | 2673 | #ifdef CONFIG_VSX |
---|
2440 | 2674 | case 57: /* lfdp, lxsd, lxssp */ |
---|
2441 | | - op->ea = dsform_ea(instr, regs); |
---|
2442 | | - switch (instr & 3) { |
---|
| 2675 | + op->ea = dsform_ea(word, regs); |
---|
| 2676 | + switch (word & 3) { |
---|
2443 | 2677 | case 0: /* lfdp */ |
---|
2444 | 2678 | if (rd & 1) |
---|
2445 | 2679 | break; /* reg must be even */ |
---|
2446 | 2680 | op->type = MKOP(LOAD_FP, 0, 16); |
---|
2447 | 2681 | break; |
---|
2448 | 2682 | case 2: /* lxsd */ |
---|
| 2683 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2684 | + goto unknown_opcode; |
---|
2449 | 2685 | op->reg = rd + 32; |
---|
2450 | 2686 | op->type = MKOP(LOAD_VSX, 0, 8); |
---|
2451 | 2687 | op->element_size = 8; |
---|
2452 | 2688 | op->vsx_flags = VSX_CHECK_VEC; |
---|
2453 | 2689 | break; |
---|
2454 | 2690 | case 3: /* lxssp */ |
---|
| 2691 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2692 | + goto unknown_opcode; |
---|
2455 | 2693 | op->reg = rd + 32; |
---|
2456 | 2694 | op->type = MKOP(LOAD_VSX, 0, 4); |
---|
2457 | 2695 | op->element_size = 8; |
---|
.. | .. |
---|
2463 | 2701 | |
---|
2464 | 2702 | #ifdef __powerpc64__ |
---|
2465 | 2703 | case 58: /* ld[u], lwa */ |
---|
2466 | | - op->ea = dsform_ea(instr, regs); |
---|
2467 | | - switch (instr & 3) { |
---|
| 2704 | + op->ea = dsform_ea(word, regs); |
---|
| 2705 | + switch (word & 3) { |
---|
2468 | 2706 | case 0: /* ld */ |
---|
2469 | 2707 | op->type = MKOP(LOAD, 0, 8); |
---|
2470 | 2708 | break; |
---|
.. | .. |
---|
2480 | 2718 | |
---|
2481 | 2719 | #ifdef CONFIG_VSX |
---|
2482 | 2720 | case 61: /* stfdp, lxv, stxsd, stxssp, stxv */ |
---|
2483 | | - switch (instr & 7) { |
---|
| 2721 | + switch (word & 7) { |
---|
2484 | 2722 | case 0: /* stfdp with LSB of DS field = 0 */ |
---|
2485 | 2723 | case 4: /* stfdp with LSB of DS field = 1 */ |
---|
2486 | | - op->ea = dsform_ea(instr, regs); |
---|
| 2724 | + op->ea = dsform_ea(word, regs); |
---|
2487 | 2725 | op->type = MKOP(STORE_FP, 0, 16); |
---|
2488 | 2726 | break; |
---|
2489 | 2727 | |
---|
2490 | 2728 | case 1: /* lxv */ |
---|
2491 | | - op->ea = dqform_ea(instr, regs); |
---|
2492 | | - if (instr & 8) |
---|
| 2729 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2730 | + goto unknown_opcode; |
---|
| 2731 | + op->ea = dqform_ea(word, regs); |
---|
| 2732 | + if (word & 8) |
---|
2493 | 2733 | op->reg = rd + 32; |
---|
2494 | 2734 | op->type = MKOP(LOAD_VSX, 0, 16); |
---|
2495 | 2735 | op->element_size = 16; |
---|
.. | .. |
---|
2498 | 2738 | |
---|
2499 | 2739 | case 2: /* stxsd with LSB of DS field = 0 */ |
---|
2500 | 2740 | case 6: /* stxsd with LSB of DS field = 1 */ |
---|
2501 | | - op->ea = dsform_ea(instr, regs); |
---|
| 2741 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2742 | + goto unknown_opcode; |
---|
| 2743 | + op->ea = dsform_ea(word, regs); |
---|
2502 | 2744 | op->reg = rd + 32; |
---|
2503 | 2745 | op->type = MKOP(STORE_VSX, 0, 8); |
---|
2504 | 2746 | op->element_size = 8; |
---|
.. | .. |
---|
2507 | 2749 | |
---|
2508 | 2750 | case 3: /* stxssp with LSB of DS field = 0 */ |
---|
2509 | 2751 | case 7: /* stxssp with LSB of DS field = 1 */ |
---|
2510 | | - op->ea = dsform_ea(instr, regs); |
---|
| 2752 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2753 | + goto unknown_opcode; |
---|
| 2754 | + op->ea = dsform_ea(word, regs); |
---|
2511 | 2755 | op->reg = rd + 32; |
---|
2512 | 2756 | op->type = MKOP(STORE_VSX, 0, 4); |
---|
2513 | 2757 | op->element_size = 8; |
---|
.. | .. |
---|
2515 | 2759 | break; |
---|
2516 | 2760 | |
---|
2517 | 2761 | case 5: /* stxv */ |
---|
2518 | | - op->ea = dqform_ea(instr, regs); |
---|
2519 | | - if (instr & 8) |
---|
| 2762 | + if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 2763 | + goto unknown_opcode; |
---|
| 2764 | + op->ea = dqform_ea(word, regs); |
---|
| 2765 | + if (word & 8) |
---|
2520 | 2766 | op->reg = rd + 32; |
---|
2521 | 2767 | op->type = MKOP(STORE_VSX, 0, 16); |
---|
2522 | 2768 | op->element_size = 16; |
---|
.. | .. |
---|
2528 | 2774 | |
---|
2529 | 2775 | #ifdef __powerpc64__ |
---|
2530 | 2776 | case 62: /* std[u] */ |
---|
2531 | | - op->ea = dsform_ea(instr, regs); |
---|
2532 | | - switch (instr & 3) { |
---|
| 2777 | + op->ea = dsform_ea(word, regs); |
---|
| 2778 | + switch (word & 3) { |
---|
2533 | 2779 | case 0: /* std */ |
---|
2534 | 2780 | op->type = MKOP(STORE, 0, 8); |
---|
2535 | 2781 | break; |
---|
.. | .. |
---|
2542 | 2788 | break; |
---|
2543 | 2789 | } |
---|
2544 | 2790 | break; |
---|
| 2791 | + case 1: /* Prefixed instructions */ |
---|
| 2792 | + if (!cpu_has_feature(CPU_FTR_ARCH_31)) |
---|
| 2793 | + goto unknown_opcode; |
---|
| 2794 | + |
---|
| 2795 | + prefix_r = GET_PREFIX_R(word); |
---|
| 2796 | + ra = GET_PREFIX_RA(suffix); |
---|
| 2797 | + op->update_reg = ra; |
---|
| 2798 | + rd = (suffix >> 21) & 0x1f; |
---|
| 2799 | + op->reg = rd; |
---|
| 2800 | + op->val = regs->gpr[rd]; |
---|
| 2801 | + |
---|
| 2802 | + suffixopcode = get_op(suffix); |
---|
| 2803 | + prefixtype = (word >> 24) & 0x3; |
---|
| 2804 | + switch (prefixtype) { |
---|
| 2805 | + case 0: /* Type 00 Eight-Byte Load/Store */ |
---|
| 2806 | + if (prefix_r && ra) |
---|
| 2807 | + break; |
---|
| 2808 | + op->ea = mlsd_8lsd_ea(word, suffix, regs); |
---|
| 2809 | + switch (suffixopcode) { |
---|
| 2810 | + case 41: /* plwa */ |
---|
| 2811 | + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4); |
---|
| 2812 | + break; |
---|
| 2813 | +#ifdef CONFIG_VSX |
---|
| 2814 | + case 42: /* plxsd */ |
---|
| 2815 | + op->reg = rd + 32; |
---|
| 2816 | + op->type = MKOP(LOAD_VSX, PREFIXED, 8); |
---|
| 2817 | + op->element_size = 8; |
---|
| 2818 | + op->vsx_flags = VSX_CHECK_VEC; |
---|
| 2819 | + break; |
---|
| 2820 | + case 43: /* plxssp */ |
---|
| 2821 | + op->reg = rd + 32; |
---|
| 2822 | + op->type = MKOP(LOAD_VSX, PREFIXED, 4); |
---|
| 2823 | + op->element_size = 8; |
---|
| 2824 | + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; |
---|
| 2825 | + break; |
---|
| 2826 | + case 46: /* pstxsd */ |
---|
| 2827 | + op->reg = rd + 32; |
---|
| 2828 | + op->type = MKOP(STORE_VSX, PREFIXED, 8); |
---|
| 2829 | + op->element_size = 8; |
---|
| 2830 | + op->vsx_flags = VSX_CHECK_VEC; |
---|
| 2831 | + break; |
---|
| 2832 | + case 47: /* pstxssp */ |
---|
| 2833 | + op->reg = rd + 32; |
---|
| 2834 | + op->type = MKOP(STORE_VSX, PREFIXED, 4); |
---|
| 2835 | + op->element_size = 8; |
---|
| 2836 | + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; |
---|
| 2837 | + break; |
---|
| 2838 | + case 51: /* plxv1 */ |
---|
| 2839 | + op->reg += 32; |
---|
| 2840 | + fallthrough; |
---|
| 2841 | + case 50: /* plxv0 */ |
---|
| 2842 | + op->type = MKOP(LOAD_VSX, PREFIXED, 16); |
---|
| 2843 | + op->element_size = 16; |
---|
| 2844 | + op->vsx_flags = VSX_CHECK_VEC; |
---|
| 2845 | + break; |
---|
| 2846 | + case 55: /* pstxv1 */ |
---|
| 2847 | + op->reg = rd + 32; |
---|
| 2848 | + fallthrough; |
---|
| 2849 | + case 54: /* pstxv0 */ |
---|
| 2850 | + op->type = MKOP(STORE_VSX, PREFIXED, 16); |
---|
| 2851 | + op->element_size = 16; |
---|
| 2852 | + op->vsx_flags = VSX_CHECK_VEC; |
---|
| 2853 | + break; |
---|
| 2854 | +#endif /* CONFIG_VSX */ |
---|
| 2855 | + case 56: /* plq */ |
---|
| 2856 | + op->type = MKOP(LOAD, PREFIXED, 16); |
---|
| 2857 | + break; |
---|
| 2858 | + case 57: /* pld */ |
---|
| 2859 | + op->type = MKOP(LOAD, PREFIXED, 8); |
---|
| 2860 | + break; |
---|
| 2861 | + case 60: /* pstq */ |
---|
| 2862 | + op->type = MKOP(STORE, PREFIXED, 16); |
---|
| 2863 | + break; |
---|
| 2864 | + case 61: /* pstd */ |
---|
| 2865 | + op->type = MKOP(STORE, PREFIXED, 8); |
---|
| 2866 | + break; |
---|
| 2867 | + } |
---|
| 2868 | + break; |
---|
| 2869 | + case 1: /* Type 01 Eight-Byte Register-to-Register */ |
---|
| 2870 | + break; |
---|
| 2871 | + case 2: /* Type 10 Modified Load/Store */ |
---|
| 2872 | + if (prefix_r && ra) |
---|
| 2873 | + break; |
---|
| 2874 | + op->ea = mlsd_8lsd_ea(word, suffix, regs); |
---|
| 2875 | + switch (suffixopcode) { |
---|
| 2876 | + case 32: /* plwz */ |
---|
| 2877 | + op->type = MKOP(LOAD, PREFIXED, 4); |
---|
| 2878 | + break; |
---|
| 2879 | + case 34: /* plbz */ |
---|
| 2880 | + op->type = MKOP(LOAD, PREFIXED, 1); |
---|
| 2881 | + break; |
---|
| 2882 | + case 36: /* pstw */ |
---|
| 2883 | + op->type = MKOP(STORE, PREFIXED, 4); |
---|
| 2884 | + break; |
---|
| 2885 | + case 38: /* pstb */ |
---|
| 2886 | + op->type = MKOP(STORE, PREFIXED, 1); |
---|
| 2887 | + break; |
---|
| 2888 | + case 40: /* plhz */ |
---|
| 2889 | + op->type = MKOP(LOAD, PREFIXED, 2); |
---|
| 2890 | + break; |
---|
| 2891 | + case 42: /* plha */ |
---|
| 2892 | + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2); |
---|
| 2893 | + break; |
---|
| 2894 | + case 44: /* psth */ |
---|
| 2895 | + op->type = MKOP(STORE, PREFIXED, 2); |
---|
| 2896 | + break; |
---|
| 2897 | + case 48: /* plfs */ |
---|
| 2898 | + op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4); |
---|
| 2899 | + break; |
---|
| 2900 | + case 50: /* plfd */ |
---|
| 2901 | + op->type = MKOP(LOAD_FP, PREFIXED, 8); |
---|
| 2902 | + break; |
---|
| 2903 | + case 52: /* pstfs */ |
---|
| 2904 | + op->type = MKOP(STORE_FP, PREFIXED | FPCONV, 4); |
---|
| 2905 | + break; |
---|
| 2906 | + case 54: /* pstfd */ |
---|
| 2907 | + op->type = MKOP(STORE_FP, PREFIXED, 8); |
---|
| 2908 | + break; |
---|
| 2909 | + } |
---|
| 2910 | + break; |
---|
| 2911 | + case 3: /* Type 11 Modified Register-to-Register */ |
---|
| 2912 | + break; |
---|
| 2913 | + } |
---|
2545 | 2914 | #endif /* __powerpc64__ */ |
---|
2546 | 2915 | |
---|
| 2916 | + } |
---|
| 2917 | + |
---|
| 2918 | + if (OP_IS_LOAD_STORE(op->type) && (op->type & UPDATE)) { |
---|
| 2919 | + switch (GETTYPE(op->type)) { |
---|
| 2920 | + case LOAD: |
---|
| 2921 | + if (ra == rd) |
---|
| 2922 | + goto unknown_opcode; |
---|
| 2923 | + fallthrough; |
---|
| 2924 | + case STORE: |
---|
| 2925 | + case LOAD_FP: |
---|
| 2926 | + case STORE_FP: |
---|
| 2927 | + if (ra == 0) |
---|
| 2928 | + goto unknown_opcode; |
---|
| 2929 | + } |
---|
2547 | 2930 | } |
---|
2548 | 2931 | |
---|
2549 | 2932 | #ifdef CONFIG_VSX |
---|
.. | .. |
---|
2556 | 2939 | |
---|
2557 | 2940 | return 0; |
---|
2558 | 2941 | |
---|
| 2942 | + unknown_opcode: |
---|
| 2943 | + op->type = UNKNOWN; |
---|
| 2944 | + return 0; |
---|
| 2945 | + |
---|
2559 | 2946 | logical_done: |
---|
2560 | | - if (instr & 1) |
---|
| 2947 | + if (word & 1) |
---|
2561 | 2948 | set_cr0(regs, op); |
---|
2562 | 2949 | logical_done_nocc: |
---|
2563 | 2950 | op->reg = ra; |
---|
.. | .. |
---|
2565 | 2952 | return 1; |
---|
2566 | 2953 | |
---|
2567 | 2954 | arith_done: |
---|
2568 | | - if (instr & 1) |
---|
| 2955 | + if (word & 1) |
---|
2569 | 2956 | set_cr0(regs, op); |
---|
2570 | 2957 | compute_done: |
---|
2571 | 2958 | op->reg = rd; |
---|
.. | .. |
---|
2650 | 3037 | { |
---|
2651 | 3038 | unsigned long next_pc; |
---|
2652 | 3039 | |
---|
2653 | | - next_pc = truncate_if_32bit(regs->msr, regs->nip + 4); |
---|
| 3040 | + next_pc = truncate_if_32bit(regs->msr, regs->nip + GETLENGTH(op->type)); |
---|
2654 | 3041 | switch (GETTYPE(op->type)) { |
---|
2655 | 3042 | case COMPUTE: |
---|
2656 | 3043 | if (op->type & SETREG) |
---|
.. | .. |
---|
2806 | 3193 | __put_user_asmx(op->val, ea, err, "stbcx.", cr); |
---|
2807 | 3194 | break; |
---|
2808 | 3195 | case 2: |
---|
2809 | | - __put_user_asmx(op->val, ea, err, "stbcx.", cr); |
---|
| 3196 | + __put_user_asmx(op->val, ea, err, "sthcx.", cr); |
---|
2810 | 3197 | break; |
---|
2811 | 3198 | #endif |
---|
2812 | 3199 | case 4: |
---|
.. | .. |
---|
2997 | 3384 | * or -1 if the instruction is one that should not be stepped, |
---|
2998 | 3385 | * such as an rfid, or a mtmsrd that would clear MSR_RI. |
---|
2999 | 3386 | */ |
---|
3000 | | -int emulate_step(struct pt_regs *regs, unsigned int instr) |
---|
| 3387 | +int emulate_step(struct pt_regs *regs, struct ppc_inst instr) |
---|
3001 | 3388 | { |
---|
3002 | 3389 | struct instruction_op op; |
---|
3003 | 3390 | int r, err, type; |
---|
.. | .. |
---|
3075 | 3462 | * entry code works. If that is changed, this will |
---|
3076 | 3463 | * need to be changed also. |
---|
3077 | 3464 | */ |
---|
3078 | | - if (regs->gpr[0] == 0x1ebe && |
---|
3079 | | - cpu_has_feature(CPU_FTR_REAL_LE)) { |
---|
| 3465 | + if (IS_ENABLED(CONFIG_PPC_FAST_ENDIAN_SWITCH) && |
---|
| 3466 | + cpu_has_feature(CPU_FTR_REAL_LE) && |
---|
| 3467 | + regs->gpr[0] == 0x1ebe) { |
---|
3080 | 3468 | regs->msr ^= MSR_LE; |
---|
3081 | 3469 | goto instr_done; |
---|
3082 | 3470 | } |
---|
.. | .. |
---|
3089 | 3477 | regs->msr = MSR_KERNEL; |
---|
3090 | 3478 | return 1; |
---|
3091 | 3479 | |
---|
| 3480 | +#ifdef CONFIG_PPC_BOOK3S_64 |
---|
| 3481 | + case SYSCALL_VECTORED_0: /* scv 0 */ |
---|
| 3482 | + regs->gpr[9] = regs->gpr[13]; |
---|
| 3483 | + regs->gpr[10] = MSR_KERNEL; |
---|
| 3484 | + regs->gpr[11] = regs->nip + 4; |
---|
| 3485 | + regs->gpr[12] = regs->msr & MSR_MASK; |
---|
| 3486 | + regs->gpr[13] = (unsigned long) get_paca(); |
---|
| 3487 | + regs->nip = (unsigned long) &system_call_vectored_emulate; |
---|
| 3488 | + regs->msr = MSR_KERNEL; |
---|
| 3489 | + return 1; |
---|
| 3490 | +#endif |
---|
| 3491 | + |
---|
3092 | 3492 | case RFI: |
---|
3093 | 3493 | return -1; |
---|
3094 | 3494 | #endif |
---|
.. | .. |
---|
3096 | 3496 | return 0; |
---|
3097 | 3497 | |
---|
3098 | 3498 | instr_done: |
---|
3099 | | - regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); |
---|
| 3499 | + regs->nip = truncate_if_32bit(regs->msr, regs->nip + GETLENGTH(op.type)); |
---|
3100 | 3500 | return 1; |
---|
3101 | 3501 | } |
---|
3102 | 3502 | NOKPROBE_SYMBOL(emulate_step); |
---|