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