OLD | NEW |
1 /* Simulator for Analog Devices Blackfin processors. | 1 /* Simulator for Analog Devices Blackfin processors. |
2 | 2 |
3 Copyright (C) 2005-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2005-2012 Free Software Foundation, Inc. |
4 Contributed by Analog Devices, Inc. | 4 Contributed by Analog Devices, Inc. |
5 | 5 |
6 This file is part of simulators. | 6 This file is part of simulators. |
7 | 7 |
8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 static __attribute__ ((noreturn)) void | 46 static __attribute__ ((noreturn)) void |
47 illegal_instruction_combination (SIM_CPU *cpu) | 47 illegal_instruction_combination (SIM_CPU *cpu) |
48 { | 48 { |
49 TRACE_INSN (cpu, "ILLEGAL INSTRUCTION COMBINATION"); | 49 TRACE_INSN (cpu, "ILLEGAL INSTRUCTION COMBINATION"); |
50 while (1) | 50 while (1) |
51 cec_exception (cpu, VEC_ILGAL_I); | 51 cec_exception (cpu, VEC_ILGAL_I); |
52 } | 52 } |
53 | 53 |
54 static __attribute__ ((noreturn)) void | 54 static __attribute__ ((noreturn)) void |
| 55 illegal_instruction_or_combination (SIM_CPU *cpu) |
| 56 { |
| 57 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 58 illegal_instruction_combination (cpu); |
| 59 else |
| 60 illegal_instruction (cpu); |
| 61 } |
| 62 |
| 63 static __attribute__ ((noreturn)) void |
55 unhandled_instruction (SIM_CPU *cpu, const char *insn) | 64 unhandled_instruction (SIM_CPU *cpu, const char *insn) |
56 { | 65 { |
57 SIM_DESC sd = CPU_STATE (cpu); | 66 SIM_DESC sd = CPU_STATE (cpu); |
58 bu16 iw0, iw1; | 67 bu16 iw0, iw1; |
59 bu32 iw2; | 68 bu32 iw2; |
60 | 69 |
61 TRACE_EVENTS (cpu, "unhandled instruction"); | 70 TRACE_EVENTS (cpu, "unhandled instruction"); |
62 | 71 |
63 iw0 = IFETCH (PCREG); | 72 iw0 = IFETCH (PCREG); |
64 iw1 = IFETCH (PCREG + 2); | 73 iw1 = IFETCH (PCREG + 2); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 else | 225 else |
217 x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbit
s) : x; | 226 x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbit
s) : x; |
218 | 227 |
219 if (constant_formats[cf].offset) | 228 if (constant_formats[cf].offset) |
220 x += constant_formats[cf].offset; | 229 x += constant_formats[cf].offset; |
221 | 230 |
222 if (constant_formats[cf].scale) | 231 if (constant_formats[cf].scale) |
223 x <<= constant_formats[cf].scale; | 232 x <<= constant_formats[cf].scale; |
224 | 233 |
225 if (constant_formats[cf].decimal) | 234 if (constant_formats[cf].decimal) |
226 { | 235 sprintf (buf, "%*i", constant_formats[cf].leading, x); |
227 if (constant_formats[cf].leading) | |
228 » { | |
229 » char ps[10]; | |
230 » sprintf (ps, "%%%ii", constant_formats[cf].leading); | |
231 » sprintf (buf, ps, x); | |
232 » } | |
233 else | |
234 » sprintf (buf, "%i", x); | |
235 } | |
236 else | 236 else |
237 { | 237 { |
238 if (constant_formats[cf].issigned && x < 0) | 238 if (constant_formats[cf].issigned && x < 0) |
239 sprintf (buf, "-0x%x", abs (x)); | 239 sprintf (buf, "-0x%x", abs (x)); |
240 else | 240 else |
241 sprintf (buf, "0x%x", x); | 241 sprintf (buf, "0x%x", x); |
242 } | 242 } |
243 | 243 |
244 return buf; | 244 return buf; |
245 } | 245 } |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 break; | 741 break; |
742 } | 742 } |
743 SET_ASTATREG (an, val >> (size - 1)); | 743 SET_ASTATREG (an, val >> (size - 1)); |
744 SET_ASTATREG (az, val == 0); | 744 SET_ASTATREG (az, val == 0); |
745 if (size != 40) | 745 if (size != 40) |
746 SET_ASTATREG (v, 0); | 746 SET_ASTATREG (v, 0); |
747 return val; | 747 return val; |
748 } | 748 } |
749 | 749 |
750 static bu64 | 750 static bu64 |
751 lshift (SIM_CPU *cpu, bu64 val, int cnt, int size, bool saturate) | 751 lshift (SIM_CPU *cpu, bu64 val, int cnt, int size, bool saturate, bool overflow) |
752 { | 752 { |
753 int i, j, real_cnt = cnt > size ? size : cnt; | 753 int v_i, real_cnt = cnt > size ? size : cnt; |
754 bu64 sgn = ~((val >> (size - 1)) - 1); | 754 bu64 sgn = ~((val >> (size - 1)) - 1); |
755 int mask_cnt = size - 1; | 755 int mask_cnt = size - 1; |
756 bu64 masked, new_val = val, tmp; | 756 bu64 masked, new_val = val; |
757 bu64 mask = ~0; | 757 bu64 mask = ~0; |
758 | 758 |
759 mask <<= mask_cnt; | 759 mask <<= mask_cnt; |
760 sgn <<= mask_cnt; | 760 sgn <<= mask_cnt; |
761 masked = val & mask; | 761 masked = val & mask; |
762 | 762 |
763 if (real_cnt > 16) | 763 if (real_cnt > 16) |
764 new_val <<= 16, real_cnt -= 16; | 764 new_val <<= 16, real_cnt -= 16; |
765 | 765 |
766 new_val <<= real_cnt; | 766 new_val <<= real_cnt; |
767 | 767 |
768 masked = new_val & mask; | 768 masked = new_val & mask; |
769 | 769 |
770 /* If an operation would otherwise cause a positive value to overflow | 770 /* If an operation would otherwise cause a positive value to overflow |
771 and become negative, instead, saturation limits the result to the | 771 and become negative, instead, saturation limits the result to the |
772 maximum positive value for the size register being used. | 772 maximum positive value for the size register being used. |
773 | 773 |
774 Conversely, if an operation would otherwise cause a negative value | 774 Conversely, if an operation would otherwise cause a negative value |
775 to overflow and become positive, saturation limits the result to the | 775 to overflow and become positive, saturation limits the result to the |
776 maximum negative value for the register size. | 776 maximum negative value for the register size. |
777 | 777 |
778 However, it's a little more complex than looking at sign bits, we need | 778 However, it's a little more complex than looking at sign bits, we need |
779 to see if we are shifting the sign information away... */ | 779 to see if we are shifting the sign information away... */ |
780 tmp = val & ((~mask << 1) | 1); | 780 if (((val << cnt) >> size) == 0 |
781 | 781 || (((val << cnt) >> size) == ~(~0 << cnt) |
782 j = 0; | 782 » && ((new_val >> (size - 1)) & 0x1))) |
783 for (i = 1; i <= real_cnt && saturate; i++) | 783 v_i = 0; |
784 { | 784 else |
785 if ((tmp & ((bu64)1 << (size - 1))) != | 785 v_i = 1; |
786 » (((val >> mask_cnt) & 0x1) << mask_cnt)) | |
787 » j++; | |
788 tmp <<= 1; | |
789 } | |
790 saturate &= (!sgn && (new_val & (1 << mask_cnt))) | |
791 » || (sgn && !(new_val & (1 << mask_cnt))); | |
792 | 786 |
793 switch (size) | 787 switch (size) |
794 { | 788 { |
795 case 16: | 789 case 16: |
796 if (j || (saturate && (new_val & mask))) | |
797 new_val = sgn == 0 ? 0x7fff : 0x8000, saturate = 1; | |
798 new_val &= 0xFFFF; | 790 new_val &= 0xFFFF; |
| 791 if (saturate && (v_i || ((val >> (size - 1)) != (new_val >> (size - 1))))) |
| 792 { |
| 793 new_val = (val >> (size - 1)) == 0 ? 0x7fff : 0x8000; |
| 794 v_i = 1; |
| 795 } |
799 break; | 796 break; |
800 case 32: | 797 case 32: |
801 new_val &= 0xFFFFFFFF; | 798 new_val &= 0xFFFFFFFF; |
802 masked &= 0xFFFFFFFF; | 799 masked &= 0xFFFFFFFF; |
803 if (j || (saturate && ((sgn != masked) || (!sgn && new_val == 0)))) | 800 sgn &= 0xFFFFFFFF; |
804 » new_val = sgn == 0 ? 0x7fffffff : 0x80000000, saturate = 1; | 801 if (saturate |
| 802 » && (v_i |
| 803 » || (sgn != masked) |
| 804 » || (!sgn && new_val == 0 && val != 0))) |
| 805 » { |
| 806 » new_val = sgn == 0 ? 0x7fffffff : 0x80000000; |
| 807 » v_i = 1; |
| 808 » } |
805 break; | 809 break; |
806 case 40: | 810 case 40: |
807 new_val &= 0xFFFFFFFFFFull; | 811 new_val &= 0xFFFFFFFFFFull; |
808 masked &= 0xFFFFFFFFFFull; | 812 masked &= 0xFFFFFFFFFFull; |
809 break; | 813 break; |
810 default: | 814 default: |
811 illegal_instruction (cpu); | 815 illegal_instruction (cpu); |
812 break; | 816 break; |
813 } | 817 } |
814 | 818 |
815 SET_ASTATREG (an, new_val >> (size - 1)); | 819 SET_ASTATREG (an, new_val >> (size - 1)); |
816 SET_ASTATREG (az, new_val == 0); | 820 SET_ASTATREG (az, new_val == 0); |
817 SET_ASTATREG (v, !!(saturate || j)); | 821 if (size != 40) |
818 if (saturate || j) | 822 { |
819 SET_ASTATREG (vs, 1); | 823 SET_ASTATREG (v, overflow && v_i); |
| 824 if (overflow && v_i) |
| 825 » SET_ASTATREG (vs, 1); |
| 826 } |
| 827 |
820 return new_val; | 828 return new_val; |
821 } | 829 } |
822 | 830 |
823 static bu32 | 831 static bu32 |
824 algn (bu32 l, bu32 h, bu32 aln) | 832 algn (bu32 l, bu32 h, bu32 aln) |
825 { | 833 { |
826 if (aln == 0) | 834 if (aln == 0) |
827 return l; | 835 return l; |
828 else | 836 else |
829 return (l >> (8 * aln)) | (h << (32 - 8 * aln)); | 837 return (l >> (8 * aln)) | (h << (32 - 8 * aln)); |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 { | 1764 { |
1757 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_nop); | 1765 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_nop); |
1758 TRACE_INSN (cpu, "NOP;"); | 1766 TRACE_INSN (cpu, "NOP;"); |
1759 } | 1767 } |
1760 else if (prgfunc == 1 && poprnd == 0) | 1768 else if (prgfunc == 1 && poprnd == 0) |
1761 { | 1769 { |
1762 bu32 newpc = RETSREG; | 1770 bu32 newpc = RETSREG; |
1763 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1771 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1764 TRACE_INSN (cpu, "RTS;"); | 1772 TRACE_INSN (cpu, "RTS;"); |
1765 IFETCH_CHECK (newpc); | 1773 IFETCH_CHECK (newpc); |
1766 if (INSN_LEN == 8) | 1774 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1767 illegal_instruction_combination (cpu); | 1775 illegal_instruction_combination (cpu); |
1768 TRACE_BRANCH (cpu, pc, newpc, -1, "RTS"); | 1776 TRACE_BRANCH (cpu, pc, newpc, -1, "RTS"); |
1769 SET_PCREG (newpc); | 1777 SET_PCREG (newpc); |
1770 BFIN_CPU_STATE.did_jump = true; | 1778 BFIN_CPU_STATE.did_jump = true; |
1771 CYCLE_DELAY = 5; | 1779 CYCLE_DELAY = 5; |
1772 } | 1780 } |
1773 else if (prgfunc == 1 && poprnd == 1) | 1781 else if (prgfunc == 1 && poprnd == 1) |
1774 { | 1782 { |
1775 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1783 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1776 TRACE_INSN (cpu, "RTI;"); | 1784 TRACE_INSN (cpu, "RTI;"); |
1777 /* Do not do IFETCH_CHECK here -- LSB has special meaning. */ | 1785 /* Do not do IFETCH_CHECK here -- LSB has special meaning. */ |
1778 if (INSN_LEN == 8) | 1786 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1779 illegal_instruction_combination (cpu); | 1787 illegal_instruction_combination (cpu); |
1780 cec_return (cpu, -1); | 1788 cec_return (cpu, -1); |
1781 CYCLE_DELAY = 5; | 1789 CYCLE_DELAY = 5; |
1782 } | 1790 } |
1783 else if (prgfunc == 1 && poprnd == 2) | 1791 else if (prgfunc == 1 && poprnd == 2) |
1784 { | 1792 { |
1785 bu32 newpc = RETXREG; | 1793 bu32 newpc = RETXREG; |
1786 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1794 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1787 TRACE_INSN (cpu, "RTX;"); | 1795 TRACE_INSN (cpu, "RTX;"); |
1788 /* XXX: Not sure if this is what the hardware does. */ | 1796 /* XXX: Not sure if this is what the hardware does. */ |
1789 IFETCH_CHECK (newpc); | 1797 IFETCH_CHECK (newpc); |
1790 if (INSN_LEN == 8) | 1798 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1791 illegal_instruction_combination (cpu); | 1799 illegal_instruction_combination (cpu); |
1792 cec_return (cpu, IVG_EVX); | 1800 cec_return (cpu, IVG_EVX); |
1793 CYCLE_DELAY = 5; | 1801 CYCLE_DELAY = 5; |
1794 } | 1802 } |
1795 else if (prgfunc == 1 && poprnd == 3) | 1803 else if (prgfunc == 1 && poprnd == 3) |
1796 { | 1804 { |
1797 bu32 newpc = RETNREG; | 1805 bu32 newpc = RETNREG; |
1798 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1806 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1799 TRACE_INSN (cpu, "RTN;"); | 1807 TRACE_INSN (cpu, "RTN;"); |
1800 /* XXX: Not sure if this is what the hardware does. */ | 1808 /* XXX: Not sure if this is what the hardware does. */ |
1801 IFETCH_CHECK (newpc); | 1809 IFETCH_CHECK (newpc); |
1802 if (INSN_LEN == 8) | 1810 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1803 illegal_instruction_combination (cpu); | 1811 illegal_instruction_combination (cpu); |
1804 cec_return (cpu, IVG_NMI); | 1812 cec_return (cpu, IVG_NMI); |
1805 CYCLE_DELAY = 5; | 1813 CYCLE_DELAY = 5; |
1806 } | 1814 } |
1807 else if (prgfunc == 1 && poprnd == 4) | 1815 else if (prgfunc == 1 && poprnd == 4) |
1808 { | 1816 { |
1809 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1817 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1810 TRACE_INSN (cpu, "RTE;"); | 1818 TRACE_INSN (cpu, "RTE;"); |
1811 if (INSN_LEN == 8) | 1819 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1812 illegal_instruction_combination (cpu); | 1820 illegal_instruction_combination (cpu); |
1813 cec_return (cpu, IVG_EMU); | 1821 cec_return (cpu, IVG_EMU); |
1814 CYCLE_DELAY = 5; | 1822 CYCLE_DELAY = 5; |
1815 } | 1823 } |
1816 else if (prgfunc == 2 && poprnd == 0) | 1824 else if (prgfunc == 2 && poprnd == 0) |
1817 { | 1825 { |
1818 SIM_DESC sd = CPU_STATE (cpu); | 1826 SIM_DESC sd = CPU_STATE (cpu); |
1819 sim_events *events = STATE_EVENTS (sd); | 1827 sim_events *events = STATE_EVENTS (sd); |
1820 | 1828 |
1821 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); | 1829 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); |
1822 /* XXX: in supervisor mode, utilizes wake up sources | 1830 /* XXX: in supervisor mode, utilizes wake up sources |
1823 in user mode, it's a NOP ... */ | 1831 in user mode, it's a NOP ... */ |
1824 TRACE_INSN (cpu, "IDLE;"); | 1832 TRACE_INSN (cpu, "IDLE;"); |
1825 | 1833 |
1826 if (INSN_LEN == 8) | 1834 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1827 illegal_instruction_combination (cpu); | 1835 illegal_instruction_combination (cpu); |
1828 | 1836 |
1829 /* Timewarp ! */ | 1837 /* Timewarp ! */ |
1830 if (events->queue) | 1838 if (events->queue) |
1831 CYCLE_DELAY = events->time_from_event; | 1839 CYCLE_DELAY = events->time_from_event; |
1832 else | 1840 else |
1833 abort (); /* XXX: Should this ever happen ? */ | 1841 abort (); /* XXX: Should this ever happen ? */ |
1834 } | 1842 } |
1835 else if (prgfunc == 2 && poprnd == 3) | 1843 else if (prgfunc == 2 && poprnd == 3) |
1836 { | 1844 { |
1837 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); | 1845 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); |
1838 /* Just NOP it. */ | 1846 /* Just NOP it. */ |
1839 TRACE_INSN (cpu, "CSYNC;"); | 1847 TRACE_INSN (cpu, "CSYNC;"); |
1840 if (INSN_LEN == 8) | 1848 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1841 illegal_instruction_combination (cpu); | 1849 illegal_instruction_combination (cpu); |
1842 CYCLE_DELAY = 10; | 1850 CYCLE_DELAY = 10; |
1843 } | 1851 } |
1844 else if (prgfunc == 2 && poprnd == 4) | 1852 else if (prgfunc == 2 && poprnd == 4) |
1845 { | 1853 { |
1846 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); | 1854 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync); |
1847 /* Just NOP it. */ | 1855 /* Just NOP it. */ |
1848 TRACE_INSN (cpu, "SSYNC;"); | 1856 TRACE_INSN (cpu, "SSYNC;"); |
1849 if (INSN_LEN == 8) | 1857 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1850 illegal_instruction_combination (cpu); | 1858 illegal_instruction_combination (cpu); |
1851 | 1859 |
1852 /* Really 10+, but no model info for this. */ | 1860 /* Really 10+, but no model info for this. */ |
1853 CYCLE_DELAY = 10; | 1861 CYCLE_DELAY = 10; |
1854 } | 1862 } |
1855 else if (prgfunc == 2 && poprnd == 5) | 1863 else if (prgfunc == 2 && poprnd == 5) |
1856 { | 1864 { |
1857 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); | 1865 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); |
1858 TRACE_INSN (cpu, "EMUEXCPT;"); | 1866 TRACE_INSN (cpu, "EMUEXCPT;"); |
1859 if (INSN_LEN == 8) | 1867 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1860 illegal_instruction_combination (cpu); | 1868 illegal_instruction_combination (cpu); |
1861 cec_exception (cpu, VEC_SIM_TRAP); | 1869 cec_exception (cpu, VEC_SIM_TRAP); |
1862 } | 1870 } |
1863 else if (prgfunc == 3 && poprnd < 8) | 1871 else if (prgfunc == 3 && poprnd < 8) |
1864 { | 1872 { |
1865 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); | 1873 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); |
1866 TRACE_INSN (cpu, "CLI R%i;", poprnd); | 1874 TRACE_INSN (cpu, "CLI R%i;", poprnd); |
1867 if (INSN_LEN == 8) | 1875 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1868 illegal_instruction_combination (cpu); | 1876 illegal_instruction_combination (cpu); |
1869 SET_DREG (poprnd, cec_cli (cpu)); | 1877 SET_DREG (poprnd, cec_cli (cpu)); |
1870 } | 1878 } |
1871 else if (prgfunc == 4 && poprnd < 8) | 1879 else if (prgfunc == 4 && poprnd < 8) |
1872 { | 1880 { |
1873 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); | 1881 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); |
1874 TRACE_INSN (cpu, "STI R%i;", poprnd); | 1882 TRACE_INSN (cpu, "STI R%i;", poprnd); |
1875 if (INSN_LEN == 8) | 1883 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1876 illegal_instruction_combination (cpu); | 1884 illegal_instruction_combination (cpu); |
1877 cec_sti (cpu, DREG (poprnd)); | 1885 cec_sti (cpu, DREG (poprnd)); |
1878 CYCLE_DELAY = 3; | 1886 CYCLE_DELAY = 3; |
1879 } | 1887 } |
1880 else if (prgfunc == 5 && poprnd < 8) | 1888 else if (prgfunc == 5 && poprnd < 8) |
1881 { | 1889 { |
1882 bu32 newpc = PREG (poprnd); | 1890 bu32 newpc = PREG (poprnd); |
1883 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1891 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1884 TRACE_INSN (cpu, "JUMP (%s);", get_preg_name (poprnd)); | 1892 TRACE_INSN (cpu, "JUMP (%s);", get_preg_name (poprnd)); |
1885 IFETCH_CHECK (newpc); | 1893 IFETCH_CHECK (newpc); |
1886 if (INSN_LEN == 8) | 1894 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1887 illegal_instruction_combination (cpu); | 1895 illegal_instruction_combination (cpu); |
1888 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)"); | 1896 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)"); |
1889 SET_PCREG (newpc); | 1897 SET_PCREG (newpc); |
1890 BFIN_CPU_STATE.did_jump = true; | 1898 BFIN_CPU_STATE.did_jump = true; |
1891 PROFILE_BRANCH_TAKEN (cpu); | 1899 PROFILE_BRANCH_TAKEN (cpu); |
1892 CYCLE_DELAY = 5; | 1900 CYCLE_DELAY = 5; |
1893 } | 1901 } |
1894 else if (prgfunc == 6 && poprnd < 8) | 1902 else if (prgfunc == 6 && poprnd < 8) |
1895 { | 1903 { |
1896 bu32 newpc = PREG (poprnd); | 1904 bu32 newpc = PREG (poprnd); |
1897 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1905 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1898 TRACE_INSN (cpu, "CALL (%s);", get_preg_name (poprnd)); | 1906 TRACE_INSN (cpu, "CALL (%s);", get_preg_name (poprnd)); |
1899 IFETCH_CHECK (newpc); | 1907 IFETCH_CHECK (newpc); |
1900 if (INSN_LEN == 8) | 1908 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1901 illegal_instruction_combination (cpu); | 1909 illegal_instruction_combination (cpu); |
1902 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)"); | 1910 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)"); |
1903 /* If we're at the end of a hardware loop, RETS is going to be | 1911 /* If we're at the end of a hardware loop, RETS is going to be |
1904 the top of the loop rather than the next instruction. */ | 1912 the top of the loop rather than the next instruction. */ |
1905 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2)); | 1913 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2)); |
1906 SET_PCREG (newpc); | 1914 SET_PCREG (newpc); |
1907 BFIN_CPU_STATE.did_jump = true; | 1915 BFIN_CPU_STATE.did_jump = true; |
1908 PROFILE_BRANCH_TAKEN (cpu); | 1916 PROFILE_BRANCH_TAKEN (cpu); |
1909 CYCLE_DELAY = 5; | 1917 CYCLE_DELAY = 5; |
1910 } | 1918 } |
1911 else if (prgfunc == 7 && poprnd < 8) | 1919 else if (prgfunc == 7 && poprnd < 8) |
1912 { | 1920 { |
1913 bu32 newpc = pc + PREG (poprnd); | 1921 bu32 newpc = pc + PREG (poprnd); |
1914 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1922 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1915 TRACE_INSN (cpu, "CALL (PC + %s);", get_preg_name (poprnd)); | 1923 TRACE_INSN (cpu, "CALL (PC + %s);", get_preg_name (poprnd)); |
1916 IFETCH_CHECK (newpc); | 1924 IFETCH_CHECK (newpc); |
1917 if (INSN_LEN == 8) | 1925 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1918 illegal_instruction_combination (cpu); | 1926 illegal_instruction_combination (cpu); |
1919 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)"); | 1927 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)"); |
1920 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2)); | 1928 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2)); |
1921 SET_PCREG (newpc); | 1929 SET_PCREG (newpc); |
1922 BFIN_CPU_STATE.did_jump = true; | 1930 BFIN_CPU_STATE.did_jump = true; |
1923 PROFILE_BRANCH_TAKEN (cpu); | 1931 PROFILE_BRANCH_TAKEN (cpu); |
1924 CYCLE_DELAY = 5; | 1932 CYCLE_DELAY = 5; |
1925 } | 1933 } |
1926 else if (prgfunc == 8 && poprnd < 8) | 1934 else if (prgfunc == 8 && poprnd < 8) |
1927 { | 1935 { |
1928 bu32 newpc = pc + PREG (poprnd); | 1936 bu32 newpc = pc + PREG (poprnd); |
1929 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); | 1937 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch); |
1930 TRACE_INSN (cpu, "JUMP (PC + %s);", get_preg_name (poprnd)); | 1938 TRACE_INSN (cpu, "JUMP (PC + %s);", get_preg_name (poprnd)); |
1931 IFETCH_CHECK (newpc); | 1939 IFETCH_CHECK (newpc); |
1932 if (INSN_LEN == 8) | 1940 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1933 illegal_instruction_combination (cpu); | 1941 illegal_instruction_combination (cpu); |
1934 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)"); | 1942 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)"); |
1935 SET_PCREG (newpc); | 1943 SET_PCREG (newpc); |
1936 BFIN_CPU_STATE.did_jump = true; | 1944 BFIN_CPU_STATE.did_jump = true; |
1937 PROFILE_BRANCH_TAKEN (cpu); | 1945 PROFILE_BRANCH_TAKEN (cpu); |
1938 CYCLE_DELAY = 5; | 1946 CYCLE_DELAY = 5; |
1939 } | 1947 } |
1940 else if (prgfunc == 9) | 1948 else if (prgfunc == 9) |
1941 { | 1949 { |
1942 int raise = uimm4 (poprnd); | 1950 int raise = uimm4 (poprnd); |
1943 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); | 1951 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); |
1944 TRACE_INSN (cpu, "RAISE %s;", uimm4_str (raise)); | 1952 TRACE_INSN (cpu, "RAISE %s;", uimm4_str (raise)); |
1945 if (INSN_LEN == 8) | 1953 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1946 illegal_instruction_combination (cpu); | 1954 illegal_instruction_combination (cpu); |
1947 cec_require_supervisor (cpu); | 1955 cec_require_supervisor (cpu); |
1948 if (raise == IVG_IVHW) | 1956 if (raise == IVG_IVHW) |
1949 cec_hwerr (cpu, HWERR_RAISE_5); | 1957 cec_hwerr (cpu, HWERR_RAISE_5); |
1950 else | 1958 else |
1951 cec_latch (cpu, raise); | 1959 cec_latch (cpu, raise); |
1952 CYCLE_DELAY = 3; /* XXX: Only if IVG is unmasked. */ | 1960 CYCLE_DELAY = 3; /* XXX: Only if IVG is unmasked. */ |
1953 } | 1961 } |
1954 else if (prgfunc == 10) | 1962 else if (prgfunc == 10) |
1955 { | 1963 { |
1956 int excpt = uimm4 (poprnd); | 1964 int excpt = uimm4 (poprnd); |
1957 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); | 1965 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec); |
1958 TRACE_INSN (cpu, "EXCPT %s;", uimm4_str (excpt)); | 1966 TRACE_INSN (cpu, "EXCPT %s;", uimm4_str (excpt)); |
1959 if (INSN_LEN == 8) | 1967 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1960 illegal_instruction_combination (cpu); | 1968 illegal_instruction_combination (cpu); |
1961 cec_exception (cpu, excpt); | 1969 cec_exception (cpu, excpt); |
1962 CYCLE_DELAY = 3; | 1970 CYCLE_DELAY = 3; |
1963 } | 1971 } |
1964 else if (prgfunc == 11 && poprnd < 6) | 1972 else if (prgfunc == 11 && poprnd < 6) |
1965 { | 1973 { |
1966 bu32 addr = PREG (poprnd); | 1974 bu32 addr = PREG (poprnd); |
1967 bu8 byte; | 1975 bu8 byte; |
1968 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_atomic); | 1976 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_atomic); |
1969 TRACE_INSN (cpu, "TESTSET (%s);", get_preg_name (poprnd)); | 1977 TRACE_INSN (cpu, "TESTSET (%s);", get_preg_name (poprnd)); |
1970 if (INSN_LEN == 8) | 1978 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
1971 illegal_instruction_combination (cpu); | 1979 illegal_instruction_combination (cpu); |
1972 byte = GET_WORD (addr); | 1980 byte = GET_WORD (addr); |
1973 SET_CCREG (byte == 0); | 1981 SET_CCREG (byte == 0); |
1974 PUT_BYTE (addr, byte | 0x80); | 1982 PUT_BYTE (addr, byte | 0x80); |
1975 /* Also includes memory stalls, but we don't model that. */ | 1983 /* Also includes memory stalls, but we don't model that. */ |
1976 CYCLE_DELAY = 2; | 1984 CYCLE_DELAY = 2; |
1977 } | 1985 } |
1978 else | 1986 else |
1979 illegal_instruction (cpu); | 1987 illegal_instruction_or_combination (cpu); |
1980 } | 1988 } |
1981 | 1989 |
1982 static void | 1990 static void |
1983 decode_CaCTRL_0 (SIM_CPU *cpu, bu16 iw0) | 1991 decode_CaCTRL_0 (SIM_CPU *cpu, bu16 iw0) |
1984 { | 1992 { |
1985 /* CaCTRL | 1993 /* CaCTRL |
1986 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 1994 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
1987 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......| | 1995 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......| |
1988 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 1996 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
1989 int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask); | 1997 int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask); |
1990 int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask); | 1998 int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask); |
1991 int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask); | 1999 int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask); |
1992 bu32 preg = PREG (reg); | 2000 bu32 preg = PREG (reg); |
1993 const char * const sinsn[] = { "PREFETCH", "FLUSHINV", "FLUSH", "IFLUSH", }; | 2001 const char * const sinsn[] = { "PREFETCH", "FLUSHINV", "FLUSH", "IFLUSH", }; |
1994 | 2002 |
1995 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CaCTRL); | 2003 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CaCTRL); |
1996 TRACE_EXTRACT (cpu, "%s: a:%i op:%i reg:%i", __func__, a, op, reg); | 2004 TRACE_EXTRACT (cpu, "%s: a:%i op:%i reg:%i", __func__, a, op, reg); |
1997 TRACE_INSN (cpu, "%s [%s%s];", sinsn[op], get_preg_name (reg), a ? "++" : ""); | 2005 TRACE_INSN (cpu, "%s [%s%s];", sinsn[op], get_preg_name (reg), a ? "++" : ""); |
1998 | 2006 |
1999 if (INSN_LEN == 8) | 2007 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2000 /* None of these can be part of a parallel instruction. */ | 2008 /* None of these can be part of a parallel instruction. */ |
2001 illegal_instruction_combination (cpu); | 2009 illegal_instruction_combination (cpu); |
2002 | 2010 |
2003 /* No cache simulation, so these are (mostly) all NOPs. | 2011 /* No cache simulation, so these are (mostly) all NOPs. |
2004 XXX: The hardware takes care of masking to cache lines, but need | 2012 XXX: The hardware takes care of masking to cache lines, but need |
2005 to check behavior of the post increment. Should we be aligning | 2013 to check behavior of the post increment. Should we be aligning |
2006 the value to the cache line before adding the cache line size, or | 2014 the value to the cache line before adding the cache line size, or |
2007 do we just add the cache line size ? */ | 2015 do we just add the cache line size ? */ |
2008 if (op == 0) | 2016 if (op == 0) |
2009 { /* PREFETCH */ | 2017 { /* PREFETCH */ |
(...skipping 29 matching lines...) Expand all Loading... |
2039 const char *reg_name = get_allreg_name (grp, reg); | 2047 const char *reg_name = get_allreg_name (grp, reg); |
2040 bu32 value; | 2048 bu32 value; |
2041 bu32 sp = SPREG; | 2049 bu32 sp = SPREG; |
2042 | 2050 |
2043 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopReg); | 2051 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopReg); |
2044 TRACE_EXTRACT (cpu, "%s: W:%i grp:%i reg:%i", __func__, W, grp, reg); | 2052 TRACE_EXTRACT (cpu, "%s: W:%i grp:%i reg:%i", __func__, W, grp, reg); |
2045 TRACE_DECODE (cpu, "%s: reg:%s", __func__, reg_name); | 2053 TRACE_DECODE (cpu, "%s: reg:%s", __func__, reg_name); |
2046 | 2054 |
2047 /* Can't push/pop reserved registers */ | 2055 /* Can't push/pop reserved registers */ |
2048 if (reg_is_reserved (grp, reg)) | 2056 if (reg_is_reserved (grp, reg)) |
2049 illegal_instruction (cpu); | 2057 illegal_instruction_or_combination (cpu); |
2050 | 2058 |
2051 if (W == 0) | 2059 if (W == 0) |
2052 { | 2060 { |
2053 /* Dreg and Preg are not supported by this instruction. */ | 2061 /* Dreg and Preg are not supported by this instruction. */ |
2054 if (grp == 0 || grp == 1) | 2062 if (grp == 0 || grp == 1) |
2055 » illegal_instruction (cpu); | 2063 » illegal_instruction_or_combination (cpu); |
2056 TRACE_INSN (cpu, "%s = [SP++];", reg_name); | 2064 TRACE_INSN (cpu, "%s = [SP++];", reg_name); |
2057 /* Can't pop USP while in userspace. */ | 2065 /* Can't pop USP while in userspace. */ |
2058 if (INSN_LEN == 8 || (grp == 7 && reg == 0 && cec_is_user_mode(cpu))) | 2066 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE |
| 2067 » || (grp == 7 && reg == 0 && cec_is_user_mode(cpu))) |
2059 illegal_instruction_combination (cpu); | 2068 illegal_instruction_combination (cpu); |
2060 /* XXX: The valid register check is in reg_write(), so we might | 2069 /* XXX: The valid register check is in reg_write(), so we might |
2061 incorrectly do a GET_LONG() here ... */ | 2070 incorrectly do a GET_LONG() here ... */ |
2062 value = GET_LONG (sp); | 2071 value = GET_LONG (sp); |
2063 reg_write (cpu, grp, reg, value); | 2072 reg_write (cpu, grp, reg, value); |
2064 if (grp == 7 && reg == 3) | 2073 if (grp == 7 && reg == 3) |
2065 cec_pop_reti (cpu); | 2074 cec_pop_reti (cpu); |
2066 | 2075 |
2067 sp += 4; | 2076 sp += 4; |
2068 } | 2077 } |
2069 else | 2078 else |
2070 { | 2079 { |
2071 TRACE_INSN (cpu, "[--SP] = %s;", reg_name); | 2080 TRACE_INSN (cpu, "[--SP] = %s;", reg_name); |
2072 if (INSN_LEN == 8) | 2081 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2073 illegal_instruction_combination (cpu); | 2082 illegal_instruction_combination (cpu); |
2074 | 2083 |
2075 sp -= 4; | 2084 sp -= 4; |
2076 value = reg_read (cpu, grp, reg); | 2085 value = reg_read (cpu, grp, reg); |
2077 if (grp == 7 && reg == 3) | 2086 if (grp == 7 && reg == 3) |
2078 cec_push_reti (cpu); | 2087 cec_push_reti (cpu); |
2079 | 2088 |
2080 PUT_LONG (sp, value); | 2089 PUT_LONG (sp, value); |
2081 } | 2090 } |
2082 | 2091 |
(...skipping 14 matching lines...) Expand all Loading... |
2097 int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask); | 2106 int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask); |
2098 int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask); | 2107 int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask); |
2099 int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask); | 2108 int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask); |
2100 int i; | 2109 int i; |
2101 bu32 sp = SPREG; | 2110 bu32 sp = SPREG; |
2102 | 2111 |
2103 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopMultiple); | 2112 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopMultiple); |
2104 TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i", | 2113 TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i", |
2105 __func__, d, p, W, dr, pr); | 2114 __func__, d, p, W, dr, pr); |
2106 | 2115 |
| 2116 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2117 illegal_instruction_combination (cpu); |
| 2118 |
2107 if ((d == 0 && p == 0) || (p && imm5 (pr) > 5) | 2119 if ((d == 0 && p == 0) || (p && imm5 (pr) > 5) |
2108 || (d && !p && pr) || (p && !d && dr)) | 2120 || (d && !p && pr) || (p && !d && dr)) |
2109 illegal_instruction (cpu); | 2121 illegal_instruction (cpu); |
2110 | 2122 |
2111 if (W == 1) | 2123 if (W == 1) |
2112 { | 2124 { |
2113 if (d && p) | 2125 if (d && p) |
2114 TRACE_INSN (cpu, "[--SP] = (R7:%i, P5:%i);", dr, pr); | 2126 TRACE_INSN (cpu, "[--SP] = (R7:%i, P5:%i);", dr, pr); |
2115 else if (d) | 2127 else if (d) |
2116 TRACE_INSN (cpu, "[--SP] = (R7:%i);", dr); | 2128 TRACE_INSN (cpu, "[--SP] = (R7:%i);", dr); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2177 int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask); | 2189 int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask); |
2178 int cond = T ? CCREG : ! CCREG; | 2190 int cond = T ? CCREG : ! CCREG; |
2179 | 2191 |
2180 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ccMV); | 2192 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ccMV); |
2181 TRACE_EXTRACT (cpu, "%s: T:%i d:%i s:%i dst:%i src:%i", | 2193 TRACE_EXTRACT (cpu, "%s: T:%i d:%i s:%i dst:%i src:%i", |
2182 __func__, T, d, s, dst, src); | 2194 __func__, T, d, s, dst, src); |
2183 | 2195 |
2184 TRACE_INSN (cpu, "IF %sCC %s = %s;", T ? "" : "! ", | 2196 TRACE_INSN (cpu, "IF %sCC %s = %s;", T ? "" : "! ", |
2185 get_allreg_name (d, dst), | 2197 get_allreg_name (d, dst), |
2186 get_allreg_name (s, src)); | 2198 get_allreg_name (s, src)); |
2187 if (INSN_LEN == 8) | 2199 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2188 illegal_instruction_combination (cpu); | 2200 illegal_instruction_combination (cpu); |
2189 | 2201 |
2190 if (cond) | 2202 if (cond) |
2191 reg_write (cpu, d, dst, reg_read (cpu, s, src)); | 2203 reg_write (cpu, d, dst, reg_read (cpu, s, src)); |
2192 } | 2204 } |
2193 | 2205 |
2194 static void | 2206 static void |
2195 decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0) | 2207 decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0) |
2196 { | 2208 { |
2197 /* CCflag | 2209 /* CCflag |
(...skipping 10 matching lines...) Expand all Loading... |
2208 TRACE_EXTRACT (cpu, "%s: I:%i opc:%i G:%i y:%i x:%i", | 2220 TRACE_EXTRACT (cpu, "%s: I:%i opc:%i G:%i y:%i x:%i", |
2209 __func__, I, opc, G, y, x); | 2221 __func__, I, opc, G, y, x); |
2210 | 2222 |
2211 if (opc > 4) | 2223 if (opc > 4) |
2212 { | 2224 { |
2213 bs64 acc0 = get_extended_acc (cpu, 0); | 2225 bs64 acc0 = get_extended_acc (cpu, 0); |
2214 bs64 acc1 = get_extended_acc (cpu, 1); | 2226 bs64 acc1 = get_extended_acc (cpu, 1); |
2215 bs64 diff = acc0 - acc1; | 2227 bs64 diff = acc0 - acc1; |
2216 | 2228 |
2217 if (x != 0 || y != 0) | 2229 if (x != 0 || y != 0) |
2218 » illegal_instruction (cpu); | 2230 » illegal_instruction_or_combination (cpu); |
2219 | 2231 |
2220 if (opc == 5 && I == 0 && G == 0) | 2232 if (opc == 5 && I == 0 && G == 0) |
2221 { | 2233 { |
2222 TRACE_INSN (cpu, "CC = A0 == A1;"); | 2234 TRACE_INSN (cpu, "CC = A0 == A1;"); |
2223 » if (INSN_LEN == 8) | 2235 » if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2224 illegal_instruction_combination (cpu); | 2236 illegal_instruction_combination (cpu); |
2225 SET_CCREG (acc0 == acc1); | 2237 SET_CCREG (acc0 == acc1); |
2226 } | 2238 } |
2227 else if (opc == 6 && I == 0 && G == 0) | 2239 else if (opc == 6 && I == 0 && G == 0) |
2228 { | 2240 { |
2229 TRACE_INSN (cpu, "CC = A0 < A1"); | 2241 TRACE_INSN (cpu, "CC = A0 < A1"); |
2230 » if (INSN_LEN == 8) | 2242 » if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2231 illegal_instruction_combination (cpu); | 2243 illegal_instruction_combination (cpu); |
2232 SET_CCREG (acc0 < acc1); | 2244 SET_CCREG (acc0 < acc1); |
2233 } | 2245 } |
2234 else if (opc == 7 && I == 0 && G == 0) | 2246 else if (opc == 7 && I == 0 && G == 0) |
2235 { | 2247 { |
2236 TRACE_INSN (cpu, "CC = A0 <= A1"); | 2248 TRACE_INSN (cpu, "CC = A0 <= A1"); |
2237 » if (INSN_LEN == 8) | 2249 » if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2238 illegal_instruction_combination (cpu); | 2250 illegal_instruction_combination (cpu); |
2239 SET_CCREG (acc0 <= acc1); | 2251 SET_CCREG (acc0 <= acc1); |
2240 } | 2252 } |
2241 else | 2253 else |
2242 » illegal_instruction (cpu); | 2254 » illegal_instruction_or_combination (cpu); |
2243 | 2255 |
2244 SET_ASTATREG (az, diff == 0); | 2256 SET_ASTATREG (az, diff == 0); |
2245 SET_ASTATREG (an, diff < 0); | 2257 SET_ASTATREG (an, diff < 0); |
2246 SET_ASTATREG (ac0, (bu40)acc1 <= (bu40)acc0); | 2258 SET_ASTATREG (ac0, (bu40)acc1 <= (bu40)acc0); |
2247 } | 2259 } |
2248 else | 2260 else |
2249 { | 2261 { |
2250 int issigned = opc < 3; | 2262 int issigned = opc < 3; |
2251 const char *sign = issigned ? "" : " (IU)"; | 2263 const char *sign = issigned ? "" : " (IU)"; |
2252 bu32 srcop = G ? PREG (x) : DREG (x); | 2264 bu32 srcop = G ? PREG (x) : DREG (x); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 if (I) | 2309 if (I) |
2298 TRACE_INSN (cpu, "CC = %c%i %s %s%s;", s, x, op, | 2310 TRACE_INSN (cpu, "CC = %c%i %s %s%s;", s, x, op, |
2299 issigned ? imm3_str (y) : uimm3_str (y), sign); | 2311 issigned ? imm3_str (y) : uimm3_str (y), sign); |
2300 else | 2312 else |
2301 { | 2313 { |
2302 TRACE_DECODE (cpu, "%s %c%i:%x %c%i:%x", __func__, | 2314 TRACE_DECODE (cpu, "%s %c%i:%x %c%i:%x", __func__, |
2303 s, x, srcop, d, y, dstop); | 2315 s, x, srcop, d, y, dstop); |
2304 TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign); | 2316 TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign); |
2305 } | 2317 } |
2306 | 2318 |
| 2319 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2320 illegal_instruction_combination (cpu); |
| 2321 |
2307 SET_CCREG (cc); | 2322 SET_CCREG (cc); |
2308 /* Pointer compares only touch CC. */ | 2323 /* Pointer compares only touch CC. */ |
2309 if (!G) | 2324 if (!G) |
2310 { | 2325 { |
2311 SET_ASTATREG (az, az); | 2326 SET_ASTATREG (az, az); |
2312 SET_ASTATREG (an, an); | 2327 SET_ASTATREG (an, an); |
2313 SET_ASTATREG (ac0, ac0); | 2328 SET_ASTATREG (ac0, ac0); |
2314 } | 2329 } |
2315 } | 2330 } |
2316 } | 2331 } |
2317 | 2332 |
2318 static void | 2333 static void |
2319 decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0) | 2334 decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0) |
2320 { | 2335 { |
2321 /* CC2dreg | 2336 /* CC2dreg |
2322 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 2337 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
2323 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......| | 2338 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......| |
2324 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2339 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2325 int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask); | 2340 int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask); |
2326 int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask); | 2341 int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask); |
2327 | 2342 |
2328 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2dreg); | 2343 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2dreg); |
2329 TRACE_EXTRACT (cpu, "%s: op:%i reg:%i", __func__, op, reg); | 2344 TRACE_EXTRACT (cpu, "%s: op:%i reg:%i", __func__, op, reg); |
2330 | 2345 |
2331 if (op == 0) | 2346 if (op == 0) |
2332 { | 2347 { |
2333 TRACE_INSN (cpu, "R%i = CC;", reg); | 2348 TRACE_INSN (cpu, "R%i = CC;", reg); |
2334 if (INSN_LEN == 8) | 2349 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2335 illegal_instruction_combination (cpu); | 2350 illegal_instruction_combination (cpu); |
2336 SET_DREG (reg, CCREG); | 2351 SET_DREG (reg, CCREG); |
2337 } | 2352 } |
2338 else if (op == 1) | 2353 else if (op == 1) |
2339 { | 2354 { |
2340 TRACE_INSN (cpu, "CC = R%i;", reg); | 2355 TRACE_INSN (cpu, "CC = R%i;", reg); |
2341 if (INSN_LEN == 8) | 2356 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2342 illegal_instruction_combination (cpu); | 2357 illegal_instruction_combination (cpu); |
2343 SET_CCREG (DREG (reg) != 0); | 2358 SET_CCREG (DREG (reg) != 0); |
2344 } | 2359 } |
2345 else if (op == 3 && reg == 0) | 2360 else if (op == 3 && reg == 0) |
2346 { | 2361 { |
2347 TRACE_INSN (cpu, "CC = !CC;"); | 2362 TRACE_INSN (cpu, "CC = !CC;"); |
2348 if (INSN_LEN == 8) | 2363 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2349 illegal_instruction_combination (cpu); | 2364 illegal_instruction_combination (cpu); |
2350 SET_CCREG (!CCREG); | 2365 SET_CCREG (!CCREG); |
2351 } | 2366 } |
2352 else | 2367 else |
2353 illegal_instruction (cpu); | 2368 illegal_instruction_or_combination (cpu); |
2354 } | 2369 } |
2355 | 2370 |
2356 static void | 2371 static void |
2357 decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0) | 2372 decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0) |
2358 { | 2373 { |
2359 /* CC2stat | 2374 /* CC2stat |
2360 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 2375 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
2361 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............| | 2376 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............| |
2362 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2377 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2363 int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask); | 2378 int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask); |
2364 int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask); | 2379 int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask); |
2365 int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask); | 2380 int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask); |
2366 bu32 pval; | 2381 bu32 pval; |
2367 | 2382 |
2368 const char * const op_names[] = { "", "|", "&", "^" } ; | 2383 const char * const op_names[] = { "", "|", "&", "^" } ; |
2369 | 2384 |
2370 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2stat); | 2385 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2stat); |
2371 TRACE_EXTRACT (cpu, "%s: D:%i op:%i cbit:%i", __func__, D, op, cbit); | 2386 TRACE_EXTRACT (cpu, "%s: D:%i op:%i cbit:%i", __func__, D, op, cbit); |
2372 | 2387 |
2373 TRACE_INSN (cpu, "%s %s= %s;", D ? astat_names[cbit] : "CC", | 2388 TRACE_INSN (cpu, "%s %s= %s;", D ? astat_names[cbit] : "CC", |
2374 op_names[op], D ? "CC" : astat_names[cbit]); | 2389 op_names[op], D ? "CC" : astat_names[cbit]); |
2375 | 2390 |
| 2391 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2392 illegal_instruction_combination (cpu); |
| 2393 |
2376 /* CC = CC; is invalid. */ | 2394 /* CC = CC; is invalid. */ |
2377 if (cbit == 5) | 2395 if (cbit == 5) |
2378 illegal_instruction (cpu); | 2396 illegal_instruction (cpu); |
2379 | 2397 |
2380 if (INSN_LEN == 8) | |
2381 illegal_instruction_combination (cpu); | |
2382 | |
2383 pval = !!(ASTAT & (1 << cbit)); | 2398 pval = !!(ASTAT & (1 << cbit)); |
2384 if (D == 0) | 2399 if (D == 0) |
2385 switch (op) | 2400 switch (op) |
2386 { | 2401 { |
2387 case 0: SET_CCREG (pval); break; | 2402 case 0: SET_CCREG (pval); break; |
2388 case 1: SET_CCREG (CCREG | pval); break; | 2403 case 1: SET_CCREG (CCREG | pval); break; |
2389 case 2: SET_CCREG (CCREG & pval); break; | 2404 case 2: SET_CCREG (CCREG & pval); break; |
2390 case 3: SET_CCREG (CCREG ^ pval); break; | 2405 case 3: SET_CCREG (CCREG ^ pval); break; |
2391 } | 2406 } |
2392 else | 2407 else |
(...skipping 23 matching lines...) Expand all Loading... |
2416 int cond = T ? CCREG : ! CCREG; | 2431 int cond = T ? CCREG : ! CCREG; |
2417 int pcrel = pcrel10 (offset); | 2432 int pcrel = pcrel10 (offset); |
2418 | 2433 |
2419 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_BRCC); | 2434 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_BRCC); |
2420 TRACE_EXTRACT (cpu, "%s: T:%i B:%i offset:%#x", __func__, T, B, offset); | 2435 TRACE_EXTRACT (cpu, "%s: T:%i B:%i offset:%#x", __func__, T, B, offset); |
2421 TRACE_DECODE (cpu, "%s: pcrel10:%#x", __func__, pcrel); | 2436 TRACE_DECODE (cpu, "%s: pcrel10:%#x", __func__, pcrel); |
2422 | 2437 |
2423 TRACE_INSN (cpu, "IF %sCC JUMP %#x%s;", T ? "" : "! ", | 2438 TRACE_INSN (cpu, "IF %sCC JUMP %#x%s;", T ? "" : "! ", |
2424 pcrel, B ? " (bp)" : ""); | 2439 pcrel, B ? " (bp)" : ""); |
2425 | 2440 |
2426 if (INSN_LEN == 8) | 2441 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2427 illegal_instruction_combination (cpu); | 2442 illegal_instruction_combination (cpu); |
2428 | 2443 |
2429 if (cond) | 2444 if (cond) |
2430 { | 2445 { |
2431 bu32 newpc = pc + pcrel; | 2446 bu32 newpc = pc + pcrel; |
2432 TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP"); | 2447 TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP"); |
2433 SET_PCREG (newpc); | 2448 SET_PCREG (newpc); |
2434 BFIN_CPU_STATE.did_jump = true; | 2449 BFIN_CPU_STATE.did_jump = true; |
2435 PROFILE_BRANCH_TAKEN (cpu); | 2450 PROFILE_BRANCH_TAKEN (cpu); |
2436 CYCLE_DELAY = B ? 5 : 9; | 2451 CYCLE_DELAY = B ? 5 : 9; |
(...skipping 15 matching lines...) Expand all Loading... |
2452 int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask); | 2467 int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask); |
2453 int pcrel = pcrel12 (offset); | 2468 int pcrel = pcrel12 (offset); |
2454 bu32 newpc = pc + pcrel; | 2469 bu32 newpc = pc + pcrel; |
2455 | 2470 |
2456 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_UJUMP); | 2471 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_UJUMP); |
2457 TRACE_EXTRACT (cpu, "%s: offset:%#x", __func__, offset); | 2472 TRACE_EXTRACT (cpu, "%s: offset:%#x", __func__, offset); |
2458 TRACE_DECODE (cpu, "%s: pcrel12:%#x", __func__, pcrel); | 2473 TRACE_DECODE (cpu, "%s: pcrel12:%#x", __func__, pcrel); |
2459 | 2474 |
2460 TRACE_INSN (cpu, "JUMP.S %#x;", pcrel); | 2475 TRACE_INSN (cpu, "JUMP.S %#x;", pcrel); |
2461 | 2476 |
2462 if (INSN_LEN == 8) | 2477 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2463 illegal_instruction_combination (cpu); | 2478 illegal_instruction_combination (cpu); |
2464 | 2479 |
2465 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S"); | 2480 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S"); |
2466 | 2481 |
2467 SET_PCREG (newpc); | 2482 SET_PCREG (newpc); |
2468 BFIN_CPU_STATE.did_jump = true; | 2483 BFIN_CPU_STATE.did_jump = true; |
2469 PROFILE_BRANCH_TAKEN (cpu); | 2484 PROFILE_BRANCH_TAKEN (cpu); |
2470 CYCLE_DELAY = 5; | 2485 CYCLE_DELAY = 5; |
2471 } | 2486 } |
2472 | 2487 |
(...skipping 11 matching lines...) Expand all Loading... |
2484 const char *srcreg_name = get_allreg_name (gs, src); | 2499 const char *srcreg_name = get_allreg_name (gs, src); |
2485 const char *dstreg_name = get_allreg_name (gd, dst); | 2500 const char *dstreg_name = get_allreg_name (gd, dst); |
2486 | 2501 |
2487 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_REGMV); | 2502 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_REGMV); |
2488 TRACE_EXTRACT (cpu, "%s: gd:%i gs:%i dst:%i src:%i", | 2503 TRACE_EXTRACT (cpu, "%s: gd:%i gs:%i dst:%i src:%i", |
2489 __func__, gd, gs, dst, src); | 2504 __func__, gd, gs, dst, src); |
2490 TRACE_DECODE (cpu, "%s: dst:%s src:%s", __func__, dstreg_name, srcreg_name); | 2505 TRACE_DECODE (cpu, "%s: dst:%s src:%s", __func__, dstreg_name, srcreg_name); |
2491 | 2506 |
2492 TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name); | 2507 TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name); |
2493 | 2508 |
| 2509 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2510 illegal_instruction_combination (cpu); |
| 2511 |
2494 /* Reserved slots cannot be a src/dst. */ | 2512 /* Reserved slots cannot be a src/dst. */ |
2495 if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst)) | 2513 if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst)) |
2496 goto invalid_move; | 2514 goto invalid_move; |
2497 | 2515 |
2498 /* Standard register moves. */ | 2516 /* Standard register moves. */ |
2499 if ((gs < 2) /* Dregs/Pregs src */ | 2517 if ((gs < 2) /* Dregs/Pregs src */ |
2500 || (gd < 2) /* Dregs/Pregs dst */ | 2518 || (gd < 2) /* Dregs/Pregs dst */ |
2501 || (gs == 4 && src < 4) /* Accumulators src */ | 2519 || (gs == 4 && src < 4) /* Accumulators src */ |
2502 || (gd == 4 && dst < 4 && (gs < 4)) /* Accumulators dst */ | 2520 || (gd == 4 && dst < 4 && (gs < 4)) /* Accumulators dst */ |
2503 || (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) /* EMUDAT src */ | 2521 || (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) /* EMUDAT src */ |
(...skipping 28 matching lines...) Expand all Loading... |
2532 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 2550 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
2533 | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......| | 2551 | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......| |
2534 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2552 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2535 int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask); | 2553 int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask); |
2536 int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask); | 2554 int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask); |
2537 int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask); | 2555 int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask); |
2538 | 2556 |
2539 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op); | 2557 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op); |
2540 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); | 2558 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); |
2541 | 2559 |
| 2560 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2561 illegal_instruction_combination (cpu); |
| 2562 |
2542 if (opc == 0) | 2563 if (opc == 0) |
2543 { | 2564 { |
2544 TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src); | 2565 TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src); |
2545 SET_DREG (dst, ashiftrt (cpu, DREG (dst), DREG (src), 32)); | 2566 SET_DREG (dst, ashiftrt (cpu, DREG (dst), DREG (src), 32)); |
2546 } | 2567 } |
2547 else if (opc == 1) | 2568 else if (opc == 1) |
2548 { | 2569 { |
2549 bu32 val; | 2570 bu32 val; |
2550 TRACE_INSN (cpu, "R%i >>= R%i;", dst, src); | 2571 TRACE_INSN (cpu, "R%i >>= R%i;", dst, src); |
2551 if (DREG (src) <= 0x1F) | 2572 if (DREG (src) <= 0x1F) |
2552 val = lshiftrt (cpu, DREG (dst), DREG (src), 32); | 2573 val = lshiftrt (cpu, DREG (dst), DREG (src), 32); |
2553 else | 2574 else |
2554 val = 0; | 2575 val = 0; |
2555 SET_DREG (dst, val); | 2576 SET_DREG (dst, val); |
2556 } | 2577 } |
2557 else if (opc == 2) | 2578 else if (opc == 2) |
2558 { | 2579 { |
2559 TRACE_INSN (cpu, "R%i <<= R%i;", dst, src); | 2580 TRACE_INSN (cpu, "R%i <<= R%i;", dst, src); |
2560 SET_DREG (dst, lshift (cpu, DREG (dst), DREG (src), 32, 0)); | 2581 SET_DREG (dst, lshift (cpu, DREG (dst), DREG (src), 32, 0, 0)); |
2561 } | 2582 } |
2562 else if (opc == 3) | 2583 else if (opc == 3) |
2563 { | 2584 { |
2564 TRACE_INSN (cpu, "R%i *= R%i;", dst, src); | 2585 TRACE_INSN (cpu, "R%i *= R%i;", dst, src); |
2565 SET_DREG (dst, DREG (dst) * DREG (src)); | 2586 SET_DREG (dst, DREG (dst) * DREG (src)); |
2566 CYCLE_DELAY = 3; | 2587 CYCLE_DELAY = 3; |
2567 } | 2588 } |
2568 else if (opc == 4) | 2589 else if (opc == 4) |
2569 { | 2590 { |
2570 TRACE_INSN (cpu, "R%i = (R%i + R%i) << 1;", dst, dst, src); | 2591 TRACE_INSN (cpu, "R%i = (R%i + R%i) << 1;", dst, dst, src); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2640 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2661 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2641 int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask); | 2662 int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask); |
2642 int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask); | 2663 int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask); |
2643 int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask); | 2664 int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask); |
2644 const char *src_name = get_preg_name (src); | 2665 const char *src_name = get_preg_name (src); |
2645 const char *dst_name = get_preg_name (dst); | 2666 const char *dst_name = get_preg_name (dst); |
2646 | 2667 |
2647 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op); | 2668 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op); |
2648 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); | 2669 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); |
2649 | 2670 |
| 2671 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2672 illegal_instruction_combination (cpu); |
| 2673 |
2650 if (opc == 0) | 2674 if (opc == 0) |
2651 { | 2675 { |
2652 TRACE_INSN (cpu, "%s -= %s", dst_name, src_name); | 2676 TRACE_INSN (cpu, "%s -= %s", dst_name, src_name); |
2653 SET_PREG (dst, PREG (dst) - PREG (src)); | 2677 SET_PREG (dst, PREG (dst) - PREG (src)); |
2654 } | 2678 } |
2655 else if (opc == 1) | 2679 else if (opc == 1) |
2656 { | 2680 { |
2657 TRACE_INSN (cpu, "%s = %s << 2", dst_name, src_name); | 2681 TRACE_INSN (cpu, "%s = %s << 2", dst_name, src_name); |
2658 SET_PREG (dst, PREG (src) << 2); | 2682 SET_PREG (dst, PREG (src) << 2); |
2659 } | 2683 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 int uimm = uimm5 (src); | 2723 int uimm = uimm5 (src); |
2700 const char *uimm_str = uimm5_str (uimm); | 2724 const char *uimm_str = uimm5_str (uimm); |
2701 | 2725 |
2702 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LOGI2op); | 2726 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LOGI2op); |
2703 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); | 2727 TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); |
2704 TRACE_DECODE (cpu, "%s: uimm5:%#x", __func__, uimm); | 2728 TRACE_DECODE (cpu, "%s: uimm5:%#x", __func__, uimm); |
2705 | 2729 |
2706 if (opc == 0) | 2730 if (opc == 0) |
2707 { | 2731 { |
2708 TRACE_INSN (cpu, "CC = ! BITTST (R%i, %s);", dst, uimm_str); | 2732 TRACE_INSN (cpu, "CC = ! BITTST (R%i, %s);", dst, uimm_str); |
2709 if (INSN_LEN == 8) | 2733 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2710 illegal_instruction_combination (cpu); | 2734 illegal_instruction_combination (cpu); |
2711 SET_CCREG ((~DREG (dst) >> uimm) & 1); | 2735 SET_CCREG ((~DREG (dst) >> uimm) & 1); |
2712 } | 2736 } |
2713 else if (opc == 1) | 2737 else if (opc == 1) |
2714 { | 2738 { |
2715 TRACE_INSN (cpu, "CC = BITTST (R%i, %s);", dst, uimm_str); | 2739 TRACE_INSN (cpu, "CC = BITTST (R%i, %s);", dst, uimm_str); |
2716 if (INSN_LEN == 8) | 2740 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2717 illegal_instruction_combination (cpu); | 2741 illegal_instruction_combination (cpu); |
2718 SET_CCREG ((DREG (dst) >> uimm) & 1); | 2742 SET_CCREG ((DREG (dst) >> uimm) & 1); |
2719 } | 2743 } |
2720 else if (opc == 2) | 2744 else if (opc == 2) |
2721 { | 2745 { |
2722 TRACE_INSN (cpu, "BITSET (R%i, %s);", dst, uimm_str); | 2746 TRACE_INSN (cpu, "BITSET (R%i, %s);", dst, uimm_str); |
2723 if (INSN_LEN == 8) | 2747 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2724 illegal_instruction_combination (cpu); | 2748 illegal_instruction_combination (cpu); |
2725 SET_DREG (dst, DREG (dst) | (1 << uimm)); | 2749 SET_DREG (dst, DREG (dst) | (1 << uimm)); |
2726 setflags_logical (cpu, DREG (dst)); | 2750 setflags_logical (cpu, DREG (dst)); |
2727 } | 2751 } |
2728 else if (opc == 3) | 2752 else if (opc == 3) |
2729 { | 2753 { |
2730 TRACE_INSN (cpu, "BITTGL (R%i, %s);", dst, uimm_str); | 2754 TRACE_INSN (cpu, "BITTGL (R%i, %s);", dst, uimm_str); |
2731 if (INSN_LEN == 8) | 2755 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2732 illegal_instruction_combination (cpu); | 2756 illegal_instruction_combination (cpu); |
2733 SET_DREG (dst, DREG (dst) ^ (1 << uimm)); | 2757 SET_DREG (dst, DREG (dst) ^ (1 << uimm)); |
2734 setflags_logical (cpu, DREG (dst)); | 2758 setflags_logical (cpu, DREG (dst)); |
2735 } | 2759 } |
2736 else if (opc == 4) | 2760 else if (opc == 4) |
2737 { | 2761 { |
2738 TRACE_INSN (cpu, "BITCLR (R%i, %s);", dst, uimm_str); | 2762 TRACE_INSN (cpu, "BITCLR (R%i, %s);", dst, uimm_str); |
2739 if (INSN_LEN == 8) | 2763 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2740 illegal_instruction_combination (cpu); | 2764 illegal_instruction_combination (cpu); |
2741 SET_DREG (dst, DREG (dst) & ~(1 << uimm)); | 2765 SET_DREG (dst, DREG (dst) & ~(1 << uimm)); |
2742 setflags_logical (cpu, DREG (dst)); | 2766 setflags_logical (cpu, DREG (dst)); |
2743 } | 2767 } |
2744 else if (opc == 5) | 2768 else if (opc == 5) |
2745 { | 2769 { |
2746 TRACE_INSN (cpu, "R%i >>>= %s;", dst, uimm_str); | 2770 TRACE_INSN (cpu, "R%i >>>= %s;", dst, uimm_str); |
2747 if (INSN_LEN == 8) | 2771 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2748 illegal_instruction_combination (cpu); | 2772 illegal_instruction_combination (cpu); |
2749 SET_DREG (dst, ashiftrt (cpu, DREG (dst), uimm, 32)); | 2773 SET_DREG (dst, ashiftrt (cpu, DREG (dst), uimm, 32)); |
2750 } | 2774 } |
2751 else if (opc == 6) | 2775 else if (opc == 6) |
2752 { | 2776 { |
2753 TRACE_INSN (cpu, "R%i >>= %s;", dst, uimm_str); | 2777 TRACE_INSN (cpu, "R%i >>= %s;", dst, uimm_str); |
2754 if (INSN_LEN == 8) | 2778 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2755 illegal_instruction_combination (cpu); | 2779 illegal_instruction_combination (cpu); |
2756 SET_DREG (dst, lshiftrt (cpu, DREG (dst), uimm, 32)); | 2780 SET_DREG (dst, lshiftrt (cpu, DREG (dst), uimm, 32)); |
2757 } | 2781 } |
2758 else if (opc == 7) | 2782 else if (opc == 7) |
2759 { | 2783 { |
2760 TRACE_INSN (cpu, "R%i <<= %s;", dst, uimm_str); | 2784 TRACE_INSN (cpu, "R%i <<= %s;", dst, uimm_str); |
2761 if (INSN_LEN == 8) | 2785 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
2762 illegal_instruction_combination (cpu); | 2786 illegal_instruction_combination (cpu); |
2763 SET_DREG (dst, lshift (cpu, DREG (dst), uimm, 32, 0)); | 2787 SET_DREG (dst, lshift (cpu, DREG (dst), uimm, 32, 0, 0)); |
2764 } | 2788 } |
2765 } | 2789 } |
2766 | 2790 |
2767 static void | 2791 static void |
2768 decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0) | 2792 decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0) |
2769 { | 2793 { |
2770 /* COMP3op | 2794 /* COMP3op |
2771 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 2795 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
2772 | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......| | 2796 | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......| |
2773 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2797 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2774 int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask); | 2798 int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask); |
2775 int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask); | 2799 int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask); |
2776 int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask); | 2800 int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask); |
2777 int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask); | 2801 int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask); |
2778 | 2802 |
2779 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMP3op); | 2803 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMP3op); |
2780 TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i", | 2804 TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i", |
2781 __func__, opc, dst, src1, src0); | 2805 __func__, opc, dst, src1, src0); |
2782 | 2806 |
| 2807 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2808 illegal_instruction_combination (cpu); |
| 2809 |
2783 if (opc == 0) | 2810 if (opc == 0) |
2784 { | 2811 { |
2785 TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1); | 2812 TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1); |
2786 SET_DREG (dst, add32 (cpu, DREG (src0), DREG (src1), 1, 0)); | 2813 SET_DREG (dst, add32 (cpu, DREG (src0), DREG (src1), 1, 0)); |
2787 } | 2814 } |
2788 else if (opc == 1) | 2815 else if (opc == 1) |
2789 { | 2816 { |
2790 TRACE_INSN (cpu, "R%i = R%i - R%i;", dst, src0, src1); | 2817 TRACE_INSN (cpu, "R%i = R%i - R%i;", dst, src0, src1); |
2791 SET_DREG (dst, sub32 (cpu, DREG (src0), DREG (src1), 1, 0, 0)); | 2818 SET_DREG (dst, sub32 (cpu, DREG (src0), DREG (src1), 1, 0, 0)); |
2792 } | 2819 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2863 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2837 int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask); | 2864 int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask); |
2838 int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask); | 2865 int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask); |
2839 int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask); | 2866 int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask); |
2840 int imm = imm7 (src); | 2867 int imm = imm7 (src); |
2841 | 2868 |
2842 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opD); | 2869 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opD); |
2843 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); | 2870 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); |
2844 TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm); | 2871 TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm); |
2845 | 2872 |
| 2873 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2874 illegal_instruction_combination (cpu); |
| 2875 |
2846 if (op == 0) | 2876 if (op == 0) |
2847 { | 2877 { |
2848 TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm)); | 2878 TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm)); |
2849 SET_DREG (dst, imm); | 2879 SET_DREG (dst, imm); |
2850 } | 2880 } |
2851 else if (op == 1) | 2881 else if (op == 1) |
2852 { | 2882 { |
2853 TRACE_INSN (cpu, "R%i += %s;", dst, imm7_str (imm)); | 2883 TRACE_INSN (cpu, "R%i += %s;", dst, imm7_str (imm)); |
2854 SET_DREG (dst, add32 (cpu, DREG (dst), imm, 1, 0)); | 2884 SET_DREG (dst, add32 (cpu, DREG (dst), imm, 1, 0)); |
2855 } | 2885 } |
2856 } | 2886 } |
2857 | 2887 |
2858 static void | 2888 static void |
2859 decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0) | 2889 decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0) |
2860 { | 2890 { |
2861 /* COMPI2opP | 2891 /* COMPI2opP |
2862 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 2892 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
2863 | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......| | 2893 | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......| |
2864 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 2894 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
2865 int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask); | 2895 int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask); |
2866 int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask); | 2896 int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask); |
2867 int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask); | 2897 int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask); |
2868 int imm = imm7 (src); | 2898 int imm = imm7 (src); |
2869 const char *dst_name = get_preg_name (dst); | 2899 const char *dst_name = get_preg_name (dst); |
2870 | 2900 |
2871 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opP); | 2901 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opP); |
2872 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); | 2902 TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); |
2873 TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm); | 2903 TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm); |
2874 | 2904 |
| 2905 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
| 2906 illegal_instruction_combination (cpu); |
| 2907 |
2875 if (op == 0) | 2908 if (op == 0) |
2876 { | 2909 { |
2877 TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm)); | 2910 TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm)); |
2878 SET_PREG (dst, imm); | 2911 SET_PREG (dst, imm); |
2879 } | 2912 } |
2880 else if (op == 1) | 2913 else if (op == 1) |
2881 { | 2914 { |
2882 TRACE_INSN (cpu, "%s += %s;", dst_name, imm7_str (imm)); | 2915 TRACE_INSN (cpu, "%s += %s;", dst_name, imm7_str (imm)); |
2883 SET_PREG (dst, PREG (dst) + imm); | 2916 SET_PREG (dst, PREG (dst) + imm); |
2884 } | 2917 } |
(...skipping 12 matching lines...) Expand all Loading... |
2897 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask); | 2930 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask); |
2898 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask); | 2931 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask); |
2899 const char *ptr_name = get_preg_name (ptr); | 2932 const char *ptr_name = get_preg_name (ptr); |
2900 const char *idx_name = get_preg_name (idx); | 2933 const char *idx_name = get_preg_name (idx); |
2901 bu32 addr, val; | 2934 bu32 addr, val; |
2902 | 2935 |
2903 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTpmod); | 2936 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTpmod); |
2904 TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i", | 2937 TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i", |
2905 __func__, W, aop, reg, idx, ptr); | 2938 __func__, W, aop, reg, idx, ptr); |
2906 | 2939 |
| 2940 if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
| 2941 illegal_instruction_combination (cpu); |
| 2942 |
2907 if (aop == 1 && W == 0 && idx == ptr) | 2943 if (aop == 1 && W == 0 && idx == ptr) |
2908 { | 2944 { |
2909 TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name); | 2945 TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name); |
2910 addr = PREG (ptr); | 2946 addr = PREG (ptr); |
2911 val = GET_WORD (addr); | 2947 val = GET_WORD (addr); |
2912 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val); | 2948 STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val); |
2913 } | 2949 } |
2914 else if (aop == 2 && W == 0 && idx == ptr) | 2950 else if (aop == 2 && W == 0 && idx == ptr) |
2915 { | 2951 { |
2916 TRACE_INSN (cpu, "R%i.H = W[%s];", reg, ptr_name); | 2952 TRACE_INSN (cpu, "R%i.H = W[%s];", reg, ptr_name); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2993 } | 3029 } |
2994 else if (aop == 2 && W == 1) | 3030 else if (aop == 2 && W == 1) |
2995 { | 3031 { |
2996 TRACE_INSN (cpu, "W[%s ++ %s] = R%i.H;", ptr_name, idx_name, reg); | 3032 TRACE_INSN (cpu, "W[%s ++ %s] = R%i.H;", ptr_name, idx_name, reg); |
2997 addr = PREG (ptr); | 3033 addr = PREG (ptr); |
2998 PUT_WORD (addr, DREG (reg) >> 16); | 3034 PUT_WORD (addr, DREG (reg) >> 16); |
2999 if (ptr != idx) | 3035 if (ptr != idx) |
3000 STORE (PREG (ptr), addr + PREG (idx)); | 3036 STORE (PREG (ptr), addr + PREG (idx)); |
3001 } | 3037 } |
3002 else | 3038 else |
3003 illegal_instruction (cpu); | 3039 illegal_instruction_or_combination (cpu); |
3004 } | 3040 } |
3005 | 3041 |
3006 static void | 3042 static void |
3007 decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0) | 3043 decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0) |
3008 { | 3044 { |
3009 /* dagMODim | 3045 /* dagMODim |
3010 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 3046 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
3011 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....| | 3047 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....| |
3012 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 3048 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
3013 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask); | 3049 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask); |
3014 int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask); | 3050 int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask); |
3015 int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask); | 3051 int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask); |
3016 int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask); | 3052 int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask); |
3017 | 3053 |
3018 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim); | 3054 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim); |
3019 TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i); | 3055 TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i); |
3020 | 3056 |
| 3057 if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
| 3058 illegal_instruction_combination (cpu); |
| 3059 |
3021 if (op == 0 && br == 1) | 3060 if (op == 0 && br == 1) |
3022 { | 3061 { |
3023 TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m); | 3062 TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m); |
3024 SET_IREG (i, add_brev (IREG (i), MREG (m))); | 3063 SET_IREG (i, add_brev (IREG (i), MREG (m))); |
3025 } | 3064 } |
3026 else if (op == 0) | 3065 else if (op == 0) |
3027 { | 3066 { |
3028 TRACE_INSN (cpu, "I%i += M%i;", i, m); | 3067 TRACE_INSN (cpu, "I%i += M%i;", i, m); |
3029 dagadd (cpu, i, MREG (m)); | 3068 dagadd (cpu, i, MREG (m)); |
3030 } | 3069 } |
3031 else if (op == 1 && br == 0) | 3070 else if (op == 1 && br == 0) |
3032 { | 3071 { |
3033 TRACE_INSN (cpu, "I%i -= M%i;", i, m); | 3072 TRACE_INSN (cpu, "I%i -= M%i;", i, m); |
3034 dagsub (cpu, i, MREG (m)); | 3073 dagsub (cpu, i, MREG (m)); |
3035 } | 3074 } |
3036 else | 3075 else |
3037 illegal_instruction (cpu); | 3076 illegal_instruction_or_combination (cpu); |
3038 } | 3077 } |
3039 | 3078 |
3040 static void | 3079 static void |
3041 decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0) | 3080 decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0) |
3042 { | 3081 { |
3043 /* dagMODik | 3082 /* dagMODik |
3044 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 3083 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
3045 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....| | 3084 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....| |
3046 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 3085 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
3047 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask); | 3086 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask); |
3048 int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask); | 3087 int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask); |
3049 | 3088 |
3050 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik); | 3089 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik); |
3051 TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i); | 3090 TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i); |
3052 | 3091 |
| 3092 if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
| 3093 illegal_instruction_combination (cpu); |
| 3094 |
3053 if (op == 0) | 3095 if (op == 0) |
3054 { | 3096 { |
3055 TRACE_INSN (cpu, "I%i += 2;", i); | 3097 TRACE_INSN (cpu, "I%i += 2;", i); |
3056 dagadd (cpu, i, 2); | 3098 dagadd (cpu, i, 2); |
3057 } | 3099 } |
3058 else if (op == 1) | 3100 else if (op == 1) |
3059 { | 3101 { |
3060 TRACE_INSN (cpu, "I%i -= 2;", i); | 3102 TRACE_INSN (cpu, "I%i -= 2;", i); |
3061 dagsub (cpu, i, 2); | 3103 dagsub (cpu, i, 2); |
3062 } | 3104 } |
3063 else if (op == 2) | 3105 else if (op == 2) |
3064 { | 3106 { |
3065 TRACE_INSN (cpu, "I%i += 4;", i); | 3107 TRACE_INSN (cpu, "I%i += 4;", i); |
3066 dagadd (cpu, i, 4); | 3108 dagadd (cpu, i, 4); |
3067 } | 3109 } |
3068 else if (op == 3) | 3110 else if (op == 3) |
3069 { | 3111 { |
3070 TRACE_INSN (cpu, "I%i -= 4;", i); | 3112 TRACE_INSN (cpu, "I%i -= 4;", i); |
3071 dagsub (cpu, i, 4); | 3113 dagsub (cpu, i, 4); |
3072 } | 3114 } |
3073 else | 3115 else |
3074 illegal_instruction (cpu); | 3116 illegal_instruction_or_combination (cpu); |
3075 } | 3117 } |
3076 | 3118 |
3077 static void | 3119 static void |
3078 decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0) | 3120 decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0) |
3079 { | 3121 { |
3080 /* dspLDST | 3122 /* dspLDST |
3081 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 3123 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
3082 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......| | 3124 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......| |
3083 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 3125 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
3084 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask); | 3126 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3227 STORE (DREG (reg), GET_LONG (addr)); | 3269 STORE (DREG (reg), GET_LONG (addr)); |
3228 } | 3270 } |
3229 else if (aop == 3 && W == 1) | 3271 else if (aop == 3 && W == 1) |
3230 { | 3272 { |
3231 TRACE_INSN (cpu, "[I%i ++ M%i] = R%i;", i, m, reg); | 3273 TRACE_INSN (cpu, "[I%i ++ M%i] = R%i;", i, m, reg); |
3232 addr = IREG (i); | 3274 addr = IREG (i); |
3233 dagadd (cpu, i, MREG (m)); | 3275 dagadd (cpu, i, MREG (m)); |
3234 PUT_LONG (addr, DREG (reg)); | 3276 PUT_LONG (addr, DREG (reg)); |
3235 } | 3277 } |
3236 else | 3278 else |
3237 illegal_instruction (cpu); | 3279 illegal_instruction_or_combination (cpu); |
3238 } | 3280 } |
3239 | 3281 |
3240 static void | 3282 static void |
3241 decode_LDST_0 (SIM_CPU *cpu, bu16 iw0) | 3283 decode_LDST_0 (SIM_CPU *cpu, bu16 iw0) |
3242 { | 3284 { |
3243 /* LDST | 3285 /* LDST |
3244 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 3286 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
3245 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......| | 3287 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......| |
3246 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 3288 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
3247 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask); | 3289 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask); |
3248 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask); | 3290 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask); |
3249 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask); | 3291 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask); |
3250 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask); | 3292 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask); |
3251 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask); | 3293 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask); |
3252 int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask); | 3294 int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask); |
3253 const char * const posts[] = { "++", "--", "" }; | 3295 const char * const posts[] = { "++", "--", "" }; |
3254 const char *post = posts[aop]; | 3296 const char *post = posts[aop]; |
3255 const char *ptr_name = get_preg_name (ptr); | 3297 const char *ptr_name = get_preg_name (ptr); |
3256 | 3298 |
3257 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDST); | 3299 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDST); |
3258 TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i", | 3300 TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i", |
3259 __func__, sz, W, aop, Z, ptr, reg); | 3301 __func__, sz, W, aop, Z, ptr, reg); |
3260 | 3302 |
3261 if (aop == 3) | 3303 if (aop == 3 || PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
3262 illegal_instruction (cpu); | 3304 illegal_instruction_or_combination (cpu); |
3263 | 3305 |
3264 if (W == 0) | 3306 if (W == 0) |
3265 { | 3307 { |
3266 if (sz == 0 && Z == 0) | 3308 if (sz == 0 && Z == 0) |
3267 { | 3309 { |
3268 TRACE_INSN (cpu, "R%i = [%s%s];", reg, ptr_name, post); | 3310 TRACE_INSN (cpu, "R%i = [%s%s];", reg, ptr_name, post); |
3269 SET_DREG (reg, GET_LONG (PREG (ptr))); | 3311 SET_DREG (reg, GET_LONG (PREG (ptr))); |
3270 } | 3312 } |
3271 else if (sz == 0 && Z == 1) | 3313 else if (sz == 0 && Z == 1) |
3272 { | 3314 { |
(...skipping 16 matching lines...) Expand all Loading... |
3289 { | 3331 { |
3290 TRACE_INSN (cpu, "R%i = B[%s%s] (Z);", reg, ptr_name, post); | 3332 TRACE_INSN (cpu, "R%i = B[%s%s] (Z);", reg, ptr_name, post); |
3291 SET_DREG (reg, GET_BYTE (PREG (ptr))); | 3333 SET_DREG (reg, GET_BYTE (PREG (ptr))); |
3292 } | 3334 } |
3293 else if (sz == 2 && Z == 1) | 3335 else if (sz == 2 && Z == 1) |
3294 { | 3336 { |
3295 TRACE_INSN (cpu, "R%i = B[%s%s] (X);", reg, ptr_name, post); | 3337 TRACE_INSN (cpu, "R%i = B[%s%s] (X);", reg, ptr_name, post); |
3296 SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr))); | 3338 SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr))); |
3297 } | 3339 } |
3298 else | 3340 else |
3299 » illegal_instruction (cpu); | 3341 » illegal_instruction_or_combination (cpu); |
3300 } | 3342 } |
3301 else | 3343 else |
3302 { | 3344 { |
3303 if (sz == 0 && Z == 0) | 3345 if (sz == 0 && Z == 0) |
3304 { | 3346 { |
3305 TRACE_INSN (cpu, "[%s%s] = R%i;", ptr_name, post, reg); | 3347 TRACE_INSN (cpu, "[%s%s] = R%i;", ptr_name, post, reg); |
3306 PUT_LONG (PREG (ptr), DREG (reg)); | 3348 PUT_LONG (PREG (ptr), DREG (reg)); |
3307 } | 3349 } |
3308 else if (sz == 0 && Z == 1) | 3350 else if (sz == 0 && Z == 1) |
3309 { | 3351 { |
3310 TRACE_INSN (cpu, "[%s%s] = %s;", ptr_name, post, get_preg_name (reg)); | 3352 TRACE_INSN (cpu, "[%s%s] = %s;", ptr_name, post, get_preg_name (reg)); |
3311 PUT_LONG (PREG (ptr), PREG (reg)); | 3353 PUT_LONG (PREG (ptr), PREG (reg)); |
3312 } | 3354 } |
3313 else if (sz == 1 && Z == 0) | 3355 else if (sz == 1 && Z == 0) |
3314 { | 3356 { |
3315 TRACE_INSN (cpu, "W[%s%s] = R%i;", ptr_name, post, reg); | 3357 TRACE_INSN (cpu, "W[%s%s] = R%i;", ptr_name, post, reg); |
3316 PUT_WORD (PREG (ptr), DREG (reg)); | 3358 PUT_WORD (PREG (ptr), DREG (reg)); |
3317 } | 3359 } |
3318 else if (sz == 2 && Z == 0) | 3360 else if (sz == 2 && Z == 0) |
3319 { | 3361 { |
3320 TRACE_INSN (cpu, "B[%s%s] = R%i;", ptr_name, post, reg); | 3362 TRACE_INSN (cpu, "B[%s%s] = R%i;", ptr_name, post, reg); |
3321 PUT_BYTE (PREG (ptr), DREG (reg)); | 3363 PUT_BYTE (PREG (ptr), DREG (reg)); |
3322 } | 3364 } |
3323 else | 3365 else |
3324 » illegal_instruction (cpu); | 3366 » illegal_instruction_or_combination (cpu); |
3325 } | 3367 } |
3326 | 3368 |
3327 if (aop == 0) | 3369 if (aop == 0) |
3328 SET_PREG (ptr, PREG (ptr) + (1 << (2 - sz))); | 3370 SET_PREG (ptr, PREG (ptr) + (1 << (2 - sz))); |
3329 if (aop == 1) | 3371 if (aop == 1) |
3330 SET_PREG (ptr, PREG (ptr) - (1 << (2 - sz))); | 3372 SET_PREG (ptr, PREG (ptr) - (1 << (2 - sz))); |
3331 } | 3373 } |
3332 | 3374 |
3333 static void | 3375 static void |
3334 decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0) | 3376 decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0) |
(...skipping 11 matching lines...) Expand all Loading... |
3346 bu32 imm = negimm5s4 (offset); | 3388 bu32 imm = negimm5s4 (offset); |
3347 bu32 ea = FPREG + imm; | 3389 bu32 ea = FPREG + imm; |
3348 const char *imm_str = negimm5s4_str (offset); | 3390 const char *imm_str = negimm5s4_str (offset); |
3349 const char *reg_name = get_allreg_name (grp, reg); | 3391 const char *reg_name = get_allreg_name (grp, reg); |
3350 | 3392 |
3351 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTiiFP); | 3393 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTiiFP); |
3352 TRACE_EXTRACT (cpu, "%s: W:%i offset:%#x grp:%i reg:%i", __func__, | 3394 TRACE_EXTRACT (cpu, "%s: W:%i offset:%#x grp:%i reg:%i", __func__, |
3353 W, offset, grp, reg); | 3395 W, offset, grp, reg); |
3354 TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm); | 3396 TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm); |
3355 | 3397 |
| 3398 if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
| 3399 illegal_instruction_or_combination (cpu); |
| 3400 |
3356 if (W == 0) | 3401 if (W == 0) |
3357 { | 3402 { |
3358 TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str); | 3403 TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str); |
3359 reg_write (cpu, grp, reg, GET_LONG (ea)); | 3404 reg_write (cpu, grp, reg, GET_LONG (ea)); |
3360 } | 3405 } |
3361 else | 3406 else |
3362 { | 3407 { |
3363 TRACE_INSN (cpu, "[FP + %s] = %s;", imm_str, reg_name); | 3408 TRACE_INSN (cpu, "[FP + %s] = %s;", imm_str, reg_name); |
3364 PUT_LONG (ea, reg_read (cpu, grp, reg)); | 3409 PUT_LONG (ea, reg_read (cpu, grp, reg)); |
3365 } | 3410 } |
(...skipping 20 matching lines...) Expand all Loading... |
3386 __func__, W, op, offset, ptr, reg); | 3431 __func__, W, op, offset, ptr, reg); |
3387 | 3432 |
3388 if (op == 0 || op == 3) | 3433 if (op == 0 || op == 3) |
3389 imm = uimm4s4 (offset), imm_str = uimm4s4_str (offset); | 3434 imm = uimm4s4 (offset), imm_str = uimm4s4_str (offset); |
3390 else | 3435 else |
3391 imm = uimm4s2 (offset), imm_str = uimm4s2_str (offset); | 3436 imm = uimm4s2 (offset), imm_str = uimm4s2_str (offset); |
3392 ea = PREG (ptr) + imm; | 3437 ea = PREG (ptr) + imm; |
3393 | 3438 |
3394 TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm); | 3439 TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm); |
3395 | 3440 |
| 3441 if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) |
| 3442 illegal_instruction_combination (cpu); |
| 3443 |
3396 if (W == 1 && op == 2) | 3444 if (W == 1 && op == 2) |
3397 illegal_instruction (cpu); | 3445 illegal_instruction (cpu); |
3398 | 3446 |
3399 if (W == 0) | 3447 if (W == 0) |
3400 { | 3448 { |
3401 if (op == 0) | 3449 if (op == 0) |
3402 { | 3450 { |
3403 TRACE_INSN (cpu, "R%i = [%s + %s];", reg, ptr_name, imm_str); | 3451 TRACE_INSN (cpu, "R%i = [%s + %s];", reg, ptr_name, imm_str); |
3404 SET_DREG (reg, GET_LONG (ea)); | 3452 SET_DREG (reg, GET_LONG (ea)); |
3405 } | 3453 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3459 | 3507 |
3460 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LoopSetup); | 3508 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LoopSetup); |
3461 TRACE_EXTRACT (cpu, "%s: rop:%i c:%i soffset:%i reg:%i eoffset:%i", | 3509 TRACE_EXTRACT (cpu, "%s: rop:%i c:%i soffset:%i reg:%i eoffset:%i", |
3462 __func__, rop, c, soffset, reg, eoffset); | 3510 __func__, rop, c, soffset, reg, eoffset); |
3463 TRACE_DECODE (cpu, "%s: s_pcrel4:%#x e_lppcrel10:%#x", | 3511 TRACE_DECODE (cpu, "%s: s_pcrel4:%#x e_lppcrel10:%#x", |
3464 __func__, spcrel, epcrel); | 3512 __func__, spcrel, epcrel); |
3465 | 3513 |
3466 if (reg > 7) | 3514 if (reg > 7) |
3467 illegal_instruction (cpu); | 3515 illegal_instruction (cpu); |
3468 | 3516 |
3469 if (INSN_LEN == 8) | 3517 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
3470 illegal_instruction_combination (cpu); | 3518 illegal_instruction_combination (cpu); |
3471 | 3519 |
3472 if (rop == 0) | 3520 if (rop == 0) |
3473 { | 3521 { |
3474 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i;", spcrel, epcrel, c); | 3522 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i;", spcrel, epcrel, c); |
3475 } | 3523 } |
3476 else if (rop == 1 && reg <= 7) | 3524 else if (rop == 1 && reg <= 7) |
3477 { | 3525 { |
3478 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s;", | 3526 TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s;", |
3479 spcrel, epcrel, c, get_preg_name (reg)); | 3527 spcrel, epcrel, c, get_preg_name (reg)); |
(...skipping 27 matching lines...) Expand all Loading... |
3507 int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask); | 3555 int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask); |
3508 int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask); | 3556 int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask); |
3509 bu32 val; | 3557 bu32 val; |
3510 const char *val_str; | 3558 const char *val_str; |
3511 const char *reg_name = get_allreg_name (grp, reg); | 3559 const char *reg_name = get_allreg_name (grp, reg); |
3512 | 3560 |
3513 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDIMMhalf); | 3561 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDIMMhalf); |
3514 TRACE_EXTRACT (cpu, "%s: Z:%i H:%i S:%i grp:%i reg:%i hword:%#x", | 3562 TRACE_EXTRACT (cpu, "%s: Z:%i H:%i S:%i grp:%i reg:%i hword:%#x", |
3515 __func__, Z, H, S, grp, reg, hword); | 3563 __func__, Z, H, S, grp, reg, hword); |
3516 | 3564 |
3517 if (INSN_LEN == 8) | 3565 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
3518 illegal_instruction_combination (cpu); | 3566 illegal_instruction_combination (cpu); |
3519 | 3567 |
3520 if (S == 1) | 3568 if (S == 1) |
3521 val = imm16 (hword), val_str = imm16_str (hword); | 3569 val = imm16 (hword), val_str = imm16_str (hword); |
3522 else | 3570 else |
3523 val = luimm16 (hword), val_str = luimm16_str (hword); | 3571 val = luimm16 (hword), val_str = luimm16_str (hword); |
3524 | 3572 |
3525 if (H == 0 && S == 1 && Z == 0) | 3573 if (H == 0 && S == 1 && Z == 0) |
3526 { | 3574 { |
3527 TRACE_INSN (cpu, "%s = %s (X);", reg_name, val_str); | 3575 TRACE_INSN (cpu, "%s = %s (X);", reg_name, val_str); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3559 int msw = ((iw0 >> 0) & 0xff); | 3607 int msw = ((iw0 >> 0) & 0xff); |
3560 int pcrel = pcrel24 ((msw << 16) | lsw); | 3608 int pcrel = pcrel24 ((msw << 16) | lsw); |
3561 bu32 newpc = pc + pcrel; | 3609 bu32 newpc = pc + pcrel; |
3562 | 3610 |
3563 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CALLa); | 3611 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CALLa); |
3564 TRACE_EXTRACT (cpu, "%s: S:%i msw:%#x lsw:%#x", __func__, S, msw, lsw); | 3612 TRACE_EXTRACT (cpu, "%s: S:%i msw:%#x lsw:%#x", __func__, S, msw, lsw); |
3565 TRACE_DECODE (cpu, "%s: pcrel24:%#x", __func__, pcrel); | 3613 TRACE_DECODE (cpu, "%s: pcrel24:%#x", __func__, pcrel); |
3566 | 3614 |
3567 TRACE_INSN (cpu, "%s %#x;", S ? "CALL" : "JUMP.L", pcrel); | 3615 TRACE_INSN (cpu, "%s %#x;", S ? "CALL" : "JUMP.L", pcrel); |
3568 | 3616 |
3569 if (INSN_LEN == 8) | 3617 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
3570 illegal_instruction_combination (cpu); | 3618 illegal_instruction_combination (cpu); |
3571 | 3619 |
3572 if (S == 1) | 3620 if (S == 1) |
3573 { | 3621 { |
3574 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL"); | 3622 TRACE_BRANCH (cpu, pc, newpc, -1, "CALL"); |
3575 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4)); | 3623 SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4)); |
3576 } | 3624 } |
3577 else | 3625 else |
3578 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L"); | 3626 TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L"); |
3579 | 3627 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3693 bu32 sp; | 3741 bu32 sp; |
3694 | 3742 |
3695 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_linkage); | 3743 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_linkage); |
3696 TRACE_EXTRACT (cpu, "%s: R:%i framesize:%#x", __func__, R, framesize); | 3744 TRACE_EXTRACT (cpu, "%s: R:%i framesize:%#x", __func__, R, framesize); |
3697 | 3745 |
3698 if (R == 0) | 3746 if (R == 0) |
3699 { | 3747 { |
3700 int size = uimm16s4 (framesize); | 3748 int size = uimm16s4 (framesize); |
3701 sp = SPREG; | 3749 sp = SPREG; |
3702 TRACE_INSN (cpu, "LINK %s;", uimm16s4_str (framesize)); | 3750 TRACE_INSN (cpu, "LINK %s;", uimm16s4_str (framesize)); |
3703 if (INSN_LEN == 8) | 3751 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
3704 illegal_instruction_combination (cpu); | 3752 illegal_instruction_combination (cpu); |
3705 sp -= 4; | 3753 sp -= 4; |
3706 PUT_LONG (sp, RETSREG); | 3754 PUT_LONG (sp, RETSREG); |
3707 sp -= 4; | 3755 sp -= 4; |
3708 PUT_LONG (sp, FPREG); | 3756 PUT_LONG (sp, FPREG); |
3709 SET_FPREG (sp); | 3757 SET_FPREG (sp); |
3710 sp -= size; | 3758 sp -= size; |
3711 CYCLE_DELAY = 3; | 3759 CYCLE_DELAY = 3; |
3712 } | 3760 } |
3713 else | 3761 else |
3714 { | 3762 { |
3715 /* Restore SP from FP. */ | 3763 /* Restore SP from FP. */ |
3716 sp = FPREG; | 3764 sp = FPREG; |
3717 TRACE_INSN (cpu, "UNLINK;"); | 3765 TRACE_INSN (cpu, "UNLINK;"); |
3718 if (INSN_LEN == 8) | 3766 if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) |
3719 illegal_instruction_combination (cpu); | 3767 illegal_instruction_combination (cpu); |
3720 SET_FPREG (GET_LONG (sp)); | 3768 SET_FPREG (GET_LONG (sp)); |
3721 sp += 4; | 3769 sp += 4; |
3722 SET_RETSREG (GET_LONG (sp)); | 3770 SET_RETSREG (GET_LONG (sp)); |
3723 sp += 4; | 3771 sp += 4; |
3724 CYCLE_DELAY = 2; | 3772 CYCLE_DELAY = 2; |
3725 } | 3773 } |
3726 | 3774 |
3727 SET_SPREG (sp); | 3775 SET_SPREG (sp); |
3728 } | 3776 } |
(...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4959 | 5007 |
4960 SET_ASTATREG (v, v); | 5008 SET_ASTATREG (v, v); |
4961 if (v) | 5009 if (v) |
4962 SET_ASTATREG (vs, 1); | 5010 SET_ASTATREG (vs, 1); |
4963 setflags_nz (cpu, val); | 5011 setflags_nz (cpu, val); |
4964 } | 5012 } |
4965 else if (aop == 3 && aopcde == 7) | 5013 else if (aop == 3 && aopcde == 7) |
4966 { | 5014 { |
4967 bu32 val = DREG (src0); | 5015 bu32 val = DREG (src0); |
4968 | 5016 |
4969 TRACE_INSN (cpu, "R%i = - R%i %s;", dst0, src0, amod1 (s, 0)); | 5017 TRACE_INSN (cpu, "R%i = - R%i%s;", dst0, src0, amod1 (s, 0)); |
4970 | 5018 |
4971 if (s && val == 0x80000000) | 5019 if (s && val == 0x80000000) |
4972 { | 5020 { |
4973 val = 0x7fffffff; | 5021 val = 0x7fffffff; |
4974 SET_ASTATREG (v, 1); | 5022 SET_ASTATREG (v, 1); |
4975 SET_ASTATREG (vs, 1); | 5023 SET_ASTATREG (vs, 1); |
4976 } | 5024 } |
4977 else if (val == 0x80000000) | 5025 else if (val == 0x80000000) |
4978 val = 0x80000000; | 5026 val = 0x80000000; |
4979 else | 5027 else |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5151 if ((HLs & 1) == 0) | 5199 if ((HLs & 1) == 0) |
5152 val = (bu16)(DREG (src1) & 0xFFFF); | 5200 val = (bu16)(DREG (src1) & 0xFFFF); |
5153 else | 5201 else |
5154 val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); | 5202 val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); |
5155 | 5203 |
5156 /* Positive shift magnitudes produce Logical Left shifts. | 5204 /* Positive shift magnitudes produce Logical Left shifts. |
5157 Negative shift magnitudes produce Arithmetic Right shifts. */ | 5205 Negative shift magnitudes produce Arithmetic Right shifts. */ |
5158 if (shft <= 0) | 5206 if (shft <= 0) |
5159 val = ashiftrt (cpu, val, -shft, 16); | 5207 val = ashiftrt (cpu, val, -shft, 16); |
5160 else | 5208 else |
5161 » val = lshift (cpu, val, shft, 16, sop == 1); | 5209 » { |
| 5210 » int sgn = (val >> 15) & 0x1; |
| 5211 |
| 5212 » val = lshift (cpu, val, shft, 16, sop == 1, 1); |
| 5213 » if (((val >> 15) & 0x1) != sgn) |
| 5214 » { |
| 5215 » SET_ASTATREG (v, 1); |
| 5216 » SET_ASTATREG (vs, 1); |
| 5217 » } |
| 5218 » } |
5162 | 5219 |
5163 if ((HLs & 2) == 0) | 5220 if ((HLs & 2) == 0) |
5164 STORE (DREG (dst0), REG_H_L (DREG (dst0), val)); | 5221 STORE (DREG (dst0), REG_H_L (DREG (dst0), val)); |
5165 else | 5222 else |
5166 STORE (DREG (dst0), REG_H_L (val << 16, DREG (dst0))); | 5223 STORE (DREG (dst0), REG_H_L (val << 16, DREG (dst0))); |
5167 } | 5224 } |
5168 else if (sop == 2 && sopcde == 0) | 5225 else if (sop == 2 && sopcde == 0) |
5169 { | 5226 { |
5170 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; | 5227 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; |
5171 bu16 val; | 5228 bu16 val; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5203 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc); | 5260 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc); |
5204 | 5261 |
5205 acc = rot40 (acc, shift, &cc); | 5262 acc = rot40 (acc, shift, &cc); |
5206 SET_AREG (HLs, acc); | 5263 SET_AREG (HLs, acc); |
5207 if (shift) | 5264 if (shift) |
5208 SET_CCREG (cc); | 5265 SET_CCREG (cc); |
5209 } | 5266 } |
5210 else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1)) | 5267 else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1)) |
5211 { | 5268 { |
5212 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; | 5269 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; |
5213 bu64 val = get_extended_acc (cpu, HLs); | 5270 bu64 acc = get_extended_acc (cpu, HLs); |
| 5271 bu64 val; |
5214 | 5272 |
5215 HLs = !!HLs; | 5273 HLs = !!HLs; |
5216 TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0); | 5274 TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0); |
5217 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, val, shft); | 5275 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft); |
5218 | 5276 |
5219 if (shft <= 0) | 5277 if (shft <= 0) |
5220 » val = ashiftrt (cpu, val, -shft, 40); | 5278 » val = ashiftrt (cpu, acc, -shft, 40); |
5221 else | 5279 else |
5222 » val = lshift (cpu, val, shft, 40, 0); | 5280 » val = lshift (cpu, acc, shft, 40, 0, 0); |
5223 | 5281 |
5224 STORE (AXREG (HLs), (val >> 32) & 0xff); | 5282 STORE (AXREG (HLs), (val >> 32) & 0xff); |
5225 STORE (AWREG (HLs), (val & 0xffffffff)); | 5283 STORE (AWREG (HLs), (val & 0xffffffff)); |
5226 STORE (ASTATREG (av[HLs]), val == 0); | 5284 STORE (ASTATREG (av[HLs]), 0); |
5227 if (val == 0) | |
5228 » STORE (ASTATREG (avs[HLs]), 1); | |
5229 } | 5285 } |
5230 else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1)) | 5286 else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1)) |
5231 { | 5287 { |
5232 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; | 5288 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; |
| 5289 bu64 acc = get_unextended_acc (cpu, HLs); |
5233 bu64 val; | 5290 bu64 val; |
5234 | 5291 |
5235 HLs = !!HLs; | 5292 HLs = !!HLs; |
5236 TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0); | 5293 TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0); |
5237 val = get_unextended_acc (cpu, HLs); | 5294 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft); |
5238 | 5295 |
5239 if (shft <= 0) | 5296 if (shft <= 0) |
5240 » val = lshiftrt (cpu, val, -shft, 40); | 5297 » val = lshiftrt (cpu, acc, -shft, 40); |
5241 else | 5298 else |
5242 » val = lshift (cpu, val, shft, 40, 0); | 5299 » val = lshift (cpu, acc, shft, 40, 0, 0); |
5243 | 5300 |
5244 STORE (AXREG (HLs), (val >> 32) & 0xff); | 5301 STORE (AXREG (HLs), (val >> 32) & 0xff); |
5245 STORE (AWREG (HLs), (val & 0xffffffff)); | 5302 STORE (AWREG (HLs), (val & 0xffffffff)); |
5246 STORE (ASTATREG (av[HLs]), val == 0); | 5303 STORE (ASTATREG (av[HLs]), 0); |
5247 if (val == 0) | |
5248 » STORE (ASTATREG (avs[HLs]), 1); | |
5249 } | 5304 } |
5250 else if ((sop == 0 || sop == 1) && sopcde == 1) | 5305 else if ((sop == 0 || sop == 1) && sopcde == 1) |
5251 { | 5306 { |
5252 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; | 5307 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; |
5253 bu16 val0, val1; | 5308 bu16 val0, val1; |
5254 bu32 astat; | 5309 bu32 astat; |
5255 | 5310 |
5256 TRACE_INSN (cpu, "R%i = ASHIFT R%i BY R%i.L (V%s);", | 5311 TRACE_INSN (cpu, "R%i = ASHIFT R%i BY R%i.L (V%s);", |
5257 dst0, src1, src0, sop == 1 ? ",S" : ""); | 5312 dst0, src1, src0, sop == 1 ? ",S" : ""); |
5258 | 5313 |
5259 val0 = (bu16)DREG (src1) & 0xFFFF; | 5314 val0 = (bu16)DREG (src1) & 0xFFFF; |
5260 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); | 5315 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); |
5261 | 5316 |
5262 if (shft <= 0) | 5317 if (shft <= 0) |
5263 { | 5318 { |
5264 val0 = ashiftrt (cpu, val0, -shft, 16); | 5319 val0 = ashiftrt (cpu, val0, -shft, 16); |
5265 astat = ASTAT; | 5320 astat = ASTAT; |
5266 val1 = ashiftrt (cpu, val1, -shft, 16); | 5321 val1 = ashiftrt (cpu, val1, -shft, 16); |
5267 } | 5322 } |
5268 else | 5323 else |
5269 { | 5324 { |
5270 » val0 = lshift (cpu, val0, shft, 16, sop == 1); | 5325 » int sgn0 = (val0 >> 15) & 0x1; |
| 5326 » int sgn1 = (val1 >> 15) & 0x1; |
| 5327 |
| 5328 » val0 = lshift (cpu, val0, shft, 16, sop == 1, 1); |
5271 astat = ASTAT; | 5329 astat = ASTAT; |
5272 » val1 = lshift (cpu, val1, shft, 16, sop == 1); | 5330 » val1 = lshift (cpu, val1, shft, 16, sop == 1, 1); |
| 5331 |
| 5332 » if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1))) |
| 5333 » { |
| 5334 » SET_ASTATREG (v, 1); |
| 5335 » SET_ASTATREG (vs, 1); |
| 5336 » } |
5273 } | 5337 } |
5274 SET_ASTAT (ASTAT | astat); | 5338 SET_ASTAT (ASTAT | astat); |
5275 STORE (DREG (dst0), (val1 << 16) | val0); | 5339 STORE (DREG (dst0), (val1 << 16) | val0); |
5276 } | 5340 } |
5277 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2) | 5341 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2) |
5278 { | 5342 { |
5279 /* dregs = [LA]SHIFT dregs BY dregs_lo (opt_S) */ | 5343 /* dregs = [LA]SHIFT dregs BY dregs_lo (opt_S) */ |
5280 /* sop == 1 : opt_S */ | 5344 /* sop == 1 : opt_S */ |
5281 bu32 v = DREG (src1); | 5345 bu32 v = DREG (src1); |
5282 /* LSHIFT uses sign extended low 6 bits of dregs_lo. */ | 5346 /* LSHIFT uses sign extended low 6 bits of dregs_lo. */ |
5283 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; | 5347 bs32 shft = (bs8)(DREG (src0) << 2) >> 2; |
5284 | 5348 |
5285 TRACE_INSN (cpu, "R%i = %cSHIFT R%i BY R%i.L%s;", dst0, | 5349 TRACE_INSN (cpu, "R%i = %cSHIFT R%i BY R%i.L%s;", dst0, |
5286 shft && sop != 2 ? 'A' : 'L', src1, src0, | 5350 shft && sop != 2 ? 'A' : 'L', src1, src0, |
5287 sop == 1 ? " (S)" : ""); | 5351 sop == 1 ? " (S)" : ""); |
5288 | 5352 |
5289 if (shft < 0) | 5353 if (shft < 0) |
5290 { | 5354 { |
5291 if (sop == 2) | 5355 if (sop == 2) |
5292 STORE (DREG (dst0), lshiftrt (cpu, v, -shft, 32)); | 5356 STORE (DREG (dst0), lshiftrt (cpu, v, -shft, 32)); |
5293 else | 5357 else |
5294 STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32)); | 5358 STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32)); |
5295 } | 5359 } |
5296 else | 5360 else |
5297 » STORE (DREG (dst0), lshift (cpu, v, shft, 32, sop == 1)); | 5361 » { |
| 5362 » bu32 val = lshift (cpu, v, shft, 32, sop == 1, 1); |
| 5363 |
| 5364 » STORE (DREG (dst0), val); |
| 5365 » if (((v >> 31) & 0x1) != ((val >> 31) & 0x1)) |
| 5366 » { |
| 5367 » SET_ASTATREG (v, 1); |
| 5368 » SET_ASTATREG (vs, 1); |
| 5369 » } |
| 5370 » } |
5298 } | 5371 } |
5299 else if (sop == 3 && sopcde == 2) | 5372 else if (sop == 3 && sopcde == 2) |
5300 { | 5373 { |
5301 int shift = imm6 (DREG (src0) & 0xFFFF); | 5374 int shift = imm6 (DREG (src0) & 0xFFFF); |
5302 bu32 src = DREG (src1); | 5375 bu32 src = DREG (src1); |
5303 bu32 ret, cc = CCREG; | 5376 bu32 ret, cc = CCREG; |
5304 | 5377 |
5305 TRACE_INSN (cpu, "R%i = ROT R%i BY R%i.L;", dst0, src1, src0); | 5378 TRACE_INSN (cpu, "R%i = ROT R%i BY R%i.L;", dst0, src1, src0); |
5306 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i", | 5379 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i", |
5307 dst0, DREG (dst0), src1, src, shift, cc); | 5380 dst0, DREG (dst0), src1, src, shift, cc); |
(...skipping 15 matching lines...) Expand all Loading... |
5323 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); | 5396 val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16); |
5324 | 5397 |
5325 if (shft <= 0) | 5398 if (shft <= 0) |
5326 { | 5399 { |
5327 val0 = lshiftrt (cpu, val0, -shft, 16); | 5400 val0 = lshiftrt (cpu, val0, -shft, 16); |
5328 astat = ASTAT; | 5401 astat = ASTAT; |
5329 val1 = lshiftrt (cpu, val1, -shft, 16); | 5402 val1 = lshiftrt (cpu, val1, -shft, 16); |
5330 } | 5403 } |
5331 else | 5404 else |
5332 { | 5405 { |
5333 » val0 = lshift (cpu, val0, shft, 16, 0); | 5406 » val0 = lshift (cpu, val0, shft, 16, 0, 0); |
5334 astat = ASTAT; | 5407 astat = ASTAT; |
5335 » val1 = lshift (cpu, val1, shft, 16, 0); | 5408 » val1 = lshift (cpu, val1, shft, 16, 0, 0); |
5336 } | 5409 } |
5337 SET_ASTAT (ASTAT | astat); | 5410 SET_ASTAT (ASTAT | astat); |
5338 STORE (DREG (dst0), (val1 << 16) | val0); | 5411 STORE (DREG (dst0), (val1 << 16) | val0); |
5339 } | 5412 } |
5340 else if (sopcde == 4) | 5413 else if (sopcde == 4) |
5341 { | 5414 { |
5342 bu32 sv0 = DREG (src0); | 5415 bu32 sv0 = DREG (src0); |
5343 bu32 sv1 = DREG (src1); | 5416 bu32 sv1 = DREG (src1); |
5344 TRACE_INSN (cpu, "R%i = PACK (R%i.%c, R%i.%c);", dst0, | 5417 TRACE_INSN (cpu, "R%i = PACK (R%i.%c, R%i.%c);", dst0, |
5345 src1, sop & 2 ? 'H' : 'L', | 5418 src1, sop & 2 ? 'H' : 'L', |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5661 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13) | 5734 else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13) |
5662 { | 5735 { |
5663 int shift = (sop + 1) * 8; | 5736 int shift = (sop + 1) * 8; |
5664 TRACE_INSN (cpu, "R%i = ALIGN%i (R%i, R%i);", dst0, shift, src1, src0); | 5737 TRACE_INSN (cpu, "R%i = ALIGN%i (R%i, R%i);", dst0, shift, src1, src0); |
5665 STORE (DREG (dst0), (DREG (src1) << (32 - shift)) | (DREG (src0) >> shift)
); | 5738 STORE (DREG (dst0), (DREG (src1) << (32 - shift)) | (DREG (src0) >> shift)
); |
5666 } | 5739 } |
5667 else | 5740 else |
5668 illegal_instruction (cpu); | 5741 illegal_instruction (cpu); |
5669 } | 5742 } |
5670 | 5743 |
| 5744 static bu64 |
| 5745 sgn_extend (bu40 org, bu40 val, int size) |
| 5746 { |
| 5747 bu64 ret = val; |
| 5748 |
| 5749 if (org & (1ULL << (size - 1))) |
| 5750 { |
| 5751 /* We need to shift in to the MSB which is set. */ |
| 5752 int n; |
| 5753 |
| 5754 for (n = 40; n >= 0; n--) |
| 5755 if (ret & (1ULL << n)) |
| 5756 break; |
| 5757 ret |= (-1ULL << n); |
| 5758 } |
| 5759 else |
| 5760 ret &= ~(-1ULL << 39); |
| 5761 |
| 5762 return ret; |
| 5763 } |
5671 static void | 5764 static void |
5672 decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1) | 5765 decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1) |
5673 { | 5766 { |
5674 /* dsp32shiftimm | 5767 /* dsp32shiftimm |
5675 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ | 5768 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ |
5676 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............| | 5769 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............| |
5677 |.sop...|.HLs...|.dst0......|.immag.................|.src1......| | 5770 |.sop...|.HLs...|.dst0......|.immag.................|.src1......| |
5678 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ | 5771 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ |
5679 int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask); | 5772 int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask); |
5680 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask); | 5773 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask); |
(...skipping 14 matching lines...) Expand all Loading... |
5695 bu16 in = DREG (src1) >> ((HLs & 1) ? 16 : 0); | 5788 bu16 in = DREG (src1) >> ((HLs & 1) ? 16 : 0); |
5696 bu16 result; | 5789 bu16 result; |
5697 bu32 v; | 5790 bu32 v; |
5698 | 5791 |
5699 if (sop == 0) | 5792 if (sop == 0) |
5700 { | 5793 { |
5701 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;", | 5794 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;", |
5702 dst0, (HLs & 2) ? 'H' : 'L', | 5795 dst0, (HLs & 2) ? 'H' : 'L', |
5703 src1, (HLs & 1) ? 'H' : 'L', newimmag); | 5796 src1, (HLs & 1) ? 'H' : 'L', newimmag); |
5704 if (newimmag > 16) | 5797 if (newimmag > 16) |
5705 » result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0); | 5798 » { |
| 5799 » result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0, 1); |
| 5800 » if (((result >> 15) & 0x1) != ((in >> 15) & 0x1)) |
| 5801 » » { |
| 5802 » » SET_ASTATREG (v, 1); |
| 5803 » » SET_ASTATREG (vs, 1); |
| 5804 » » } |
| 5805 » } |
5706 else | 5806 else |
5707 result = ashiftrt (cpu, in, newimmag, 16); | 5807 result = ashiftrt (cpu, in, newimmag, 16); |
5708 } | 5808 } |
5709 else if (sop == 1 && bit8 == 0) | 5809 else if (sop == 1 && bit8 == 0) |
5710 { | 5810 { |
5711 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i (S);", | 5811 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i (S);", |
5712 dst0, (HLs & 2) ? 'H' : 'L', | 5812 dst0, (HLs & 2) ? 'H' : 'L', |
5713 src1, (HLs & 1) ? 'H' : 'L', immag); | 5813 src1, (HLs & 1) ? 'H' : 'L', immag); |
5714 » result = lshift (cpu, in, immag, 16, 1); | 5814 » result = lshift (cpu, in, immag, 16, 1, 1); |
5715 } | 5815 } |
5716 else if (sop == 1 && bit8) | 5816 else if (sop == 1 && bit8) |
5717 { | 5817 { |
5718 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i (S);", | 5818 TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i (S);", |
5719 dst0, (HLs & 2) ? 'H' : 'L', | 5819 dst0, (HLs & 2) ? 'H' : 'L', |
5720 » » src1, (HLs & 1) ? 'H' : 'L', immag); | 5820 » » src1, (HLs & 1) ? 'H' : 'L', newimmag); |
5721 » result = lshift (cpu, in, immag, 16, 1); | 5821 » if (newimmag > 16) |
| 5822 » { |
| 5823 » int shift = 32 - newimmag; |
| 5824 » bu16 inshift = in << shift; |
| 5825 |
| 5826 » if (((inshift & ~0xFFFF) |
| 5827 » » && ((inshift & ~0xFFFF) >> 16) != ~(~0 << shift)) |
| 5828 » » || (inshift & 0x8000) != (in & 0x8000)) |
| 5829 » » { |
| 5830 » » if (in & 0x8000) |
| 5831 » » result = 0x8000; |
| 5832 » » else |
| 5833 » » result = 0x7fff; |
| 5834 » » SET_ASTATREG (v, 1); |
| 5835 » » SET_ASTATREG (vs, 1); |
| 5836 » » } |
| 5837 » else |
| 5838 » » { |
| 5839 » » result = inshift; |
| 5840 » » SET_ASTATREG (v, 0); |
| 5841 » » } |
| 5842 |
| 5843 » SET_ASTATREG (az, !result); |
| 5844 » SET_ASTATREG (an, !!(result & 0x8000)); |
| 5845 » } |
| 5846 » else |
| 5847 » { |
| 5848 » result = ashiftrt (cpu, in, newimmag, 16); |
| 5849 » result = sgn_extend (in, result, 16); |
| 5850 » } |
5722 } | 5851 } |
5723 else if (sop == 2 && bit8) | 5852 else if (sop == 2 && bit8) |
5724 { | 5853 { |
5725 TRACE_INSN (cpu, "R%i.%c = R%i.%c >> %i;", | 5854 TRACE_INSN (cpu, "R%i.%c = R%i.%c >> %i;", |
5726 dst0, (HLs & 2) ? 'H' : 'L', | 5855 dst0, (HLs & 2) ? 'H' : 'L', |
5727 src1, (HLs & 1) ? 'H' : 'L', newimmag); | 5856 src1, (HLs & 1) ? 'H' : 'L', newimmag); |
5728 result = lshiftrt (cpu, in, newimmag, 16); | 5857 result = lshiftrt (cpu, in, newimmag, 16); |
5729 } | 5858 } |
5730 else if (sop == 2 && bit8 == 0) | 5859 else if (sop == 2 && bit8 == 0) |
5731 { | 5860 { |
5732 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i;", | 5861 TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i;", |
5733 dst0, (HLs & 2) ? 'H' : 'L', | 5862 dst0, (HLs & 2) ? 'H' : 'L', |
5734 src1, (HLs & 1) ? 'H' : 'L', immag); | 5863 src1, (HLs & 1) ? 'H' : 'L', immag); |
5735 » result = lshift (cpu, in, immag, 16, 0); | 5864 » result = lshift (cpu, in, immag, 16, 0, 1); |
5736 } | 5865 } |
5737 else | 5866 else |
5738 illegal_instruction (cpu); | 5867 illegal_instruction (cpu); |
5739 | 5868 |
5740 v = DREG (dst0); | 5869 v = DREG (dst0); |
5741 if (HLs & 2) | 5870 if (HLs & 2) |
5742 STORE (DREG (dst0), (v & 0xFFFF) | (result << 16)); | 5871 STORE (DREG (dst0), (v & 0xFFFF) | (result << 16)); |
5743 else | 5872 else |
5744 STORE (DREG (dst0), (v & 0xFFFF0000) | result); | 5873 STORE (DREG (dst0), (v & 0xFFFF0000) | result); |
5745 } | 5874 } |
5746 else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0)) | 5875 else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0)) |
5747 { | 5876 { |
5748 int shift = imm6 (immag); | 5877 int shift = imm6 (immag); |
5749 bu32 cc = CCREG; | 5878 bu32 cc = CCREG; |
5750 bu40 acc = get_unextended_acc (cpu, HLs); | 5879 bu40 acc = get_unextended_acc (cpu, HLs); |
5751 | 5880 |
5752 TRACE_INSN (cpu, "A%i = ROT A%i BY %i;", HLs, HLs, shift); | 5881 TRACE_INSN (cpu, "A%i = ROT A%i BY %i;", HLs, HLs, shift); |
5753 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc); | 5882 TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc); |
5754 | 5883 |
5755 acc = rot40 (acc, shift, &cc); | 5884 acc = rot40 (acc, shift, &cc); |
5756 SET_AREG (HLs, acc); | 5885 SET_AREG (HLs, acc); |
5757 if (shift) | 5886 if (shift) |
5758 SET_CCREG (cc); | 5887 SET_CCREG (cc); |
5759 } | 5888 } |
5760 else if (sop == 0 && sopcde == 3 && bit8 == 1) | 5889 else if (sop == 0 && sopcde == 3 && bit8 == 1) |
5761 { | 5890 { |
5762 /* Arithmetic shift, so shift in sign bit copies. */ | 5891 /* Arithmetic shift, so shift in sign bit copies. */ |
5763 bu64 acc; | 5892 bu64 acc, val; |
5764 int shift = uimm5 (newimmag); | 5893 int shift = uimm5 (newimmag); |
5765 HLs = !!HLs; | 5894 HLs = !!HLs; |
5766 | 5895 |
5767 TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift); | 5896 TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift); |
5768 | 5897 |
5769 acc = get_extended_acc (cpu, HLs); | 5898 acc = get_extended_acc (cpu, HLs); |
5770 acc >>= shift; | 5899 val = acc >> shift; |
| 5900 |
5771 /* Sign extend again. */ | 5901 /* Sign extend again. */ |
5772 if (acc & (1ULL << 39)) | 5902 val = sgn_extend (acc, val, 40); |
5773 » acc |= -(1ULL << 39); | |
5774 else | |
5775 » acc &= ~(-(1ULL << 39)); | |
5776 | 5903 |
5777 STORE (AXREG (HLs), (acc >> 32) & 0xFF); | 5904 STORE (AXREG (HLs), (val >> 32) & 0xFF); |
5778 STORE (AWREG (HLs), acc & 0xFFFFFFFF); | 5905 STORE (AWREG (HLs), val & 0xFFFFFFFF); |
| 5906 STORE (ASTATREG (an), !!(val & (1ULL << 39))); |
| 5907 STORE (ASTATREG (az), !val); |
| 5908 STORE (ASTATREG (av[HLs]), 0); |
5779 } | 5909 } |
5780 else if ((sop == 0 && sopcde == 3 && bit8 == 0) | 5910 else if ((sop == 0 && sopcde == 3 && bit8 == 0) |
5781 || (sop == 1 && sopcde == 3)) | 5911 || (sop == 1 && sopcde == 3)) |
5782 { | 5912 { |
5783 bu64 acc; | 5913 bu64 acc; |
5784 int shiftup = uimm5 (immag); | 5914 int shiftup = uimm5 (immag); |
5785 int shiftdn = uimm5 (newimmag); | 5915 int shiftdn = uimm5 (newimmag); |
5786 HLs = !!HLs; | 5916 HLs = !!HLs; |
5787 | 5917 |
5788 TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs, | 5918 TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs, |
(...skipping 24 matching lines...) Expand all Loading... |
5813 else if (sop == 1 && sopcde == 1 && bit8 == 0) | 5943 else if (sop == 1 && sopcde == 1 && bit8 == 0) |
5814 { | 5944 { |
5815 int count = imm5 (immag); | 5945 int count = imm5 (immag); |
5816 bu16 val0 = DREG (src1) >> 16; | 5946 bu16 val0 = DREG (src1) >> 16; |
5817 bu16 val1 = DREG (src1) & 0xFFFF; | 5947 bu16 val1 = DREG (src1) & 0xFFFF; |
5818 bu32 astat; | 5948 bu32 astat; |
5819 | 5949 |
5820 TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count); | 5950 TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count); |
5821 if (count >= 0) | 5951 if (count >= 0) |
5822 { | 5952 { |
5823 » val0 = lshift (cpu, val0, count, 16, 1); | 5953 » val0 = lshift (cpu, val0, count, 16, 1, 1); |
5824 astat = ASTAT; | 5954 astat = ASTAT; |
5825 » val1 = lshift (cpu, val1, count, 16, 1); | 5955 » val1 = lshift (cpu, val1, count, 16, 1, 1); |
5826 } | 5956 } |
5827 else | 5957 else |
5828 { | 5958 { |
5829 val0 = ashiftrt (cpu, val0, -count, 16); | 5959 val0 = ashiftrt (cpu, val0, -count, 16); |
5830 astat = ASTAT; | 5960 astat = ASTAT; |
5831 val1 = ashiftrt (cpu, val1, -count, 16); | 5961 val1 = ashiftrt (cpu, val1, -count, 16); |
5832 } | 5962 } |
5833 SET_ASTAT (ASTAT | astat); | 5963 SET_ASTAT (ASTAT | astat); |
5834 | 5964 |
5835 STORE (DREG (dst0), (val0 << 16) | val1); | 5965 STORE (DREG (dst0), (val0 << 16) | val1); |
(...skipping 14 matching lines...) Expand all Loading... |
5850 STORE (DREG (dst0), val0 | (val1 << 16)); | 5980 STORE (DREG (dst0), val0 | (val1 << 16)); |
5851 } | 5981 } |
5852 else if (sop == 2 && sopcde == 1 && bit8 == 0) | 5982 else if (sop == 2 && sopcde == 1 && bit8 == 0) |
5853 { | 5983 { |
5854 int count = imm5 (immag); | 5984 int count = imm5 (immag); |
5855 bu16 val0 = DREG (src1) & 0xFFFF; | 5985 bu16 val0 = DREG (src1) & 0xFFFF; |
5856 bu16 val1 = DREG (src1) >> 16; | 5986 bu16 val1 = DREG (src1) >> 16; |
5857 bu32 astat; | 5987 bu32 astat; |
5858 | 5988 |
5859 TRACE_INSN (cpu, "R%i = R%i << %i (V);", dst0, src1, count); | 5989 TRACE_INSN (cpu, "R%i = R%i << %i (V);", dst0, src1, count); |
5860 val0 = lshift (cpu, val0, count, 16, 0); | 5990 val0 = lshift (cpu, val0, count, 16, 0, 1); |
5861 astat = ASTAT; | 5991 astat = ASTAT; |
5862 val1 = lshift (cpu, val1, count, 16, 0); | 5992 val1 = lshift (cpu, val1, count, 16, 0, 1); |
5863 SET_ASTAT (ASTAT | astat); | 5993 SET_ASTAT (ASTAT | astat); |
5864 | 5994 |
5865 STORE (DREG (dst0), val0 | (val1 << 16)); | 5995 STORE (DREG (dst0), val0 | (val1 << 16)); |
5866 } | 5996 } |
5867 else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1))) | 5997 else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1))) |
5868 { | 5998 { |
5869 int count = uimm5 (newimmag); | 5999 int count = uimm5 (newimmag); |
5870 bu16 val0 = DREG (src1) & 0xFFFF; | 6000 bu16 val0 = DREG (src1) & 0xFFFF; |
5871 bu16 val1 = DREG (src1) >> 16; | 6001 bu16 val1 = DREG (src1) >> 16; |
5872 bu32 astat; | 6002 bu32 astat; |
5873 | 6003 |
5874 TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count, | 6004 TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count, |
5875 sop == 0 ? "(V)" : "(V,S)"); | 6005 sop == 0 ? "(V)" : "(V,S)"); |
5876 | 6006 |
5877 if (count & 0x10) | 6007 if (count > 16) |
5878 { | 6008 { |
5879 » val0 = lshift (cpu, val0, 16 - (count & 0xF), 16, 0); | 6009 » int sgn0 = (val0 >> 15) & 0x1; |
| 6010 » int sgn1 = (val1 >> 15) & 0x1; |
| 6011 |
| 6012 » val0 = lshift (cpu, val0, 16 - (count & 0xF), 16, 0, 1); |
5880 astat = ASTAT; | 6013 astat = ASTAT; |
5881 » val1 = lshift (cpu, val1, 16 - (count & 0xF), 16, 0); | 6014 » val1 = lshift (cpu, val1, 16 - (count & 0xF), 16, 0, 1); |
| 6015 |
| 6016 » if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1))) |
| 6017 » { |
| 6018 » SET_ASTATREG (v, 1); |
| 6019 » SET_ASTATREG (vs, 1); |
| 6020 » } |
5882 } | 6021 } |
5883 else | 6022 else |
5884 { | 6023 { |
5885 val0 = ashiftrt (cpu, val0, count, 16); | 6024 val0 = ashiftrt (cpu, val0, count, 16); |
5886 astat = ASTAT; | 6025 astat = ASTAT; |
5887 val1 = ashiftrt (cpu, val1, count, 16); | 6026 val1 = ashiftrt (cpu, val1, count, 16); |
5888 } | 6027 } |
5889 | 6028 |
5890 SET_ASTAT (ASTAT | astat); | 6029 SET_ASTAT (ASTAT | astat); |
5891 | 6030 |
5892 STORE (DREG (dst0), REG_H_L (val1 << 16, val0)); | 6031 STORE (DREG (dst0), REG_H_L (val1 << 16, val0)); |
5893 } | 6032 } |
5894 else if (sop == 1 && sopcde == 2) | 6033 else if (sop == 1 && sopcde == 2) |
5895 { | 6034 { |
5896 int count = imm6 (immag); | 6035 int count = imm6 (immag); |
5897 | 6036 |
5898 TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count); | 6037 TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count); |
5899 STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1)); | 6038 STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1)); |
5900 } | 6039 } |
5901 else if (sop == 2 && sopcde == 2) | 6040 else if (sop == 2 && sopcde == 2) |
5902 { | 6041 { |
5903 int count = imm6 (newimmag); | 6042 int count = imm6 (newimmag); |
5904 | 6043 |
5905 TRACE_INSN (cpu, "R%i = R%i >> %i;", dst0, src1, count); | 6044 TRACE_INSN (cpu, "R%i = R%i >> %i;", dst0, src1, count); |
5906 | 6045 |
5907 if (count < 0) | 6046 if (count < 0) |
5908 » STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0)); | 6047 » STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0, 1)); |
5909 else | 6048 else |
5910 STORE (DREG (dst0), lshiftrt (cpu, DREG (src1), count, 32)); | 6049 STORE (DREG (dst0), lshiftrt (cpu, DREG (src1), count, 32)); |
5911 } | 6050 } |
5912 else if (sop == 3 && sopcde == 2) | 6051 else if (sop == 3 && sopcde == 2) |
5913 { | 6052 { |
5914 int shift = imm6 (immag); | 6053 int shift = imm6 (immag); |
5915 bu32 src = DREG (src1); | 6054 bu32 src = DREG (src1); |
5916 bu32 ret, cc = CCREG; | 6055 bu32 ret, cc = CCREG; |
5917 | 6056 |
5918 TRACE_INSN (cpu, "R%i = ROT R%i BY %i;", dst0, src1, shift); | 6057 TRACE_INSN (cpu, "R%i = ROT R%i BY %i;", dst0, src1, shift); |
5919 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i", | 6058 TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i", |
5920 dst0, DREG (dst0), src1, src, shift, cc); | 6059 dst0, DREG (dst0), src1, src, shift, cc); |
5921 | 6060 |
5922 ret = rot32 (src, shift, &cc); | 6061 ret = rot32 (src, shift, &cc); |
5923 STORE (DREG (dst0), ret); | 6062 STORE (DREG (dst0), ret); |
5924 if (shift) | 6063 if (shift) |
5925 SET_CCREG (cc); | 6064 SET_CCREG (cc); |
5926 } | 6065 } |
5927 else if (sop == 0 && sopcde == 2) | 6066 else if (sop == 0 && sopcde == 2) |
5928 { | 6067 { |
5929 int count = imm6 (newimmag); | 6068 int count = imm6 (newimmag); |
5930 | 6069 |
5931 TRACE_INSN (cpu, "R%i = R%i >>> %i;", dst0, src1, count); | 6070 TRACE_INSN (cpu, "R%i = R%i >>> %i;", dst0, src1, count); |
5932 | 6071 |
5933 if (count < 0) | 6072 if (count < 0) |
5934 » STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0)); | 6073 » STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0, 1)); |
5935 else | 6074 else |
5936 STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), count, 32)); | 6075 STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), count, 32)); |
5937 } | 6076 } |
5938 else | 6077 else |
5939 illegal_instruction (cpu); | 6078 illegal_instruction (cpu); |
5940 } | 6079 } |
5941 | 6080 |
5942 static void | 6081 static void |
5943 outc (SIM_CPU *cpu, char ch) | 6082 outc (SIM_CPU *cpu, char ch) |
5944 { | 6083 { |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6158 decode_dspLDST_0 (cpu, iw0); | 6297 decode_dspLDST_0 (cpu, iw0); |
6159 else if ((iw0 & 0xF000) == 0x9000) | 6298 else if ((iw0 & 0xF000) == 0x9000) |
6160 decode_LDST_0 (cpu, iw0); | 6299 decode_LDST_0 (cpu, iw0); |
6161 else if ((iw0 & 0xFC00) == 0xB800) | 6300 else if ((iw0 & 0xFC00) == 0xB800) |
6162 decode_LDSTiiFP_0 (cpu, iw0); | 6301 decode_LDSTiiFP_0 (cpu, iw0); |
6163 else if ((iw0 & 0xE000) == 0xA000) | 6302 else if ((iw0 & 0xE000) == 0xA000) |
6164 decode_LDSTii_0 (cpu, iw0); | 6303 decode_LDSTii_0 (cpu, iw0); |
6165 else | 6304 else |
6166 { | 6305 { |
6167 TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__); | 6306 TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__); |
6168 » illegal_instruction (cpu); | 6307 » illegal_instruction_or_combination (cpu); |
6169 } | 6308 } |
6170 return insn_len; | 6309 return insn_len; |
6171 } | 6310 } |
6172 | 6311 |
6173 /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode. */ | 6312 /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode. */ |
6174 iw1 = IFETCH (pc + 2); | 6313 iw1 = IFETCH (pc + 2); |
6175 if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage */) | 6314 if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage */) |
6176 { | 6315 { |
6177 SIM_DESC sd = CPU_STATE (cpu); | 6316 SIM_DESC sd = CPU_STATE (cpu); |
6178 trace_prefix (sd, cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu), | 6317 trace_prefix (sd, cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu), |
6179 NULL, 0, "|| %#"PRIx64, sim_events_time (sd)); | 6318 NULL, 0, "|| %#"PRIx64, sim_events_time (sd)); |
6180 insn_len = 8; | 6319 insn_len = 8; |
| 6320 PARALLEL_GROUP = BFIN_PARALLEL_GROUP0; |
6181 } | 6321 } |
6182 else | 6322 else |
6183 insn_len = 4; | 6323 insn_len = 4; |
6184 | 6324 |
6185 TRACE_EXTRACT (cpu, "%s: iw0:%#x iw1:%#x insn_len:%i", __func__, | 6325 TRACE_EXTRACT (cpu, "%s: iw0:%#x iw1:%#x insn_len:%i", __func__, |
6186 iw0, iw1, insn_len); | 6326 iw0, iw1, insn_len); |
6187 | 6327 |
6188 /* Only cache on first run through (in case of parallel insns). */ | 6328 /* Only cache on first run through (in case of parallel insns). */ |
6189 if (INSN_LEN == 0) | 6329 if (INSN_LEN == 0) |
6190 INSN_LEN = insn_len; | 6330 INSN_LEN = insn_len; |
| 6331 else |
| 6332 /* Once you're past the first slot, only 16bit insns are valid. */ |
| 6333 illegal_instruction_combination (cpu); |
6191 | 6334 |
6192 if ((iw0 & 0xf7ff) == 0xc003 && (iw1 & 0xfe00) == 0x1800) | 6335 if ((iw0 & 0xf7ff) == 0xc003 && (iw1 & 0xfe00) == 0x1800) |
6193 { | 6336 { |
6194 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac); | 6337 PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac); |
6195 TRACE_INSN (cpu, "MNOP;"); | 6338 TRACE_INSN (cpu, "MNOP;"); |
6196 } | 6339 } |
6197 else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000)) | 6340 else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000)) |
6198 decode_LoopSetup_0 (cpu, iw0, iw1, pc); | 6341 decode_LoopSetup_0 (cpu, iw0, iw1, pc); |
6199 else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000)) | 6342 else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000)) |
6200 decode_LDIMMhalf_0 (cpu, iw0, iw1); | 6343 decode_LDIMMhalf_0 (cpu, iw0, iw1); |
(...skipping 28 matching lines...) Expand all Loading... |
6229 return insn_len; | 6372 return insn_len; |
6230 } | 6373 } |
6231 | 6374 |
6232 bu32 | 6375 bu32 |
6233 interp_insn_bfin (SIM_CPU *cpu, bu32 pc) | 6376 interp_insn_bfin (SIM_CPU *cpu, bu32 pc) |
6234 { | 6377 { |
6235 int i; | 6378 int i; |
6236 bu32 insn_len; | 6379 bu32 insn_len; |
6237 | 6380 |
6238 BFIN_CPU_STATE.n_stores = 0; | 6381 BFIN_CPU_STATE.n_stores = 0; |
| 6382 PARALLEL_GROUP = BFIN_PARALLEL_NONE; |
6239 DIS_ALGN_EXPT &= ~1; | 6383 DIS_ALGN_EXPT &= ~1; |
6240 CYCLE_DELAY = 1; | 6384 CYCLE_DELAY = 1; |
6241 INSN_LEN = 0; | 6385 INSN_LEN = 0; |
6242 | 6386 |
6243 insn_len = _interp_insn_bfin (cpu, pc); | 6387 insn_len = _interp_insn_bfin (cpu, pc); |
6244 | 6388 |
6245 /* Proper display of multiple issue instructions. */ | 6389 /* Proper display of multiple issue instructions. */ |
6246 if (insn_len == 8) | 6390 if (insn_len == 8) |
6247 { | 6391 { |
| 6392 PARALLEL_GROUP = BFIN_PARALLEL_GROUP1; |
6248 _interp_insn_bfin (cpu, pc + 4); | 6393 _interp_insn_bfin (cpu, pc + 4); |
| 6394 PARALLEL_GROUP = BFIN_PARALLEL_GROUP2; |
6249 _interp_insn_bfin (cpu, pc + 6); | 6395 _interp_insn_bfin (cpu, pc + 6); |
6250 } | 6396 } |
6251 for (i = 0; i < BFIN_CPU_STATE.n_stores; i++) | 6397 for (i = 0; i < BFIN_CPU_STATE.n_stores; i++) |
6252 { | 6398 { |
6253 bu32 *addr = BFIN_CPU_STATE.stores[i].addr; | 6399 bu32 *addr = BFIN_CPU_STATE.stores[i].addr; |
6254 *addr = BFIN_CPU_STATE.stores[i].val; | 6400 *addr = BFIN_CPU_STATE.stores[i].val; |
6255 TRACE_REGISTER (cpu, "dequeuing write %s = %#x", | 6401 TRACE_REGISTER (cpu, "dequeuing write %s = %#x", |
6256 get_store_name (cpu, addr), *addr); | 6402 get_store_name (cpu, addr), *addr); |
6257 } | 6403 } |
6258 | 6404 |
6259 cycles_inc (cpu, CYCLE_DELAY); | 6405 cycles_inc (cpu, CYCLE_DELAY); |
6260 | 6406 |
6261 /* Set back to zero in case a pending CEC event occurs | 6407 /* Set back to zero in case a pending CEC event occurs |
6262 after this this insn. */ | 6408 after this this insn. */ |
6263 INSN_LEN = 0; | 6409 INSN_LEN = 0; |
6264 | 6410 |
6265 return insn_len; | 6411 return insn_len; |
6266 } | 6412 } |
OLD | NEW |