unsigned char flags;
};
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RA(inst) (((inst) & 0x001F0000) >> 16)
-#define IS_DFORM(code) ((code) >= 32 && (code) <= 55)
+#define IS_XFORM(code) ((code) == 31)
#endif
#define INVALID { 0, 0 }
{ 4, ST+F+S }, /* 00 0 1010: stfs */
{ 8, ST+F }, /* 00 0 1011: stfd */
INVALID, /* 00 0 1100 */
- INVALID, /* 00 0 1101 */
+ INVALID, /* 00 0 1101: ld/ldu/lwa */
INVALID, /* 00 0 1110 */
- INVALID, /* 00 0 1111 */
+ INVALID, /* 00 0 1111: std/stdu */
{ 4, LD+U }, /* 00 1 0000: lwzu */
INVALID, /* 00 1 0001 */
{ 4, ST+U }, /* 00 1 0010: stwu */
INVALID, /* 00 1 1101 */
INVALID, /* 00 1 1110 */
INVALID, /* 00 1 1111 */
- INVALID, /* 01 0 0000 */
+ INVALID, /* 01 0 0000: ldx */
INVALID, /* 01 0 0001 */
- INVALID, /* 01 0 0010 */
+ INVALID, /* 01 0 0010: stdx */
INVALID, /* 01 0 0011 */
INVALID, /* 01 0 0100 */
- INVALID, /* 01 0 0101: lwax?? */
+ INVALID, /* 01 0 0101: lwax */
INVALID, /* 01 0 0110 */
INVALID, /* 01 0 0111 */
{ 0, LD+HARD }, /* 01 0 1000: lswx */
INVALID, /* 01 0 1101 */
INVALID, /* 01 0 1110 */
INVALID, /* 01 0 1111 */
- INVALID, /* 01 1 0000 */
+ INVALID, /* 01 1 0000: ldux */
INVALID, /* 01 1 0001 */
- INVALID, /* 01 1 0010 */
+ INVALID, /* 01 1 0010: stdux */
INVALID, /* 01 1 0011 */
INVALID, /* 01 1 0100 */
- INVALID, /* 01 1 0101: lwaux?? */
+ INVALID, /* 01 1 0101: lwaux */
INVALID, /* 01 1 0110 */
INVALID, /* 01 1 0111 */
INVALID, /* 01 1 1000 */
{ 4, ST+F+S }, /* 11 0 1010: stfsx */
{ 8, ST+F }, /* 11 0 1011: stfdx */
INVALID, /* 11 0 1100 */
- INVALID, /* 11 0 1101 */
+ INVALID, /* 11 0 1101: lmd */
INVALID, /* 11 0 1110 */
- INVALID, /* 11 0 1111 */
+ INVALID, /* 11 0 1111: stmd */
{ 4, LD+U }, /* 11 1 0000: lwzux */
INVALID, /* 11 1 0001 */
{ 4, ST+U }, /* 11 1 0010: stwux */
fix_alignment(struct pt_regs *regs)
{
int instr, nb, flags;
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
int opcode, f1, f2, f3;
#endif
int i, t;
CHECK_FULL_REGS(regs);
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
/* The 4xx-family processors have no DSISR register,
* so we emulate it.
+ * The POWER4 has a DSISR register but doesn't set it on
+ * an alignment fault. -- paulus
*/
instr = *((unsigned int *)regs->nip);
reg = RS(instr);
areg = RA(instr);
- if (IS_DFORM(opcode)) {
+ if (!IS_XFORM(opcode)) {
f1 = 0;
f2 = (instr & 0x04000000) >> 26;
f3 = (instr & 0x78000000) >> 27;