| 1 | // -*- C -*- |
| 2 | |
| 3 | // Simulator definition for the Broadcom SiByte SB-1 CPU extensions. |
| 4 | // Copyright (C) 2002-2020 Free Software Foundation, Inc. |
| 5 | // Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom |
| 6 | // Corporation (SiByte). |
| 7 | // |
| 8 | // This file is part of GDB, the GNU debugger. |
| 9 | // |
| 10 | // This program is free software; you can redistribute it and/or modify |
| 11 | // it under the terms of the GNU General Public License as published by |
| 12 | // the Free Software Foundation; either version 3 of the License, or |
| 13 | // (at your option) any later version. |
| 14 | // |
| 15 | // This program is distributed in the hope that it will be useful, |
| 16 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | // GNU General Public License for more details. |
| 19 | // |
| 20 | // You should have received a copy of the GNU General Public License |
| 21 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 22 | |
| 23 | |
| 24 | // Helper: |
| 25 | // |
| 26 | // Check that the SB-1 extension instruction can currently be used, and |
| 27 | // signal a ReservedInstruction exception if not. |
| 28 | // |
| 29 | |
| 30 | :function:::void:check_sbx:instruction_word insn |
| 31 | *sb1: |
| 32 | { |
| 33 | if ((SR & status_SBX) == 0) |
| 34 | SignalException(ReservedInstruction, insn); |
| 35 | } |
| 36 | |
| 37 | |
| 38 | // MDMX ASE Instructions |
| 39 | // --------------------- |
| 40 | // |
| 41 | // The SB-1 implements the format OB subset of MDMX |
| 42 | // and has three additions (pavg, pabsdiff, pabsdifc). |
| 43 | // In addition, there are a couple of partial-decoding |
| 44 | // issues for the read/write accumulator instructions. |
| 45 | // |
| 46 | // This code is structured so that mdmx.igen can be used by |
| 47 | // selecting the allowed instructions either via model, or by |
| 48 | // using check_mdmx_fmtsel and check_mdmx_fmtop to cause an |
| 49 | // exception if the instruction is not allowed. |
| 50 | |
| 51 | |
| 52 | :function:::void:check_mdmx:instruction_word insn |
| 53 | *sb1: |
| 54 | { |
| 55 | if (!COP_Usable(1)) |
| 56 | SignalExceptionCoProcessorUnusable(1); |
| 57 | if ((SR & status_MX) == 0) |
| 58 | SignalExceptionMDMX(); |
| 59 | check_u64 (SD_, insn); |
| 60 | } |
| 61 | |
| 62 | :function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel |
| 63 | *sb1: |
| 64 | { |
| 65 | switch (fmtsel & 0x03) |
| 66 | { |
| 67 | case 0x00: /* ob */ |
| 68 | case 0x02: |
| 69 | return 1; |
| 70 | case 0x01: /* qh */ |
| 71 | case 0x03: /* UNPREDICTABLE */ |
| 72 | SignalException (ReservedInstruction, insn); |
| 73 | return 0; |
| 74 | } |
| 75 | return 0; |
| 76 | } |
| 77 | |
| 78 | :function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop |
| 79 | *sb1: |
| 80 | { |
| 81 | switch (fmtop & 0x01) |
| 82 | { |
| 83 | case 0x00: /* ob */ |
| 84 | return 1; |
| 85 | case 0x01: /* qh */ |
| 86 | SignalException (ReservedInstruction, insn); |
| 87 | return 0; |
| 88 | } |
| 89 | return 0; |
| 90 | } |
| 91 | |
| 92 | |
| 93 | 011110,10,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.sb1.fmt |
| 94 | "rach.?<X>.%s<FMTOP> v<VD>" |
| 95 | *sb1: |
| 96 | { |
| 97 | check_mdmx (SD_, instruction_0); |
| 98 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 99 | /* No op. */ |
| 100 | } |
| 101 | |
| 102 | |
| 103 | 011110,00,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.sb1.fmt |
| 104 | "racl.?<X>.%s<FMTOP> v<VD>" |
| 105 | *sb1: |
| 106 | { |
| 107 | check_mdmx (SD_, instruction_0); |
| 108 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 109 | /* No op. */ |
| 110 | } |
| 111 | |
| 112 | |
| 113 | 011110,01,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.sb1.fmt |
| 114 | "racm.?<X>.%s<FMTOP> v<VD>" |
| 115 | *sb1: |
| 116 | { |
| 117 | check_mdmx (SD_, instruction_0); |
| 118 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 119 | /* No op. */ |
| 120 | } |
| 121 | |
| 122 | |
| 123 | 011110,2.X1!0!1!2,2.X2,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RAC.sb1.fmt |
| 124 | "rac?<X1>.?<X2> v<VD>" |
| 125 | *sb1: |
| 126 | { |
| 127 | check_mdmx (SD_, instruction_0); |
| 128 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 129 | /* No op. */ |
| 130 | } |
| 131 | |
| 132 | |
| 133 | 011110,10,2.X!0,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.sb1.fmt |
| 134 | "wach.?<X>.%s<FMTOP> v<VS>" |
| 135 | *sb1: |
| 136 | { |
| 137 | check_mdmx (SD_, instruction_0); |
| 138 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 139 | /* No op. */ |
| 140 | } |
| 141 | |
| 142 | |
| 143 | 011110,00,2.X!0,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.sb1.fmt |
| 144 | "wacl.?<X>.%s<FMTOP> v<VS>,v<VT>" |
| 145 | *sb1: |
| 146 | { |
| 147 | check_mdmx (SD_, instruction_0); |
| 148 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 149 | /* No op. */ |
| 150 | } |
| 151 | |
| 152 | |
| 153 | 011110,2.X1!0!2,2.X2,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WAC.sb1.fmt |
| 154 | "wacl?<X1>.?<X2>.%s<FMTOP> v<VS>,v<VT>" |
| 155 | *sb1: |
| 156 | { |
| 157 | check_mdmx (SD_, instruction_0); |
| 158 | check_mdmx_fmtop (SD_, instruction_0, FMTOP); |
| 159 | /* No op. */ |
| 160 | } |
| 161 | |
| 162 | |
| 163 | 011110,5.FMTSEL,5.VT,5.VS,5.VD,001001:MDMX:64::PABSDIFF.fmt |
| 164 | "pabsdiff.%s<FMTSEL> v<VD>,v<VS>,v<VT>" |
| 165 | *sb1: |
| 166 | { |
| 167 | check_mdmx (SD_, instruction_0); |
| 168 | check_sbx (SD_, instruction_0); |
| 169 | check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); |
| 170 | StoreFPR(VD,fmt_mdmx,MX_AbsDiff(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); |
| 171 | } |
| 172 | |
| 173 | |
| 174 | 011110,5.FMTSEL,5.VT,5.VS,00000,110101:MDMX:64::PABSDIFC.fmt |
| 175 | "pabsdifc.%<FMTSEL> v<VS>,v<VT>" |
| 176 | *sb1: |
| 177 | { |
| 178 | check_mdmx (SD_, instruction_0); |
| 179 | check_sbx (SD_, instruction_0); |
| 180 | check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); |
| 181 | MX_AbsDiffC(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); |
| 182 | } |
| 183 | |
| 184 | |
| 185 | 011110,5.FMTSEL,5.VT,5.VS,5.VD,001000:MDMX:64::PAVG.fmt |
| 186 | "pavg.%s<FMTSEL> v<VD>,v<VS>,v<VT>" |
| 187 | *sb1: |
| 188 | { |
| 189 | check_mdmx (SD_, instruction_0); |
| 190 | check_sbx (SD_, instruction_0); |
| 191 | check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); |
| 192 | StoreFPR(VD,fmt_mdmx,MX_Avg(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); |
| 193 | } |
| 194 | |
| 195 | |
| 196 | // Paired-Single Extension Instructions |
| 197 | // ------------------------------------ |
| 198 | // |
| 199 | // The SB-1 implements several .PS format instructions that are |
| 200 | // extensions to the MIPS64 architecture. |
| 201 | |
| 202 | 010001,10,3.FMT=6,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.PS |
| 203 | "div.%s<FMT> f<FD>, f<FS>, f<FT>" |
| 204 | *sb1: |
| 205 | { |
| 206 | int fmt = FMT; |
| 207 | check_fpu (SD_); |
| 208 | check_sbx (SD_, instruction_0); |
| 209 | StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); |
| 210 | } |
| 211 | |
| 212 | |
| 213 | 010001,10,3.FMT=6,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.PS |
| 214 | "recip.%s<FMT> f<FD>, f<FS>" |
| 215 | *sb1: |
| 216 | { |
| 217 | int fmt = FMT; |
| 218 | check_fpu (SD_); |
| 219 | check_sbx (SD_, instruction_0); |
| 220 | StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt)); |
| 221 | } |
| 222 | |
| 223 | |
| 224 | 010001,10,3.FMT=6,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.PS |
| 225 | "rsqrt.%s<FMT> f<FD>, f<FS>" |
| 226 | *sb1: |
| 227 | { |
| 228 | int fmt = FMT; |
| 229 | check_fpu (SD_); |
| 230 | check_sbx (SD_, instruction_0); |
| 231 | StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt)); |
| 232 | } |
| 233 | |
| 234 | |
| 235 | 010001,10,3.FMT=6,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.PS |
| 236 | "sqrt.%s<FMT> f<FD>, f<FS>" |
| 237 | *sb1: |
| 238 | { |
| 239 | int fmt = FMT; |
| 240 | check_fpu (SD_); |
| 241 | check_sbx (SD_, instruction_0); |
| 242 | StoreFPR (FD, fmt, (SquareRoot (ValueFPR (FS, fmt), fmt))); |
| 243 | } |