diff options
Diffstat (limited to 'arch/powerpc/lib/sstep.c')
-rw-r--r-- | arch/powerpc/lib/sstep.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index f208f560aecd..70274b7b4773 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
@@ -31,6 +31,8 @@ extern char system_call_common[]; | |||
31 | #define XER_SO 0x80000000U | 31 | #define XER_SO 0x80000000U |
32 | #define XER_OV 0x40000000U | 32 | #define XER_OV 0x40000000U |
33 | #define XER_CA 0x20000000U | 33 | #define XER_CA 0x20000000U |
34 | #define XER_OV32 0x00080000U | ||
35 | #define XER_CA32 0x00040000U | ||
34 | 36 | ||
35 | #ifdef CONFIG_PPC_FPU | 37 | #ifdef CONFIG_PPC_FPU |
36 | /* | 38 | /* |
@@ -962,6 +964,16 @@ static nokprobe_inline void set_cr0(const struct pt_regs *regs, | |||
962 | op->ccval |= 0x20000000; | 964 | op->ccval |= 0x20000000; |
963 | } | 965 | } |
964 | 966 | ||
967 | static nokprobe_inline void set_ca32(struct instruction_op *op, bool val) | ||
968 | { | ||
969 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
970 | if (val) | ||
971 | op->xerval |= XER_CA32; | ||
972 | else | ||
973 | op->xerval &= ~XER_CA32; | ||
974 | } | ||
975 | } | ||
976 | |||
965 | static nokprobe_inline void add_with_carry(const struct pt_regs *regs, | 977 | static nokprobe_inline void add_with_carry(const struct pt_regs *regs, |
966 | struct instruction_op *op, int rd, | 978 | struct instruction_op *op, int rd, |
967 | unsigned long val1, unsigned long val2, | 979 | unsigned long val1, unsigned long val2, |
@@ -985,6 +997,9 @@ static nokprobe_inline void add_with_carry(const struct pt_regs *regs, | |||
985 | op->xerval |= XER_CA; | 997 | op->xerval |= XER_CA; |
986 | else | 998 | else |
987 | op->xerval &= ~XER_CA; | 999 | op->xerval &= ~XER_CA; |
1000 | |||
1001 | set_ca32(op, (unsigned int)val < (unsigned int)val1 || | ||
1002 | (carry_in && (unsigned int)val == (unsigned int)val1)); | ||
988 | } | 1003 | } |
989 | 1004 | ||
990 | static nokprobe_inline void do_cmp_signed(const struct pt_regs *regs, | 1005 | static nokprobe_inline void do_cmp_signed(const struct pt_regs *regs, |
@@ -1791,6 +1806,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | |||
1791 | op->xerval |= XER_CA; | 1806 | op->xerval |= XER_CA; |
1792 | else | 1807 | else |
1793 | op->xerval &= ~XER_CA; | 1808 | op->xerval &= ~XER_CA; |
1809 | set_ca32(op, op->xerval & XER_CA); | ||
1794 | goto logical_done; | 1810 | goto logical_done; |
1795 | 1811 | ||
1796 | case 824: /* srawi */ | 1812 | case 824: /* srawi */ |
@@ -1803,6 +1819,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | |||
1803 | op->xerval |= XER_CA; | 1819 | op->xerval |= XER_CA; |
1804 | else | 1820 | else |
1805 | op->xerval &= ~XER_CA; | 1821 | op->xerval &= ~XER_CA; |
1822 | set_ca32(op, op->xerval & XER_CA); | ||
1806 | goto logical_done; | 1823 | goto logical_done; |
1807 | 1824 | ||
1808 | #ifdef __powerpc64__ | 1825 | #ifdef __powerpc64__ |
@@ -1832,6 +1849,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | |||
1832 | op->xerval |= XER_CA; | 1849 | op->xerval |= XER_CA; |
1833 | else | 1850 | else |
1834 | op->xerval &= ~XER_CA; | 1851 | op->xerval &= ~XER_CA; |
1852 | set_ca32(op, op->xerval & XER_CA); | ||
1835 | goto logical_done; | 1853 | goto logical_done; |
1836 | 1854 | ||
1837 | case 826: /* sradi with sh_5 = 0 */ | 1855 | case 826: /* sradi with sh_5 = 0 */ |
@@ -1845,6 +1863,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | |||
1845 | op->xerval |= XER_CA; | 1863 | op->xerval |= XER_CA; |
1846 | else | 1864 | else |
1847 | op->xerval &= ~XER_CA; | 1865 | op->xerval &= ~XER_CA; |
1866 | set_ca32(op, op->xerval & XER_CA); | ||
1848 | goto logical_done; | 1867 | goto logical_done; |
1849 | #endif /* __powerpc64__ */ | 1868 | #endif /* __powerpc64__ */ |
1850 | 1869 | ||
@@ -2698,6 +2717,7 @@ void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op) | |||
2698 | } | 2717 | } |
2699 | regs->nip = next_pc; | 2718 | regs->nip = next_pc; |
2700 | } | 2719 | } |
2720 | NOKPROBE_SYMBOL(emulate_update_regs); | ||
2701 | 2721 | ||
2702 | /* | 2722 | /* |
2703 | * Emulate a previously-analysed load or store instruction. | 2723 | * Emulate a previously-analysed load or store instruction. |