| 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 |